From e53b1e04eb6c2d12da20a0dbbb007d26b3a86380 Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Thu, 5 Dec 2024 11:33:39 -0500 Subject: [PATCH 01/29] Fix OneBranch Build of msquictest (#4688) --- src/test/bin/quic_gtest.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/bin/quic_gtest.cpp b/src/test/bin/quic_gtest.cpp index 12a2987548..2010fb93bd 100644 --- a/src/test/bin/quic_gtest.cpp +++ b/src/test/bin/quic_gtest.cpp @@ -89,7 +89,11 @@ class QuicTestEnvironment : public ::testing::Environment { ASSERT_TRUE(DriverService.Start()); ASSERT_TRUE(DriverClient.Initialize(&CertParams, DriverName)); - Config.Flags |= UseDuoNic ? QUIC_EXECUTION_CONFIG_FLAG_XDP : QUIC_EXECUTION_CONFIG_FLAG_NONE; +#if defined(QUIC_API_ENABLE_PREVIEW_FEATURES) + if (UseDuoNic) { + Config.Flags |= QUIC_EXECUTION_CONFIG_FLAG_XDP; + } +#endif QUIC_TEST_CONFIGURATION_PARAMS Params { UseDuoNic, Config, From 72df2223f9f1351224eb87d30cf6a470d442948d Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Thu, 5 Dec 2024 12:17:26 -0500 Subject: [PATCH 02/29] Update test-down-level.yml for new Releases (#4689) --- .github/workflows/test-down-level.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test-down-level.yml b/.github/workflows/test-down-level.yml index 54f236ef9a..d110ff1b6e 100644 --- a/.github/workflows/test-down-level.yml +++ b/.github/workflows/test-down-level.yml @@ -31,17 +31,17 @@ jobs: { release: "2.2.6", os: "windows-2022", arch: "x64", tls: "openssl" }, { release: "2.2.6", os: "windows-2022", arch: "x64", tls: "openssl3" }, # v2.3 - { release: "2.3.6", os: "ubuntu-20.04", arch: "x64", tls: "openssl" }, - { release: "2.3.6", os: "ubuntu-22.04", arch: "x64", tls: "openssl3" }, - { release: "2.3.6", os: "windows-2022", arch: "x64", tls: "schannel" }, - { release: "2.3.6", os: "windows-2022", arch: "x64", tls: "openssl" }, - { release: "2.3.6", os: "windows-2022", arch: "x64", tls: "openssl3" }, + { release: "2.3.8", os: "ubuntu-20.04", arch: "x64", tls: "openssl" }, + { release: "2.3.8", os: "ubuntu-22.04", arch: "x64", tls: "openssl3" }, + { release: "2.3.8", os: "windows-2022", arch: "x64", tls: "schannel" }, + { release: "2.3.8", os: "windows-2022", arch: "x64", tls: "openssl" }, + { release: "2.3.8", os: "windows-2022", arch: "x64", tls: "openssl3" }, # v2.4 - { release: "2.4.5", os: "ubuntu-20.04", arch: "x64", tls: "openssl" }, - { release: "2.4.5", os: "ubuntu-22.04", arch: "x64", tls: "openssl3" }, - { release: "2.4.5", os: "windows-2022", arch: "x64", tls: "schannel" }, - { release: "2.4.5", os: "windows-2022", arch: "x64", tls: "openssl" }, - { release: "2.4.5", os: "windows-2022", arch: "x64", tls: "openssl3" }, + { release: "2.4.7", os: "ubuntu-20.04", arch: "x64", tls: "openssl" }, + { release: "2.4.7", os: "ubuntu-22.04", arch: "x64", tls: "openssl3" }, + { release: "2.4.7", os: "windows-2022", arch: "x64", tls: "schannel" }, + { release: "2.4.7", os: "windows-2022", arch: "x64", tls: "openssl" }, + { release: "2.4.7", os: "windows-2022", arch: "x64", tls: "openssl3" }, ] runs-on: ${{ matrix.vec.os }} name: Test From d22ec11ce14470c0a1d4352d72907dedb492be30 Mon Sep 17 00:00:00 2001 From: Masahiro Kozuka Date: Sat, 7 Dec 2024 22:12:45 +0900 Subject: [PATCH 03/29] Replacing panics with `Result` returns, and adds platform-specific status codes (#4690) * Add platform-specific QUIC status codes for Windows, Linux, and macOS * Refactor API methods to return Result types instead of panicking on failure * Refactor error handling in tests to use Result types and improve readability --- src/lib.rs | 236 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 190 insertions(+), 46 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4ba2a4629b..70ed8e3001 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ use std::convert::TryInto; use std::fmt; use std::option::Option; use std::ptr; +use std::result::Result; #[macro_use] extern crate bitfield; @@ -100,6 +101,127 @@ impl Addr { } } +#[cfg(target_os = "windows")] +mod status { + pub const QUIC_STATUS_SUCCESS: u32 = 0x0; + pub const QUIC_STATUS_PENDING: u32 = 0x703e5; + pub const QUIC_STATUS_CONTINUE: u32 = 0x704de; + pub const QUIC_STATUS_OUT_OF_MEMORY: u32 = 0x8007000e; + pub const QUIC_STATUS_INVALID_PARAMETER: u32 = 0x80070057; + pub const QUIC_STATUS_INVALID_STATE: u32 = 0x8007139f; + pub const QUIC_STATUS_NOT_SUPPORTED: u32 = 0x80004002; + pub const QUIC_STATUS_NOT_FOUND: u32 = 0x80070490; + pub const QUIC_STATUS_BUFFER_TOO_SMALL: u32 = 0x8007007a; + pub const QUIC_STATUS_HANDSHAKE_FAILURE: u32 = 0x80410000; + pub const QUIC_STATUS_ABORTED: u32 = 0x80004004; + pub const QUIC_STATUS_ADDRESS_IN_USE: u32 = 0x80072740; + pub const QUIC_STATUS_INVALID_ADDRESS: u32 = 0x80072741; + pub const QUIC_STATUS_CONNECTION_TIMEOUT: u32 = 0x80410006; + pub const QUIC_STATUS_CONNECTION_IDLE: u32 = 0x80410005; + pub const QUIC_STATUS_UNREACHABLE: u32 = 0x800704d0; + pub const QUIC_STATUS_INTERNAL_ERROR: u32 = 0x80410003; + pub const QUIC_STATUS_CONNECTION_REFUSED: u32 = 0x800704c9; + pub const QUIC_STATUS_PROTOCOL_ERROR: u32 = 0x80410004; + pub const QUIC_STATUS_VER_NEG_ERROR: u32 = 0x80410001; + pub const QUIC_STATUS_TLS_ERROR: u32 = 0x80072b18; + pub const QUIC_STATUS_USER_CANCELED: u32 = 0x80410002; + pub const QUIC_STATUS_ALPN_NEG_FAILURE: u32 = 0x80410007; + pub const QUIC_STATUS_STREAM_LIMIT_REACHED: u32 = 0x80410008; + pub const QUIC_STATUS_ALPN_IN_USE: u32 = 0x80410009; + pub const QUIC_STATUS_CLOSE_NOTIFY: u32 = 0x80410100 | 0; + pub const QUIC_STATUS_BAD_CERTIFICATE: u32 = 0x80410100 | 42; + pub const QUIC_STATUS_UNSUPPORTED_CERTIFICATE: u32 = 0x80410100 | 43; + pub const QUIC_STATUS_REVOKED_CERTIFICATE: u32 = 0x80410100 | 44; + pub const QUIC_STATUS_EXPIRED_CERTIFICATE: u32 = 0x80410100 | 45; + pub const QUIC_STATUS_UNKNOWN_CERTIFICATE: u32 = 0x80410100 | 46; + pub const QUIC_STATUS_REQUIRED_CERTIFICATE: u32 = 0x80410100 | 116; + pub const QUIC_STATUS_CERT_EXPIRED: u32 = 0x800B0101; + pub const QUIC_STATUS_CERT_UNTRUSTED_ROOT: u32 = 0x800B0109; + pub const QUIC_STATUS_CERT_NO_CERT: u32 = 0x8009030E; +} + +#[cfg(target_os = "linux")] +mod status { + pub const QUIC_STATUS_SUCCESS: u32 = 0; + pub const QUIC_STATUS_PENDING: u32 = 0xFFFFFFFE; /// -2 + pub const QUIC_STATUS_CONTINUE: u32 = 0xFFFFFFFF; /// -1 + pub const QUIC_STATUS_OUT_OF_MEMORY: u32 = 12; + pub const QUIC_STATUS_INVALID_PARAMETER: u32 = 22; + pub const QUIC_STATUS_INVALID_STATE: u32 = 1; + pub const QUIC_STATUS_NOT_SUPPORTED: u32 = 95; + pub const QUIC_STATUS_NOT_FOUND: u32 = 2; + pub const QUIC_STATUS_BUFFER_TOO_SMALL: u32 = 75; + pub const QUIC_STATUS_HANDSHAKE_FAILURE: u32 = 103; + pub const QUIC_STATUS_ABORTED: u32 = 125; + pub const QUIC_STATUS_ADDRESS_IN_USE: u32 = 98; + pub const QUIC_STATUS_INVALID_ADDRESS: u32 = 97; + pub const QUIC_STATUS_CONNECTION_TIMEOUT: u32 = 110; + pub const QUIC_STATUS_CONNECTION_IDLE: u32 = 62; + pub const QUIC_STATUS_INTERNAL_ERROR: u32 = 5; + pub const QUIC_STATUS_CONNECTION_REFUSED: u32 = 111; + pub const QUIC_STATUS_PROTOCOL_ERROR: u32 = 71; + pub const QUIC_STATUS_VER_NEG_ERROR: u32 = 93; + pub const QUIC_STATUS_UNREACHABLE: u32 = 113; + pub const QUIC_STATUS_TLS_ERROR: u32 = 126; + pub const QUIC_STATUS_USER_CANCELED: u32 = 130; + pub const QUIC_STATUS_ALPN_NEG_FAILURE: u32 = 92; + pub const QUIC_STATUS_STREAM_LIMIT_REACHED: u32 = 86; + pub const QUIC_STATUS_ALPN_IN_USE: u32 = 91; + pub const QUIC_STATUS_ADDRESS_NOT_AVAILABLE: u32 = 99; + pub const QUIC_STATUS_CLOSE_NOTIFY: u32 = 0xBEBC300; + pub const QUIC_STATUS_BAD_CERTIFICATE: u32 = 0xBEBC32A; + pub const QUIC_STATUS_UNSUPPORTED_CERTIFICATE: u32 = 0xBEBC32B; + pub const QUIC_STATUS_REVOKED_CERTIFICATE: u32 = 0xBEBC32C; + pub const QUIC_STATUS_EXPIRED_CERTIFICATE: u32 = 0xBEBC32D; + pub const QUIC_STATUS_UNKNOWN_CERTIFICATE: u32 = 0xBEBC32E; + pub const QUIC_STATUS_REQUIRED_CERTIFICATE: u32 = 0xBEBC374; + pub const QUIC_STATUS_CERT_EXPIRED: u32 = 0xBEBC401; + pub const QUIC_STATUS_CERT_UNTRUSTED_ROOT: u32 = 0xBEBC402; + pub const QUIC_STATUS_CERT_NO_CERT: u32 = 0xBEBC403; +} + +#[cfg(target_os = "macos")] +mod status { + pub const QUIC_STATUS_SUCCESS: u32 = 0; + pub const QUIC_STATUS_PENDING: u32 = 0xFFFFFFFE; /// -2 + pub const QUIC_STATUS_CONTINUE: u32 = 0xFFFFFFFF; /// -1 + pub const QUIC_STATUS_OUT_OF_MEMORY: u32 = 12; + pub const QUIC_STATUS_INVALID_PARAMETER: u32 = 22; + pub const QUIC_STATUS_INVALID_STATE: u32 = 1; + pub const QUIC_STATUS_NOT_SUPPORTED: u32 = 102; + pub const QUIC_STATUS_NOT_FOUND: u32 = 2; + pub const QUIC_STATUS_BUFFER_TOO_SMALL: u32 = 84; + pub const QUIC_STATUS_HANDSHAKE_FAILURE: u32 = 53; + pub const QUIC_STATUS_ABORTED: u32 = 89; + pub const QUIC_STATUS_ADDRESS_IN_USE: u32 = 48; + pub const QUIC_STATUS_INVALID_ADDRESS: u32 = 47; + pub const QUIC_STATUS_CONNECTION_TIMEOUT: u32 = 60; + pub const QUIC_STATUS_CONNECTION_IDLE: u32 = 101; + pub const QUIC_STATUS_INTERNAL_ERROR: u32 = 5; + pub const QUIC_STATUS_CONNECTION_REFUSED: u32 = 61; + pub const QUIC_STATUS_PROTOCOL_ERROR: u32 = 100; + pub const QUIC_STATUS_VER_NEG_ERROR: u32 = 43; + pub const QUIC_STATUS_UNREACHABLE: u32 = 65; + pub const QUIC_STATUS_TLS_ERROR: u32 = 126; + pub const QUIC_STATUS_USER_CANCELED: u32 = 105; + pub const QUIC_STATUS_ALPN_NEG_FAILURE: u32 = 42; + pub const QUIC_STATUS_STREAM_LIMIT_REACHED: u32 = 86; + pub const QUIC_STATUS_ALPN_IN_USE: u32 = 41; + pub const QUIC_STATUS_ADDRESS_NOT_AVAILABLE: u32 = 47; + pub const QUIC_STATUS_CLOSE_NOTIFY: u32 = 0xBEBC300; + pub const QUIC_STATUS_BAD_CERTIFICATE: u32 = 0xBEBC32A; + pub const QUIC_STATUS_UNSUPPORTED_CERTIFICATE: u32 = 0xBEBC32B; + pub const QUIC_STATUS_REVOKED_CERTIFICATE: u32 = 0xBEBC32C; + pub const QUIC_STATUS_EXPIRED_CERTIFICATE: u32 = 0xBEBC32D; + pub const QUIC_STATUS_UNKNOWN_CERTIFICATE: u32 = 0xBEBC32E; + pub const QUIC_STATUS_REQUIRED_CERTIFICATE: u32 = 0xBEBC374; + pub const QUIC_STATUS_CERT_EXPIRED: u32 = 0xBEBC401; + pub const QUIC_STATUS_CERT_UNTRUSTED_ROOT: u32 = 0xBEBC402; + pub const QUIC_STATUS_CERT_NO_CERT: u32 = 0xBEBC403; +} + +pub use status::*; + /// Helper for processing MsQuic return statuses. pub struct Status {} @@ -129,7 +251,7 @@ impl Status { /// The different possible TLS providers used by MsQuic. pub type TlsProvider = u32; pub const TLS_PROVIDER_SCHANNEL: TlsProvider = 0; -pub const TLS_PROVIDER_OPENSSL : TlsProvider = 1; +pub const TLS_PROVIDER_OPENSSL: TlsProvider = 1; /// Configures how to process a registration's workload. pub type ExecutionProfile = u32; @@ -956,7 +1078,6 @@ pub struct StreamEventSendShutdownComplete { pub graceful: bool, } - bitfield! { #[repr(C)] #[derive(Clone, Copy)] @@ -970,7 +1091,7 @@ bitfield! { #[derive(Copy, Clone)] pub struct StreamEventShutdownComplete { connection_shutdown: bool, - flags: StreamEventShutdownCompleteBitfields + flags: StreamEventShutdownCompleteBitfields, } #[repr(C)] @@ -1272,13 +1393,13 @@ impl CredentialConfig { } impl Api { - pub fn new() -> Api { + pub fn new() -> Result { let new_table: *const ApiTable = ptr::null(); let status = unsafe { MsQuicOpenVersion(2, &new_table) }; if Status::failed(status) { - panic!("MsQuicOpenVersion failure 0x{:x}", status); + return Err(status); } - Api { table: new_table } + Ok(Api { table: new_table }) } pub fn close_listener(&self, listener: Handle) { @@ -1330,16 +1451,16 @@ impl Drop for Api { } impl Registration { - pub fn new(api: &Api, config: *const RegistrationConfig) -> Registration { + pub fn new(api: &Api, config: *const RegistrationConfig) -> Result { let new_registration: Handle = ptr::null(); let status = unsafe { ((*api.table).registration_open)(config, &new_registration) }; if Status::failed(status) { - panic!("RegistrationOpen failure 0x{:x}", status); + return Err(status); } - Registration { + Ok(Registration { table: api.table, handle: new_registration, - } + }) } pub fn shutdown(&self) { @@ -1358,7 +1479,7 @@ impl Configuration { registration: &Registration, alpn: &[Buffer], settings: *const Settings, - ) -> Configuration { + ) -> Result { let context: *const c_void = ptr::null(); let new_configuration: Handle = ptr::null(); let mut settings_size: u32 = 0; @@ -1377,20 +1498,21 @@ impl Configuration { ) }; if Status::failed(status) { - panic!("ConfigurationOpen failure 0x{:x}", status); + return Err(status); } - Configuration { + Ok(Configuration { table: registration.table, handle: new_configuration, - } + }) } - pub fn load_credential(&self, cred_config: &CredentialConfig) { + pub fn load_credential(&self, cred_config: &CredentialConfig) -> Result<(), u32> { let status = unsafe { ((*self.table).configuration_load_credential)(self.handle, *&cred_config) }; if Status::failed(status) { - panic!("ConfigurationLoadCredential failure 0x{:x}", status); + return Err(status); } + Ok(()) } } @@ -1420,16 +1542,17 @@ impl Connection { registration: &Registration, handler: ConnectionEventHandler, context: *const c_void, - ) { + ) -> Result<(), u32> { let status = unsafe { ((*self.table).connection_open)(registration.handle, handler, context, &self.handle) }; if Status::failed(status) { - panic!("ConnectionOpen failure 0x{:x}", status); + return Err(status); } + Ok(()) } - pub fn start(&self, configuration: &Configuration, server_name: &str, server_port: u16) { + pub fn start(&self, configuration: &Configuration, server_name: &str, server_port: u16) -> Result<(), u32> { let server_name_safe = std::ffi::CString::new(server_name).unwrap(); let status = unsafe { ((*self.table).connection_start)( @@ -1441,8 +1564,9 @@ impl Connection { ) }; if Status::failed(status) { - panic!("ConnectionStart failure 0x{:x}", status); + return Err(status); } + Ok(()) } pub fn close(&self) { @@ -1499,13 +1623,14 @@ impl Connection { unsafe { *(stat_buffer.as_ptr() as *const c_void as *const QuicStatisticsV2) } } - pub fn set_configuration(&self, configuration: &Configuration) { + pub fn set_configuration(&self, configuration: &Configuration) -> Result<(), u32> { let status = unsafe { ((*self.table).connection_set_configuration)(self.handle, configuration.handle) }; if Status::failed(status) { - panic!("ConnectionSetConfiguration failure 0x{:x}", status); + return Err(status); } + Ok(()) } pub fn set_callback_handler(&self, handler: ConnectionEventHandler, context: *const c_void) { @@ -1531,7 +1656,7 @@ impl Connection { buffer_count: u32, flags: SendFlags, client_send_context: *const c_void, - ) { + ) -> Result<(), u32> { let status = unsafe { ((*self.table).datagram_send)( self.handle, @@ -1542,14 +1667,15 @@ impl Connection { ) }; if Status::failed(status) { - panic!("DatagramSend failure 0x{:x}", status); + return Err(status); } + Ok(()) } pub fn resumption_ticket_validation_complete( &self, result: BOOLEAN, - ) { + ) -> Result<(), u32> { let status = unsafe { ((*self.table).resumption_ticket_validation_complete)( self.handle, @@ -1557,15 +1683,16 @@ impl Connection { ) }; if Status::failed(status) { - panic!("ticket validation completion failure 0x{:x}", status); + return Err(status); } + Ok(()) } pub fn certificate_validation_complete( &self, result: BOOLEAN, tls_alert: TlsAlertCode, - ) { + ) -> Result<(), u32> { let status = unsafe { ((*self.table).certificate_validation_complete)( self.handle, @@ -1574,8 +1701,9 @@ impl Connection { ) }; if Status::failed(status) { - panic!("ticket validation completion failure 0x{:x}", status); + return Err(status); } + Ok(()) } } @@ -1590,7 +1718,7 @@ impl Listener { registration: &Registration, handler: ListenerEventHandler, context: *const c_void, - ) -> Listener { + ) -> Result { let new_listener: Handle = ptr::null(); let status = unsafe { ((*registration.table).listener_open)( @@ -1601,16 +1729,16 @@ impl Listener { ) }; if Status::failed(status) { - panic!("ListenerOpen failed, {:x}!\n", status); + return Err(status); } - Listener { + Ok(Listener { table: registration.table, handle: new_listener, - } + }) } - pub fn start(&self, alpn: &[Buffer], local_address: &Addr) { + pub fn start(&self, alpn: &[Buffer], local_address: &Addr) -> Result<(), u32> { let status = unsafe { ((*self.table).listener_start)( self.handle, @@ -1620,8 +1748,9 @@ impl Listener { ) }; if Status::failed(status) { - panic!("ListenerStart failed, {:x}!\n", status); + return Err(status); } + Ok(()) } pub fn close(&self) { @@ -1659,20 +1788,22 @@ impl Stream { flags: StreamOpenFlags, handler: StreamEventHandler, context: *const c_void, - ) { + ) -> Result<(), u32> { let status = unsafe { ((*self.table).stream_open)(connection.handle, flags, handler, context, &self.handle) }; if Status::failed(status) { - panic!("StreamOpen failure 0x{:x}", status); + return Err(status); } + Ok(()) } - pub fn start(&self, flags: StreamStartFlags) { + pub fn start(&self, flags: StreamStartFlags) -> Result<(), u32> { let status = unsafe { ((*self.table).stream_start)(self.handle, flags) }; if Status::failed(status) { - panic!("StreamStart failure 0x{:x}", status); + return Err(status); } + Ok(()) } pub fn close(&self) { @@ -1687,7 +1818,7 @@ impl Stream { buffer_count: u32, flags: SendFlags, client_send_context: *const c_void, - ) { + ) -> Result<(), u32> { let status = unsafe { ((*self.table).stream_send)( self.handle, @@ -1698,8 +1829,9 @@ impl Stream { ) }; if Status::failed(status) { - panic!("StreamSend failure 0x{:x}", status); + return Err(status); } + Ok(()) } pub fn set_callback_handler(&self, handler: StreamEventHandler, context: *const c_void) { @@ -1782,27 +1914,39 @@ extern "C" fn test_stream_callback( #[test] fn test_module() { - let api = Api::new(); - let registration = Registration::new(&api, ptr::null()); + let res = Api::new(); + assert!(res.is_ok(), "Failed to open API: 0x{:x}", res.err().unwrap()); + let api = res.unwrap(); + + let res = Registration::new(&api, ptr::null()); + assert!(res.is_ok(), "Failed to open registration: 0x{:x}", res.err().unwrap()); + let registration = res.unwrap(); let alpn = [Buffer::from("h3")]; - let configuration = Configuration::new( + let res = Configuration::new( ®istration, &alpn, Settings::new() .set_peer_bidi_stream_count(100) .set_peer_unidi_stream_count(3), ); + assert!(res.is_ok(), "Failed to open configuration: 0x{:x}", res.err().unwrap()); + let configuration = res.unwrap(); + let cred_config = CredentialConfig::new_client(); - configuration.load_credential(&cred_config); + let res = configuration.load_credential(&cred_config); + assert!(res.is_ok(), "Failed to load credential: 0x{:x}", res.err().unwrap()); let connection = Connection::new(®istration); - connection.open( + let res = connection.open( ®istration, test_conn_callback, &connection as *const Connection as *const c_void, ); - connection.start(&configuration, "www.cloudflare.com", 443); + assert!(res.is_ok(), "Failed to open connection: 0x{:x}", res.err().unwrap()); + + let res = connection.start(&configuration, "www.cloudflare.com", 443); + assert!(res.is_ok(), "Failed to start connection: 0x{:x}", res.err().unwrap()); let duration = std::time::Duration::from_millis(1000); std::thread::sleep(duration); From a1b32b9714aff39e6785a9483cc0aaefb59f4f31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 07:47:00 -0500 Subject: [PATCH 04/29] Bump codecov/codecov-action from 5.0.7 to 5.1.1 (#4693) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.0.7 to 5.1.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/015f24e6818733317a2da2edd6290ab26238649a...7f8b4b4bde536c465e797be725718b88c5d95e0e) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/code-coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index 739b7b9430..8e9fbe0844 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -233,7 +233,7 @@ jobs: with: name: merged - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a + uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e with: fail_ci_if_error: true files: msquiccoverage.xml From c1a40870c775129ca93f988a88718371d24cbd79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 07:47:43 -0500 Subject: [PATCH 05/29] Bump github/codeql-action from 3.27.5 to 3.27.6 (#4694) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.5 to 3.27.6. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/f09c1c0a94de965c15400f5634aa42fac8fb8f88...aa578102511db1f4524ed59b8cc2bae4f6e88195) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 27efa8a943..5f114f5c8b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -51,7 +51,7 @@ jobs: cmake --build . --target OpenSSL_Target - name: Initialize CodeQL - uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 + uses: github/codeql-action/init@aa578102511db1f4524ed59b8cc2bae4f6e88195 with: languages: cpp config-file: ./.github/codeql/codeql-config.yml @@ -62,4 +62,4 @@ jobs: cmake --build . - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 + uses: github/codeql-action/analyze@aa578102511db1f4524ed59b8cc2bae4f6e88195 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 5d7c19c32b..5f36ba791b 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -51,6 +51,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 + uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 with: sarif_file: results.sarif From 80943ed4106ca4c6dbdd1cfea3a96d7d29731960 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:07:25 +0000 Subject: [PATCH 06/29] Bump step-security/harden-runner from 2.10.1 to 2.10.2 (#4662) Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.10.1 to 2.10.2. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/91182cccc01eb5e619899d80e4e971d6181294a7...0080882f6c36860b6ba35c610c98ce87d4e2f26f) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cargo.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/docker-publish-xcomp.yml | 2 +- .github/workflows/docker-publish.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index c5ec3b0480..bf8b20c4e5 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -21,7 +21,7 @@ jobs: name: Cargo steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5f114f5c8b..a4b1728f2a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/docker-publish-xcomp.yml b/.github/workflows/docker-publish-xcomp.yml index 6f6d3db4db..f4cf2e2da2 100644 --- a/.github/workflows/docker-publish-xcomp.yml +++ b/.github/workflows/docker-publish-xcomp.yml @@ -40,7 +40,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f with: egress-policy: audit diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index d32091ccea..7d13243e01 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -26,7 +26,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f with: egress-policy: audit - name: Checkout repository From 0d8e7dfd5bd9acae2f2a8a6d7b351fcc3ab6e0f8 Mon Sep 17 00:00:00 2001 From: talregev Date: Tue, 10 Dec 2024 15:53:26 +0200 Subject: [PATCH 07/29] Refactor: (#4692) - Add namespace - Enable sanitize builds - Refactor platform unittest external cmake --- .github/workflows/build-reuse-win.yml | 4 ++-- src/bin/CMakeLists.txt | 2 +- src/platform/unittest/external/CMakeLists.txt | 14 ++++++-------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-reuse-win.yml b/.github/workflows/build-reuse-win.yml index 7b65871bdf..e13e5ef9f2 100644 --- a/.github/workflows/build-reuse-win.yml +++ b/.github/workflows/build-reuse-win.yml @@ -87,11 +87,11 @@ jobs: shell: pwsh run: scripts/build.ps1 -Config ${{ inputs.config }} -Platform ${{ inputs.plat }} -Arch ${{ inputs.arch }} -Tls ${{ inputs.tls }} -DisablePerf -DynamicCRT ${{ inputs.sanitize }} - name: Build External Platform Test - if: inputs.build == '-Test' && inputs.sanitize != '-Sanitize' + if: inputs.build == '-Test' shell: pwsh run: | cmake --install build\${{ inputs.plat }}\${{ inputs.arch }}_${{ inputs.tls }} --config ${{ inputs.config }} - cmake src/platform/unittest/external -G "Visual Studio 17 2022" -A ${{ inputs.arch }} -B build_external "-DCMAKE_INSTALL_PREFIX:PATH=C:/Program Files/msquic" -DQUIC_TLS=${{ inputs.tls }} + cmake src/platform/unittest/external -G "Visual Studio 17 2022" -A ${{ inputs.arch }} -B build_external "-DCMAKE_INSTALL_PREFIX:PATH=C:/Program Files/msquic" cmake --build build_external --config ${{ inputs.config }} - name: Build For Perf if: inputs.build == '-Perf' diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt index 1262cb20b4..6b84d4555c 100644 --- a/src/bin/CMakeLists.txt +++ b/src/bin/CMakeLists.txt @@ -274,7 +274,7 @@ configure_file(msquic-config.cmake.in ${CMAKE_BINARY_DIR}/msquic-config.cmake) install(FILES ${CMAKE_BINARY_DIR}/msquic-config.cmake DESTINATION share/msquic) if(BUILD_SHARED_LIBS) - install(EXPORT msquic DESTINATION share/msquic) + install(EXPORT msquic NAMESPACE msquic:: DESTINATION share/msquic) endif() if (MSVC AND NOT QUIC_ENABLE_SANITIZERS AND BUILD_SHARED_LIBS) diff --git a/src/platform/unittest/external/CMakeLists.txt b/src/platform/unittest/external/CMakeLists.txt index 805b18ff40..cfb1ccba9b 100644 --- a/src/platform/unittest/external/CMakeLists.txt +++ b/src/platform/unittest/external/CMakeLists.txt @@ -5,12 +5,9 @@ cmake_minimum_required(VERSION 3.16) project(msquic_platform_external) -find_package(msquic REQUIRED) -find_library(MSPLATFORM_LIBRARIES - NAMES msquic_platform) +find_package(msquic CONFIG REQUIRED) message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") -message(STATUS "MSPLATFORM_LIBRARIES: ${MSPLATFORM_LIBRARIES}") include(FetchContent) FetchContent_Declare( @@ -28,11 +25,12 @@ set(SOURCES ../TlsTest.cpp ) -if(QUIC_TLS STREQUAL "openssl" OR QUIC_TLS STREQUAL "openssl3") - list(APPEND OTHER_TERGETS OpenSSL) -endif() +# Remove QUIC_EVENTS_MANIFEST_ETW and QUIC_LOGS_MANIFEST_ETW definitions. These definitions for internal use in msquic +get_target_property(defs msquic::inc INTERFACE_COMPILE_DEFINITIONS) +list(FILTER defs EXCLUDE REGEX "^(QUIC_EVENTS_MANIFEST_ETW|QUIC_LOGS_MANIFEST_ETW)$") +set_target_properties(msquic::inc PROPERTIES INTERFACE_COMPILE_DEFINITIONS "${defs}") add_executable(msquicplatformtest ${SOURCES}) target_include_directories(msquicplatformtest PRIVATE ${CMAKE_INSTALL_PREFIX}/include) -target_link_libraries(msquicplatformtest PRIVATE msquic ${MSPLATFORM_LIBRARIES} ${OTHER_TERGETS} gtest ws2_32 schannel ntdll bcrypt ncrypt crypt32 iphlpapi advapi32 secur32 userenv onecore winmm wbemuuid clang_rt.asan_dbg_dynamic-x86_64 clang_rt.asan_dynamic-x86_64) +target_link_libraries(msquicplatformtest PRIVATE gtest msquic::msquic msquic::msquic_platform ws2_32 ntdll ncrypt crypt32 iphlpapi) target_compile_definitions(msquicplatformtest PRIVATE QUIC_EVENTS_STUB QUIC_LOGS_STUB _DISABLE_VECTOR_ANNOTATION _DISABLE_STRING_ANNOTATION) From 1c3448cb5b3b83b67891708fdf1e97459efcb674 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 10 Dec 2024 15:05:42 +0100 Subject: [PATCH 08/29] Update Alpine Release doc (#4699) * Update Alpine Release doc * Fix numbering in release documentation steps --- docs/Release.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Release.md b/docs/Release.md index c5549a0ddf..b43e1c97c2 100644 --- a/docs/Release.md +++ b/docs/Release.md @@ -106,7 +106,9 @@ When testing the pipeline, please make sure to comment out the PMC cli commands Prerequisites: - Docker +- Powershell +1. Checkout to release tag. (e.g. `git checkout v2.4.7`) 1. Run `generate-alpine-packaging-file.ps1` script on host computer to create `APKBUILD` file for the release. (This script can run on any Linux distro, and this script will create a docker alpine container to calculate hash keys in APKBUILD file) 1. If you don't have account for [AlpineLinux GitLab](https://gitlab.alpinelinux.org). Create an account and [configure your SSH](https://docs.gitlab.com/ee/user/ssh.html). 1. If you didn't fork `aports` repository yet, Fork `https://gitlab.alpinelinux.org/alpine/aports`. From 21e5b41e4e9f88d809de4c78e461b57641bfca8e Mon Sep 17 00:00:00 2001 From: Daiki AMINAKA <1991.daiki@gmail.com> Date: Tue, 10 Dec 2024 13:03:24 -0800 Subject: [PATCH 09/29] potential memory leak without setting Status (#4702) --- src/platform/datapath_raw_xdp_win.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/platform/datapath_raw_xdp_win.c b/src/platform/datapath_raw_xdp_win.c index 461d4fcdec..370b53a529 100644 --- a/src/platform/datapath_raw_xdp_win.c +++ b/src/platform/datapath_raw_xdp_win.c @@ -578,10 +578,11 @@ CxPlatDpRawInterfaceInitialize( if (!SetFileCompletionNotificationModes( (HANDLE)Queue->RxXsk, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS | FILE_SKIP_SET_EVENT_ON_HANDLE)) { + Status = QUIC_STATUS_INTERNAL_ERROR; QuicTraceEvent( LibraryErrorStatus, "[ lib] ERROR, %u, %s.", - Status, + GetLastError(), "SetFileCompletionNotificationModes"); goto Error; } @@ -700,10 +701,11 @@ CxPlatDpRawInterfaceInitialize( if (!SetFileCompletionNotificationModes( (HANDLE)Queue->TxXsk, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS | FILE_SKIP_SET_EVENT_ON_HANDLE)) { + Status = QUIC_STATUS_INTERNAL_ERROR; QuicTraceEvent( LibraryErrorStatus, "[ lib] ERROR, %u, %s.", - Status, + GetLastError(), "SetFileCompletionNotificationModes"); goto Error; } From d337a3cc84a55af499bf0fceef8dfead36111bd9 Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Thu, 12 Dec 2024 10:30:41 -0500 Subject: [PATCH 10/29] Restrict MaxOperationsPerDrain to Greater Than Zero (#4706) --- src/core/settings.c | 5 ++++- src/test/lib/ApiTest.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/core/settings.c b/src/core/settings.c index a3942f691d..40dd41245f 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -431,6 +431,9 @@ QuicSettingApply( Destination->IsSet.DatagramReceiveEnabled = TRUE; } if (Source->IsSet.MaxOperationsPerDrain && (!Destination->IsSet.MaxOperationsPerDrain || OverWrite)) { + if (Source->MaxOperationsPerDrain == 0) { + return FALSE; + } Destination->MaxOperationsPerDrain = Source->MaxOperationsPerDrain; Destination->IsSet.MaxOperationsPerDrain = TRUE; } @@ -795,7 +798,7 @@ QuicSettingsLoad( QUIC_SETTING_MAX_OPERATIONS_PER_DRAIN, (uint8_t*)&Value, &ValueLen); - if (Value <= UINT8_MAX) { + if (Value > 0 && Value <= UINT8_MAX) { Settings->MaxOperationsPerDrain = (uint8_t)Value; } } diff --git a/src/test/lib/ApiTest.cpp b/src/test/lib/ApiTest.cpp index 4935cf1d65..71bda9c8ef 100644 --- a/src/test/lib/ApiTest.cpp +++ b/src/test/lib/ApiTest.cpp @@ -2090,6 +2090,32 @@ void SettingApplyTests(HQUIC Handle, uint32_t Param, bool AllowMtuEcnChanges = t sizeof(QUIC_SETTINGS), &Settings)); } + + // + // MaxOperationsPerDrain + // + { + QUIC_SETTINGS Settings{0}; + Settings.IsSet.MaxOperationsPerDrain = TRUE; + + Settings.MaxOperationsPerDrain = 0; // Not allowed + TEST_QUIC_STATUS( + QUIC_STATUS_INVALID_PARAMETER, + MsQuic->SetParam( + Handle, + Param, + sizeof(QUIC_SETTINGS), + &Settings)); + + Settings.MaxOperationsPerDrain = 255; // Max allowed + TEST_QUIC_STATUS( + QUIC_STATUS_SUCCESS, + MsQuic->SetParam( + Handle, + Param, + sizeof(QUIC_SETTINGS), + &Settings)); + } } void QuicTestStatefulGlobalSetParam() From 810b373908c0feb366c72e342806096a56da440b Mon Sep 17 00:00:00 2001 From: talregev Date: Fri, 13 Dec 2024 17:26:12 +0200 Subject: [PATCH 11/29] Add alias (#4704) --- src/bin/msquic-config.cmake.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bin/msquic-config.cmake.in b/src/bin/msquic-config.cmake.in index dd676243fe..fba676be99 100644 --- a/src/bin/msquic-config.cmake.in +++ b/src/bin/msquic-config.cmake.in @@ -2,3 +2,9 @@ include(CMakeFindDependencyMacro) @FILENAME_DEP_REPLACE@ include(${SELF_DIR}/msquic.cmake) + +foreach(_t IN ITEMS msquic msquic_platform) + if(TARGET msquic::${_t} AND NOT TARGET ${_t}) + add_library(${_t} ALIAS msquic::${_t}) + endif() +endforeach() From ff080df4cd46efa0b7de3a2681a23d53a4d3628b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 08:20:22 -0500 Subject: [PATCH 12/29] Bump github/codeql-action from 3.27.6 to 3.27.9 (#4710) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.6 to 3.27.9. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/aa578102511db1f4524ed59b8cc2bae4f6e88195...df409f7d9260372bd5f19e5b04e83cb3c43714ae) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/scorecards-analysis.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a4b1728f2a..67bb9f63c6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -51,7 +51,7 @@ jobs: cmake --build . --target OpenSSL_Target - name: Initialize CodeQL - uses: github/codeql-action/init@aa578102511db1f4524ed59b8cc2bae4f6e88195 + uses: github/codeql-action/init@df409f7d9260372bd5f19e5b04e83cb3c43714ae with: languages: cpp config-file: ./.github/codeql/codeql-config.yml @@ -62,4 +62,4 @@ jobs: cmake --build . - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@aa578102511db1f4524ed59b8cc2bae4f6e88195 + uses: github/codeql-action/analyze@df409f7d9260372bd5f19e5b04e83cb3c43714ae diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 5f36ba791b..dbd6cfb323 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -51,6 +51,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 + uses: github/codeql-action/upload-sarif@df409f7d9260372bd5f19e5b04e83cb3c43714ae with: sarif_file: results.sarif From 5801a8b1c95d1dae1cadfc2757c4a9b951541899 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 08:20:49 -0500 Subject: [PATCH 13/29] Bump submodules/googletest from `35d0c36` to `79219e2` (#4709) Bumps [submodules/googletest](https://github.com/google/googletest) from `35d0c36` to `79219e2`. - [Release notes](https://github.com/google/googletest/releases) - [Commits](https://github.com/google/googletest/compare/35d0c365609296fa4730d62057c487e3cfa030ff...79219e26e0e36b415a5804b6b017ad6c6cd99ad8) --- updated-dependencies: - dependency-name: submodules/googletest dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- submodules/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/googletest b/submodules/googletest index 35d0c36560..79219e26e0 160000 --- a/submodules/googletest +++ b/submodules/googletest @@ -1 +1 @@ -Subproject commit 35d0c365609296fa4730d62057c487e3cfa030ff +Subproject commit 79219e26e0e36b415a5804b6b017ad6c6cd99ad8 From f8e9cece975f05a394d476d4257e021004dcf910 Mon Sep 17 00:00:00 2001 From: Masahiro Kozuka Date: Tue, 17 Dec 2024 22:03:53 +0900 Subject: [PATCH 14/29] Add feature flags for static builds (#4691) --- .github/workflows/cargo.yml | 5 +++-- Cargo.toml | 4 ++++ scripts/build.rs | 23 ++++++++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index bf8b20c4e5..3f59a77a48 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -17,6 +17,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-xlarge] + features: ["", "--features static"] runs-on: ${{ matrix.os }} name: Cargo steps: @@ -41,8 +42,8 @@ jobs: if: runner.os == 'Linux' run: curl https://sh.rustup.rs -sSf | sh -s -- -y - name: Cargo build - run: cargo build --all + run: cargo build --all ${{ matrix.features }} - name: Cargo test - run: cargo test --all + run: cargo test --all ${{ matrix.features }} - name: Cargo Publish (dry run) run: cargo publish --dry-run --allow-dirty diff --git a/Cargo.toml b/Cargo.toml index 9188ecd5be..046819e8f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,10 @@ include = [ "/THIRD-PARTY-NOTICES", ] +[features] +default = [] +static = [] + [build-dependencies] cmake = "0.1" diff --git a/scripts/build.rs b/scripts/build.rs index 2881cb0001..fd206a43b7 100644 --- a/scripts/build.rs +++ b/scripts/build.rs @@ -13,13 +13,19 @@ fn main() { } let target = env::var("TARGET").unwrap(); + let out_dir = env::var("OUT_DIR").unwrap(); + // The output directory for the native MsQuic library. + let quic_output_dir = Path::new(&out_dir).join("lib"); // Builds the native MsQuic and installs it into $OUT_DIR. let mut config = Config::new("."); config .define("QUIC_ENABLE_LOGGING", logging_enabled) .define("QUIC_TLS", "openssl") - .define("QUIC_OUTPUT_DIR", "../lib"); + .define("QUIC_OUTPUT_DIR", quic_output_dir.to_str().unwrap()); + if cfg!(feature = "static") { + config.define("QUIC_BUILD_SHARED", "off"); + } // macos-latest's cargo automatically specify --target=${ARCH}-apple-macosx14.5 // which conflicts with -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}. @@ -38,4 +44,19 @@ fn main() { let dst = config.build(); let lib_path = Path::join(Path::new(&dst), Path::new(path_extra)); println!("cargo:rustc-link-search=native={}", lib_path.display()); + if cfg!(feature = "static") { + if cfg!(target_os = "linux") { + let numa_lib_path = match target.as_str() { + "x86_64-unknown-linux-gnu" => "/usr/lib/x86_64-linux-gnu", + "aarch64-unknown-linux-gnu" => "/usr/lib/aarch64-linux-gnu", + _ => panic!("Unsupported target: {}", target), + }; + println!("cargo:rustc-link-search=native={}", numa_lib_path); + println!("cargo:rustc-link-lib=static:+whole-archive=numa"); + } else if cfg!(target_os = "macos") { + println!("cargo:rustc-link-lib=framework=CoreFoundation"); + println!("cargo:rustc-link-lib=framework=Security"); + } + println!("cargo:rustc-link-lib=static=msquic"); + } } From 62ecc1648de3bdd5757ed3112db0dd68f54d4f2e Mon Sep 17 00:00:00 2001 From: youyuanwu <48816116+youyuanwu@users.noreply.github.com> Date: Wed, 18 Dec 2024 06:49:25 -0800 Subject: [PATCH 15/29] Run fmt and clippy for rust code (#4712) --- .github/workflows/cargo.yml | 4 + scripts/build.rs | 4 +- src/lib.rs | 145 ++++++++++++++++-------------------- 3 files changed, 71 insertions(+), 82 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index 3f59a77a48..689676fdbe 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -41,6 +41,10 @@ jobs: - name: Install Cargo if: runner.os == 'Linux' run: curl https://sh.rustup.rs -sSf | sh -s -- -y + - name: Cargo fmt + run: cargo fmt --all -- --check + - name: Cargo clippy + run: cargo clippy --all-targets -- -D warnings - name: Cargo build run: cargo build --all ${{ matrix.features }} - name: Cargo test diff --git a/scripts/build.rs b/scripts/build.rs index fd206a43b7..5e3d8ba4f5 100644 --- a/scripts/build.rs +++ b/scripts/build.rs @@ -2,8 +2,8 @@ // Licensed under the MIT License. use cmake::Config; -use std::path::Path; use std::env; +use std::path::Path; fn main() { let path_extra = "lib"; @@ -38,7 +38,7 @@ fn main() { "aarch64-apple-darwin" => config .define("CMAKE_OSX_ARCHITECTURES", "arm64") .define("CMAKE_OSX_DEPLOYMENT_TARGET", "14.5"), - _ => &mut config + _ => &mut config, }; let dst = config.build(); diff --git a/src/lib.rs b/src/lib.rs index 70ed8e3001..f1e48c6fa1 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,8 +33,11 @@ pub type BOOLEAN = ::std::os::raw::c_uchar; /// Family of an IP address. pub type AddressFamily = u16; +#[allow(clippy::unnecessary_cast)] pub const ADDRESS_FAMILY_UNSPEC: AddressFamily = c_types::AF_UNSPEC as u16; +#[allow(clippy::unnecessary_cast)] pub const ADDRESS_FAMILY_INET: AddressFamily = c_types::AF_INET as u16; +#[allow(clippy::unnecessary_cast)] pub const ADDRESS_FAMILY_INET6: AddressFamily = c_types::AF_INET6 as u16; /// IPv4 address payload. @@ -73,7 +76,7 @@ impl Addr { Addr { ipv4: sockaddr_in { family, - port: port, + port, addr, zero: [0, 0, 0, 0, 0, 0, 0, 0], }, @@ -92,7 +95,7 @@ impl Addr { Addr { ipv6: sockaddr_in6 { family, - port: port, + port, flow_info, addr, scope_id, @@ -128,7 +131,7 @@ mod status { pub const QUIC_STATUS_ALPN_NEG_FAILURE: u32 = 0x80410007; pub const QUIC_STATUS_STREAM_LIMIT_REACHED: u32 = 0x80410008; pub const QUIC_STATUS_ALPN_IN_USE: u32 = 0x80410009; - pub const QUIC_STATUS_CLOSE_NOTIFY: u32 = 0x80410100 | 0; + pub const QUIC_STATUS_CLOSE_NOTIFY: u32 = 0x80410100; pub const QUIC_STATUS_BAD_CERTIFICATE: u32 = 0x80410100 | 42; pub const QUIC_STATUS_UNSUPPORTED_CERTIFICATE: u32 = 0x80410100 | 43; pub const QUIC_STATUS_REVOKED_CERTIFICATE: u32 = 0x80410100 | 44; @@ -143,8 +146,8 @@ mod status { #[cfg(target_os = "linux")] mod status { pub const QUIC_STATUS_SUCCESS: u32 = 0; - pub const QUIC_STATUS_PENDING: u32 = 0xFFFFFFFE; /// -2 - pub const QUIC_STATUS_CONTINUE: u32 = 0xFFFFFFFF; /// -1 + pub const QUIC_STATUS_PENDING: u32 = 0xFFFFFFFE; // -2 + pub const QUIC_STATUS_CONTINUE: u32 = 0xFFFFFFFF; // -1 pub const QUIC_STATUS_OUT_OF_MEMORY: u32 = 12; pub const QUIC_STATUS_INVALID_PARAMETER: u32 = 22; pub const QUIC_STATUS_INVALID_STATE: u32 = 1; @@ -183,8 +186,8 @@ mod status { #[cfg(target_os = "macos")] mod status { pub const QUIC_STATUS_SUCCESS: u32 = 0; - pub const QUIC_STATUS_PENDING: u32 = 0xFFFFFFFE; /// -2 - pub const QUIC_STATUS_CONTINUE: u32 = 0xFFFFFFFF; /// -1 + pub const QUIC_STATUS_PENDING: u32 = 0xFFFFFFFE; // -2 + pub const QUIC_STATUS_CONTINUE: u32 = 0xFFFFFFFF; // -1 pub const QUIC_STATUS_OUT_OF_MEMORY: u32 = 12; pub const QUIC_STATUS_INVALID_PARAMETER: u32 = 22; pub const QUIC_STATUS_INVALID_STATE: u32 = 1; @@ -780,7 +783,7 @@ pub struct QuicTlsSecrets { } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Default)] pub struct Settings { pub is_set_flags: u64, pub max_bytes_per_key: u64, @@ -1216,15 +1219,10 @@ struct ApiTable { flags: SendFlags, client_send_context: *const c_void, ) -> u32, - resumption_ticket_validation_complete: extern "C" fn( - connection: Handle, - result: BOOLEAN, - ) -> u32, - certificate_validation_complete: extern "C" fn( - connection: Handle, - result: BOOLEAN, - tls_alert: TlsAlertCode - ) -> u32, + resumption_ticket_validation_complete: + extern "C" fn(connection: Handle, result: BOOLEAN) -> u32, + certificate_validation_complete: + extern "C" fn(connection: Handle, result: BOOLEAN, tls_alert: TlsAlertCode) -> u32, } #[link(name = "msquic")] @@ -1296,11 +1294,10 @@ impl From<&Vec> for Buffer { impl From<&[u8]> for Buffer { fn from(data: &[u8]) -> Buffer { - let buffer = Buffer { + Buffer { length: data.len() as u32, buffer: data.as_ptr() as *mut u8, - }; - buffer + } } } @@ -1321,38 +1318,8 @@ impl QuicPerformance { } impl Settings { - pub fn new() -> Settings { - Settings { - is_set_flags: 0, - max_bytes_per_key: 0, - handshake_idle_timeout_ms: 0, - idle_timeout_ms: 0, - mtu_discovery_search_complete_timeout_us: 0, - tls_client_max_send_buffer: 0, - tls_server_max_send_buffer: 0, - stream_recv_window_default: 0, - stream_recv_buffer_default: 0, - conn_flow_control_window: 0, - max_worker_queue_delay_us: 0, - max_stateless_operations: 0, - initial_window_packets: 0, - send_idle_timeout_ms: 0, - initiall_rtt_ms: 0, - max_ack_delay_ms: 0, - disconnect_timeout_ms: 0, - keep_alive_interval_ms: 0, - congestion_control_algorithm: 0, - peer_bidi_stream_count: 0, - peer_unidi_stream_count: 0, - max_binding_stateless_operations: 0, - stateless_operation_expiration_ms: 0, - minimum_mtu: 0, - maximum_mtu: 0, - other_flags: 0, - mtu_operations_per_drain: 0, - mtu_discovery_missing_probe_count: 0, - dest_cid_update_idle_timeout_ms: 0, - } + pub fn new() -> Self { + Self::default() } pub fn set_peer_bidi_stream_count(&mut self, value: u16) -> &mut Settings { self.is_set_flags |= 0x40000; @@ -1483,7 +1450,7 @@ impl Configuration { let context: *const c_void = ptr::null(); let new_configuration: Handle = ptr::null(); let mut settings_size: u32 = 0; - if settings != ptr::null() { + if !settings.is_null() { settings_size = ::std::mem::size_of::() as u32; } let status = unsafe { @@ -1508,7 +1475,7 @@ impl Configuration { pub fn load_credential(&self, cred_config: &CredentialConfig) -> Result<(), u32> { let status = - unsafe { ((*self.table).configuration_load_credential)(self.handle, *&cred_config) }; + unsafe { ((*self.table).configuration_load_credential)(self.handle, cred_config) }; if Status::failed(status) { return Err(status); } @@ -1552,14 +1519,19 @@ impl Connection { Ok(()) } - pub fn start(&self, configuration: &Configuration, server_name: &str, server_port: u16) -> Result<(), u32> { + pub fn start( + &self, + configuration: &Configuration, + server_name: &str, + server_port: u16, + ) -> Result<(), u32> { let server_name_safe = std::ffi::CString::new(server_name).unwrap(); let status = unsafe { ((*self.table).connection_start)( self.handle, configuration.handle, 0, - server_name_safe.as_ptr() as *const i8, + server_name_safe.as_ptr(), server_port, ) }; @@ -1660,7 +1632,7 @@ impl Connection { let status = unsafe { ((*self.table).datagram_send)( self.handle, - *&buffer, + buffer, buffer_count, flags, client_send_context, @@ -1672,16 +1644,9 @@ impl Connection { Ok(()) } - pub fn resumption_ticket_validation_complete( - &self, - result: BOOLEAN, - ) -> Result<(), u32> { - let status = unsafe { - ((*self.table).resumption_ticket_validation_complete)( - self.handle, - result, - ) - }; + pub fn resumption_ticket_validation_complete(&self, result: BOOLEAN) -> Result<(), u32> { + let status = + unsafe { ((*self.table).resumption_ticket_validation_complete)(self.handle, result) }; if Status::failed(status) { return Err(status); } @@ -1694,11 +1659,7 @@ impl Connection { tls_alert: TlsAlertCode, ) -> Result<(), u32> { let status = unsafe { - ((*self.table).certificate_validation_complete)( - self.handle, - result, - tls_alert, - ) + ((*self.table).certificate_validation_complete)(self.handle, result, tls_alert) }; if Status::failed(status) { return Err(status); @@ -1744,7 +1705,7 @@ impl Listener { self.handle, alpn.as_ptr(), alpn.len() as u32, - *&local_address, + local_address, ) }; if Status::failed(status) { @@ -1822,7 +1783,7 @@ impl Stream { let status = unsafe { ((*self.table).stream_send)( self.handle, - *&buffer, + buffer, buffer_count, flags, client_send_context, //(self as *const Stream) as *const c_void, @@ -1915,11 +1876,19 @@ extern "C" fn test_stream_callback( #[test] fn test_module() { let res = Api::new(); - assert!(res.is_ok(), "Failed to open API: 0x{:x}", res.err().unwrap()); + assert!( + res.is_ok(), + "Failed to open API: 0x{:x}", + res.err().unwrap() + ); let api = res.unwrap(); let res = Registration::new(&api, ptr::null()); - assert!(res.is_ok(), "Failed to open registration: 0x{:x}", res.err().unwrap()); + assert!( + res.is_ok(), + "Failed to open registration: 0x{:x}", + res.err().unwrap() + ); let registration = res.unwrap(); let alpn = [Buffer::from("h3")]; @@ -1930,12 +1899,20 @@ fn test_module() { .set_peer_bidi_stream_count(100) .set_peer_unidi_stream_count(3), ); - assert!(res.is_ok(), "Failed to open configuration: 0x{:x}", res.err().unwrap()); + assert!( + res.is_ok(), + "Failed to open configuration: 0x{:x}", + res.err().unwrap() + ); let configuration = res.unwrap(); let cred_config = CredentialConfig::new_client(); let res = configuration.load_credential(&cred_config); - assert!(res.is_ok(), "Failed to load credential: 0x{:x}", res.err().unwrap()); + assert!( + res.is_ok(), + "Failed to load credential: 0x{:x}", + res.err().unwrap() + ); let connection = Connection::new(®istration); let res = connection.open( @@ -1943,10 +1920,18 @@ fn test_module() { test_conn_callback, &connection as *const Connection as *const c_void, ); - assert!(res.is_ok(), "Failed to open connection: 0x{:x}", res.err().unwrap()); + assert!( + res.is_ok(), + "Failed to open connection: 0x{:x}", + res.err().unwrap() + ); let res = connection.start(&configuration, "www.cloudflare.com", 443); - assert!(res.is_ok(), "Failed to start connection: 0x{:x}", res.err().unwrap()); + assert!( + res.is_ok(), + "Failed to start connection: 0x{:x}", + res.err().unwrap() + ); let duration = std::time::Duration::from_millis(1000); std::thread::sleep(duration); From a03d5c2178108fcc3e151c610c37459eb967d457 Mon Sep 17 00:00:00 2001 From: Masahiro Kozuka Date: Fri, 20 Dec 2024 04:17:11 +0900 Subject: [PATCH 16/29] Add socket2 integration for address handling and retrieval (#4716) --- Cargo.toml | 1 + src/lib.rs | 146 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 98 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 046819e8f1..e940c6f816 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,3 +56,4 @@ bitfield = "0.17.0" libc = "0.2.0" c-types = "4.0.0" serde = { version = "1.0.117", features = ["derive"] } +socket2 = "0.5.8" diff --git a/src/lib.rs b/src/lib.rs index f1e48c6fa1..f695ca8387 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,10 +7,15 @@ use c_types::AF_INET; use c_types::AF_INET6; #[allow(unused_imports)] use c_types::AF_UNSPEC; +use c_types::{sa_family_t, sockaddr_in, sockaddr_in6, socklen_t}; use libc::c_void; use serde::{Deserialize, Serialize}; +use socket2::SockAddr; use std::convert::TryInto; use std::fmt; +use std::io; +use std::mem; +use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::option::Option; use std::ptr; use std::result::Result; @@ -40,27 +45,6 @@ pub const ADDRESS_FAMILY_INET: AddressFamily = c_types::AF_INET as u16; #[allow(clippy::unnecessary_cast)] pub const ADDRESS_FAMILY_INET6: AddressFamily = c_types::AF_INET6 as u16; -/// IPv4 address payload. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct sockaddr_in { - pub family: AddressFamily, - pub port: u16, - pub addr: u32, - pub zero: [u8; 8usize], -} - -/// IPv6 address payload. -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct sockaddr_in6 { - pub family: AddressFamily, - pub port: u16, - pub flow_info: u32, - pub addr: [u8; 16usize], - pub scope_id: u32, -} - /// Generic representation of IPv4 or IPv6 addresses. #[repr(C)] #[derive(Copy, Clone)] @@ -70,40 +54,66 @@ pub union Addr { } impl Addr { - /// Create a representation of IPv4 address and perform Network byte order conversion - /// on the port number. - pub fn ipv4(family: u16, port: u16, addr: u32) -> Addr { - Addr { - ipv4: sockaddr_in { - family, - port, - addr, - zero: [0, 0, 0, 0, 0, 0, 0, 0], - }, + /// Converts the `Addr` to a `SocketAddr`. + pub fn as_socket(&self) -> Option { + unsafe { + SockAddr::try_init(|addr, len| { + if self.ipv4.sin_family == AF_INET as sa_family_t { + let addr = addr.cast::(); + *addr = self.ipv4; + *len = mem::size_of::() as socklen_t; + Ok(()) + } else if self.ipv4.sin_family == AF_INET6 as sa_family_t { + let addr = addr.cast::(); + *addr = self.ipv6; + *len = mem::size_of::() as socklen_t; + Ok(()) + } else { + Err(io::Error::from(io::ErrorKind::Other)) + } + }) } + .map(|((), addr)| addr.as_socket().unwrap()) + .ok() } - /// Create a representation of IPv6 address and perform Network byte order conversion - /// on the port number. - pub fn ipv6( - family: u16, - port: u16, - flow_info: u32, - addr: [u8; 16usize], - scope_id: u32, - ) -> Addr { - Addr { - ipv6: sockaddr_in6 { - family, - port, - flow_info, - addr, - scope_id, - }, + /// Get port number from the `Addr`. + pub fn port(&self) -> u16 { + unsafe { u16::from_be(self.ipv4.sin_port) } + } +} + +impl From for Addr { + fn from(addr: SocketAddr) -> Addr { + match addr { + SocketAddr::V4(addr) => addr.into(), + SocketAddr::V6(addr) => addr.into(), } } } +impl From for Addr { + fn from(addr: SocketAddrV4) -> Addr { + // SAFETY: a `Addr` of all zeros is valid. + let mut storage = unsafe { mem::zeroed::() }; + let addr: SockAddr = addr.into(); + let addr = addr.as_ptr().cast::(); + storage.ipv4 = unsafe { *addr }; + storage + } +} + +impl From for Addr { + fn from(addr: SocketAddrV6) -> Addr { + // SAFETY: a `Addr` of all zeros is valid. + let mut storage = unsafe { mem::zeroed::() }; + let addr: SockAddr = addr.into(); + let addr = addr.as_ptr().cast::(); + storage.ipv6 = unsafe { *addr }; + storage + } +} + #[cfg(target_os = "windows")] mod status { pub const QUIC_STATUS_SUCCESS: u32 = 0x0; @@ -1666,6 +1676,40 @@ impl Connection { } Ok(()) } + + pub fn get_local_addr(&self) -> Result { + let mut addr_buffer: [u8; mem::size_of::()] = [0; mem::size_of::()]; + let addr_size_mut = mem::size_of::(); + let status = unsafe { + ((*self.table).get_param)( + self.handle, + PARAM_CONN_LOCAL_ADDRESS, + (&addr_size_mut) as *const usize as *const u32 as *mut u32, + addr_buffer.as_mut_ptr() as *const c_void, + ) + }; + if Status::failed(status) { + return Err(status); + } + Ok(unsafe { *(addr_buffer.as_ptr() as *const c_void as *const Addr) }) + } + + pub fn get_remote_addr(&self) -> Result { + let mut addr_buffer: [u8; mem::size_of::()] = [0; mem::size_of::()]; + let addr_size_mut = mem::size_of::(); + let status = unsafe { + ((*self.table).get_param)( + self.handle, + PARAM_CONN_REMOTE_ADDRESS, + (&addr_size_mut) as *const usize as *const u32 as *mut u32, + addr_buffer.as_mut_ptr() as *const c_void, + ) + }; + if Status::failed(status) { + return Err(status); + } + Ok(unsafe { *(addr_buffer.as_ptr() as *const c_void as *const Addr) }) + } } impl Drop for Connection { @@ -1820,7 +1864,11 @@ extern "C" fn test_conn_callback( ) -> u32 { let connection = unsafe { &*(context as *const Connection) }; match event.event_type { - CONNECTION_EVENT_CONNECTED => println!("Connected"), + CONNECTION_EVENT_CONNECTED => { + let local_addr = connection.get_local_addr().unwrap().as_socket().unwrap(); + let remote_addr = connection.get_remote_addr().unwrap().as_socket().unwrap(); + println!("Connected({}, {})", local_addr, remote_addr); + } CONNECTION_EVENT_SHUTDOWN_INITIATED_BY_TRANSPORT => { println!("Transport shutdown 0x{:x}", unsafe { event.payload.shutdown_initiated_by_transport.status From 99348663ec97b696f8e5a1449ce7d5a80a055e09 Mon Sep 17 00:00:00 2001 From: Gaurav Singh Date: Fri, 20 Dec 2024 04:00:40 +0530 Subject: [PATCH 17/29] added unique pointer for connection (#4718) --- src/test/lib/DataTest.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/test/lib/DataTest.cpp b/src/test/lib/DataTest.cpp index 52e4206919..2e4d91bdc3 100644 --- a/src/test/lib/DataTest.cpp +++ b/src/test/lib/DataTest.cpp @@ -3627,9 +3627,9 @@ void QuicTestConnectionPriority() const uint8_t NumConnections = 8; { - MsQuicConnection *Connections[NumConnections] = {0}; + UniquePtr Connections[NumConnections]; for (uint8_t i = 0; i < NumConnections; ++i) { - Connections[i] = new(std::nothrow) MsQuicConnection(Registration); + Connections[i].reset(new(std::nothrow) MsQuicConnection(Registration)); TEST_QUIC_SUCCEEDED(Connections[i]->GetInitStatus()); TEST_QUIC_SUCCEEDED(Connections[i]->Start(ClientConfiguration, ServerLocalAddr.GetFamily(), QUIC_TEST_LOOPBACK_FOR_AF(ServerLocalAddr.GetFamily()), ServerLocalAddr.GetPort())); TEST_TRUE(Connections[i]->HandshakeCompleteEvent.WaitTimeout(TestWaitTimeout)); @@ -3824,10 +3824,6 @@ void QuicTestConnectionPriority() TEST_TRUE(memcmp(Context.StartOrder, ExpectedStartOrder, sizeof(ExpectedStartOrder)) == 0); TEST_TRUE(memcmp(Context.SendOrder, ExpectedSendOrder, sizeof(ExpectedSendOrder)) == 0); } - - for (uint8_t i = 0; i < NumConnections; ++i) { - delete Connections[i]; - } } } From 0e74c3a470bd2c79b80b540fed17cf08e85a7815 Mon Sep 17 00:00:00 2001 From: Vishwanath Mahajanshetty Date: Sun, 22 Dec 2024 20:39:22 +0530 Subject: [PATCH 18/29] Changes to trigger wan perf test run manually (#4719) * Changes to trigger wan perf test run manually * Changes to trigger wan perf test run manually * Update .github/workflows/wan-perf.yml Co-authored-by: Nick Banks * Changes to trigger wan perf test run manually --------- Co-authored-by: Nick Banks --- .github/workflows/wan-perf.yml | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/wan-perf.yml b/.github/workflows/wan-perf.yml index 01872cfe64..d51e3b602b 100644 --- a/.github/workflows/wan-perf.yml +++ b/.github/workflows/wan-perf.yml @@ -1,24 +1,24 @@ name: WAN Perf on: - push: - branches: - - main - paths: - - .github/workflows/wan-perf.yml - - src/core/* - - src/platform/* - - src/perf/* - pull_request: - branches: - - main - paths: - - .github/workflows/wan-perf.yml - - src/core/* - - src/platform/* - - src/perf/* - - submodules/openssl/* - + workflow_dispatch: +# push: +# branches: +# - main +# paths: +# - .github/workflows/wan-perf.yml +# - src/core/* +# - src/platform/* +# - src/perf/* +# pull_request: +# branches: +# - main +# paths: +# - .github/workflows/wan-perf.yml +# - src/core/* +# - src/platform/* +# - src/perf/* +# - submodules/openssl/* concurrency: # Cancel any workflow currently in progress for the same PR. # Allow running concurrently with any other commits. @@ -92,11 +92,11 @@ jobs: name: bin path: artifacts/bin - name: Run WAN Perf (QUIC only) - if: ${{ github.event_name == 'pull_request' }} + if: ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }} shell: pwsh run: scripts/emulated-performance.ps1 -Debug -Protocol QUIC -LogProfile Performance.Light -NoDateLogDir -NumIterations ${{ env.iterations }} -DurationMs ${{ env.duration }} -Pacing ${{ env.pacing }} -BottleneckMbps ${{ matrix.rate }} -RttMs ${{ matrix.rtt }} -BottleneckQueueRatio ${{ matrix.queueRatio }} -RandomLossDenominator ${{ env.loss }} -RandomReorderDenominator ${{ env.reorder }} -ReorderDelayDeltaMs ${{ env.delay }} -BaseRandomSeed ${{ env.seed }} -CongestionControl ${{ env.congestionControl }} - name: Run WAN Perf (QUIC + TCP) - if: ${{ github.event_name != 'pull_request' }} + if: ${{ github.event_name != 'pull_request' && github.event_name != 'workflow_dispatch' }} shell: pwsh run: scripts/emulated-performance.ps1 -Debug -Protocol ('QUIC','TCPTLS') -LogProfile Performance.Light -NoDateLogDir -NumIterations ${{ env.iterations }} -DurationMs ${{ env.duration }} -Pacing ${{ env.pacing }} -BottleneckMbps ${{ matrix.rate }} -RttMs ${{ matrix.rtt }} -BottleneckQueueRatio ${{ matrix.queueRatio }} -RandomLossDenominator ${{ env.loss }} -RandomReorderDenominator ${{ env.reorder }} -ReorderDelayDeltaMs ${{ env.delay }} -BaseRandomSeed ${{ env.seed }} -CongestionControl ${{ env.congestionControl }} - name: Upload Results From 761dc0bf376de57134d42a6310de8c065053a145 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Dec 2024 16:42:58 -0600 Subject: [PATCH 19/29] Bump submodules/googletest from `79219e2` to `f3c355f` (#4720) Bumps [submodules/googletest](https://github.com/google/googletest) from `79219e2` to `f3c355f`. - [Release notes](https://github.com/google/googletest/releases) - [Commits](https://github.com/google/googletest/compare/79219e26e0e36b415a5804b6b017ad6c6cd99ad8...f3c355f9dd382bc2c323be2713e351a578b68c61) --- updated-dependencies: - dependency-name: submodules/googletest dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- submodules/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/googletest b/submodules/googletest index 79219e26e0..f3c355f9dd 160000 --- a/submodules/googletest +++ b/submodules/googletest @@ -1 +1 @@ -Subproject commit 79219e26e0e36b415a5804b6b017ad6c6cd99ad8 +Subproject commit f3c355f9dd382bc2c323be2713e351a578b68c61 From 2178cc43176448b1ccf4488cef5340bac71b86b9 Mon Sep 17 00:00:00 2001 From: talregev Date: Tue, 24 Dec 2024 16:54:34 +0100 Subject: [PATCH 20/29] Change ci that can run from other repos (#4703) --- .github/workflows/build-darwin-framework.yml | 1 + .github/workflows/build-reuse-darwin-framework.yml | 10 +++++++--- .github/workflows/build-reuse-unix.yml | 6 +++++- .github/workflows/build-reuse-win.yml | 6 +++++- .github/workflows/build-reuse-winkernel.yml | 6 +++++- .github/workflows/build.yml | 5 +++++ 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-darwin-framework.yml b/.github/workflows/build-darwin-framework.yml index 186ed64055..be92ab1f68 100644 --- a/.github/workflows/build-darwin-framework.yml +++ b/.github/workflows/build-darwin-framework.yml @@ -25,3 +25,4 @@ jobs: uses: ./.github/workflows/build-reuse-darwin-framework.yml with: config: 'Release' + repo: ${{ github.repository }} diff --git a/.github/workflows/build-reuse-darwin-framework.yml b/.github/workflows/build-reuse-darwin-framework.yml index 9aa7baba8e..c883a12fec 100644 --- a/.github/workflows/build-reuse-darwin-framework.yml +++ b/.github/workflows/build-reuse-darwin-framework.yml @@ -7,6 +7,10 @@ on: required: false default: '' type: string + repo: + required: false + default: microsoft/msquic + type: string config: required: false default: 'Release' @@ -55,7 +59,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - repository: microsoft/msquic + repository: ${{ inputs.repo}} ref: ${{ inputs.ref }} - name: Download Build Artifacts (x64) uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 @@ -92,7 +96,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - repository: microsoft/msquic + repository: ${{ inputs.repo}} ref: ${{ inputs.ref }} - name: Download Build Artifacts (x64) uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 @@ -116,7 +120,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - repository: microsoft/msquic + repository: ${{ inputs.repo}} ref: ${{ inputs.ref }} - name: Download Build Artifacts (iOS x64) uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 diff --git a/.github/workflows/build-reuse-unix.yml b/.github/workflows/build-reuse-unix.yml index 6bfadc0e56..518ba82bf3 100644 --- a/.github/workflows/build-reuse-unix.yml +++ b/.github/workflows/build-reuse-unix.yml @@ -9,6 +9,10 @@ on: required: false default: '' type: string + repo: + required: false + default: microsoft/msquic + type: string config: required: false default: 'Release' @@ -91,7 +95,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - repository: microsoft/msquic + repository: ${{ inputs.repo}} ref: ${{ inputs.ref }} - name: Set ownership if: inputs.plat == 'linux' diff --git a/.github/workflows/build-reuse-win.yml b/.github/workflows/build-reuse-win.yml index e13e5ef9f2..41f614cbbd 100644 --- a/.github/workflows/build-reuse-win.yml +++ b/.github/workflows/build-reuse-win.yml @@ -9,6 +9,10 @@ on: required: false default: '' type: string + repo: + required: false + default: microsoft/msquic + type: string config: required: false default: 'Release' @@ -71,7 +75,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - repository: microsoft/msquic + repository: ${{ inputs.repo}} ref: ${{ inputs.ref }} - name: Install Perl uses: shogo82148/actions-setup-perl@98dfedee230bcf1ee68d5b021931fc8d63f2016e diff --git a/.github/workflows/build-reuse-winkernel.yml b/.github/workflows/build-reuse-winkernel.yml index 0e55cba4ef..b6212bc4a2 100644 --- a/.github/workflows/build-reuse-winkernel.yml +++ b/.github/workflows/build-reuse-winkernel.yml @@ -9,6 +9,10 @@ on: required: false default: '' type: string + repo: + required: false + default: microsoft/msquic + type: string config: required: false default: 'Release' @@ -60,7 +64,7 @@ jobs: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 with: - repository: microsoft/msquic + repository: ${{ inputs.repo}} ref: ${{ inputs.ref }} - name: Prepare Machine shell: pwsh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aead751834..8d1ba58ae2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,6 +53,7 @@ jobs: arch: ${{ matrix.arch }} tls: ${{ matrix.tls }} static: ${{ matrix.static }} + repo: ${{ github.repository }} build-windows-kernel: name: WinKernel @@ -72,6 +73,7 @@ jobs: os: ${{ matrix.os }} arch: ${{ matrix.arch }} tls: ${{ matrix.tls }} + repo: ${{ github.repository }} build-ubuntu-cross-compile: name: UbuntuArm @@ -93,6 +95,7 @@ jobs: arch: ${{ matrix.arch }} tls: ${{ matrix.tls }} static: ${{ matrix.static }} + repo: ${{ github.repository }} build-ubuntu: name: Ubuntu @@ -177,6 +180,7 @@ jobs: clang: ${{ matrix.clang }} codecheck: ${{ matrix.codecheck }} xdp: ${{ matrix.xdp }} + repo: ${{ github.repository }} build-darwin: name: MacOs @@ -198,6 +202,7 @@ jobs: arch: ${{ matrix.arch }} tls: ${{ matrix.tls }} static: ${{ matrix.static }} + repo: ${{ github.repository }} build-nuget: name: Build Nuget Package From 10f248775a5e32f1c0935ab794c0fb4c3e2f9c18 Mon Sep 17 00:00:00 2001 From: talregev Date: Fri, 27 Dec 2024 20:52:43 +0200 Subject: [PATCH 21/29] Add repo var to all other ci job (#4721) Signed-off-by: Tal Regev --- .github/workflows/build-reuse-darwin-framework.yml | 1 + .github/workflows/code-coverage.yml | 1 + .github/workflows/dotnet-test.yml | 3 +++ .github/workflows/package-reuse-linux.yml | 1 + .github/workflows/stress.yml | 2 ++ .github/workflows/test.yml | 3 +++ 6 files changed, 11 insertions(+) diff --git a/.github/workflows/build-reuse-darwin-framework.yml b/.github/workflows/build-reuse-darwin-framework.yml index c883a12fec..0da51e5c93 100644 --- a/.github/workflows/build-reuse-darwin-framework.yml +++ b/.github/workflows/build-reuse-darwin-framework.yml @@ -50,6 +50,7 @@ jobs: arch: ${{ matrix.arch }} tls: ${{ inputs.tls }} static: ${{ inputs.static }} + repo: ${{ inputs.repo }} build-darwin-universal: name: Build Universal Binaries diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index 8e9fbe0844..a5f8d18e5a 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -37,6 +37,7 @@ jobs: tls: ${{ matrix.vec.tls }} sanitize: ${{ matrix.vec.sanitize }} build: ${{ matrix.vec.build }} + repo: ${{ github.repository }} bvt-winlatest: name: BVT WinPrerelease diff --git a/.github/workflows/dotnet-test.yml b/.github/workflows/dotnet-test.yml index ccfe8f3829..0737d43e34 100644 --- a/.github/workflows/dotnet-test.yml +++ b/.github/workflows/dotnet-test.yml @@ -25,6 +25,7 @@ jobs: uses: ./.github/workflows/build-reuse-darwin-framework.yml with: config: 'Debug' + repo: ${{ github.repository }} build-linux: name: Ubuntu @@ -45,6 +46,7 @@ jobs: arch: ${{ matrix.vec.arch }} tls: ${{ matrix.vec.tls }} xdp: ${{ matrix.vec.xdp }} + repo: ${{ github.repository }} build-windows: name: Windows @@ -63,6 +65,7 @@ jobs: os: ${{ matrix.vec.os }} arch: ${{ matrix.vec.arch }} tls: ${{ matrix.vec.tls }} + repo: ${{ github.repository }} dotnet-test: name: DotNet Test diff --git a/.github/workflows/package-reuse-linux.yml b/.github/workflows/package-reuse-linux.yml index 354a940a1f..893f621824 100644 --- a/.github/workflows/package-reuse-linux.yml +++ b/.github/workflows/package-reuse-linux.yml @@ -75,6 +75,7 @@ jobs: clang: ${{ inputs.clang }} build: ${{ inputs.build }} xdp: ${{ inputs.xdp }} + repo: ${{ github.repository }} package: name: Package diff --git a/.github/workflows/stress.yml b/.github/workflows/stress.yml index 8e1d22f828..3e850df271 100644 --- a/.github/workflows/stress.yml +++ b/.github/workflows/stress.yml @@ -40,6 +40,7 @@ jobs: tls: ${{ matrix.vec.tls }} sanitize: ${{ matrix.vec.sanitize }} build: ${{ matrix.vec.build }} + repo: ${{ github.repository }} build-unix: name: Build Unix @@ -66,6 +67,7 @@ jobs: sanitize: ${{ matrix.vec.sanitize }} build: ${{ matrix.vec.build }} xdp: ${{ matrix.vec.xdp }} + repo: ${{ github.repository }} stress: name: Stress diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8f363ddab1..df74a07281 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,6 +43,7 @@ jobs: tls: ${{ matrix.vec.tls }} build: ${{ matrix.vec.build }} ref: ${{ inputs.ref || '' }} + repo: ${{ github.repository }} build-windows: name: Build WinUser @@ -66,6 +67,7 @@ jobs: sanitize: ${{ matrix.vec.sanitize }} build: ${{ matrix.vec.build }} ref: ${{ inputs.ref || '' }} + repo: ${{ github.repository }} build-unix: name: Build Unix @@ -94,6 +96,7 @@ jobs: build: ${{ matrix.vec.build }} xdp: ${{ matrix.vec.xdp }} ref: ${{ inputs.ref || '' }} + repo: ${{ github.repository }} bvt: name: BVT From 3ad4ba7146b674251fedc70585254f7baabb91b2 Mon Sep 17 00:00:00 2001 From: Masahiro Kozuka Date: Tue, 31 Dec 2024 22:57:20 +0900 Subject: [PATCH 22/29] Use global API table instead of each handle's having table ptr (#4708) --- Cargo.toml | 1 + src/lib.rs | 199 ++++++++++++++++++++++++++++------------------------- 2 files changed, 108 insertions(+), 92 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e940c6f816..031eea7812 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,4 +56,5 @@ bitfield = "0.17.0" libc = "0.2.0" c-types = "4.0.0" serde = { version = "1.0.117", features = ["derive"] } +ctor = "0.2.9" socket2 = "0.5.8" diff --git a/src/lib.rs b/src/lib.rs index f695ca8387..34a1b1cc76 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,11 +14,13 @@ use socket2::SockAddr; use std::convert::TryInto; use std::fmt; use std::io; +use std::marker::PhantomData; use std::mem; use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::option::Option; use std::ptr; use std::result::Result; +use std::sync::Once; #[macro_use] extern crate bitfield; @@ -1245,42 +1247,39 @@ extern "C" { // The following starts the "nice" Rust API wrapper on the C interop layer. // -/// Top level entry point for the MsQuic API. -/// -/// Developper must ensure a struct containing MsQuic members such as `Connection` -/// or `Stream` declares `API` last so that the API is dropped last when the containing -/// sruct goes out of scope. +// +// APITABLE will be initialized via MsQuicOpenVersion() when we first initialize Api or Registration. +// +static mut APITABLE: *const ApiTable = ptr::null(); +static START_MSQUIC: Once = Once::new(); + +/// Entry point for some global MsQuic APIs. pub struct Api { - table: *const ApiTable, + marker: PhantomData<()>, } /// The execution context for processing connections on the application's behalf. pub struct Registration { - table: *const ApiTable, handle: Handle, } /// Specifies how to configure a connection. pub struct Configuration { - table: *const ApiTable, handle: Handle, } /// A single QUIC connection. pub struct Connection { - table: *const ApiTable, handle: Handle, } /// A single server listener pub struct Listener { - table: *const ApiTable, handle: Handle, } /// A single QUIC stream on a parent connection. pub struct Stream { - table: *const ApiTable, handle: Handle, } @@ -1369,29 +1368,43 @@ impl CredentialConfig { } } +impl Default for Api { + fn default() -> Self { + Self::new() + } +} + impl Api { - pub fn new() -> Result { - let new_table: *const ApiTable = ptr::null(); - let status = unsafe { MsQuicOpenVersion(2, &new_table) }; - if Status::failed(status) { - return Err(status); + pub fn new() -> Self { + // We initialize APITABLE at only once. + unsafe { + START_MSQUIC.call_once(|| { + let table: *const ApiTable = ptr::null(); + let status = MsQuicOpenVersion(2, &table); + if Status::failed(status) { + panic!("Failed to open MsQuic: {}", status); + } + APITABLE = table; + }); + } + Self { + marker: PhantomData, } - Ok(Api { table: new_table }) } pub fn close_listener(&self, listener: Handle) { unsafe { - ((*self.table).listener_close)(listener); + ((*APITABLE).listener_close)(listener); } } pub fn close_connection(&self, connection: Handle) { unsafe { - ((*self.table).connection_close)(connection); + ((*APITABLE).connection_close)(connection); } } pub fn close_stream(&self, stream: Handle) { unsafe { - ((*self.table).stream_close)(stream); + ((*APITABLE).stream_close)(stream); } } @@ -1401,7 +1414,7 @@ impl Api { }; let perf_length = std::mem::size_of::<[i64; PERF_COUNTER_MAX as usize]>() as u32; unsafe { - ((*self.table).get_param)( + ((*APITABLE).get_param)( std::ptr::null(), PARAM_GLOBAL_PERF_COUNTERS, (&perf_length) as *const u32 as *mut u32, @@ -1417,37 +1430,51 @@ impl Api { handler: *const c_void, context: *const c_void, ) { - unsafe { ((*self.table).set_callback_handler)(handle, handler, context) } + unsafe { ((*APITABLE).set_callback_handler)(handle, handler, context) } } } -impl Drop for Api { - fn drop(&mut self) { - unsafe { MsQuicClose(self.table) }; +#[ctor::dtor] +fn close_msquic() { + unsafe { + if !APITABLE.is_null() { + MsQuicClose(APITABLE); + APITABLE = ptr::null(); + } } } impl Registration { - pub fn new(api: &Api, config: *const RegistrationConfig) -> Result { + pub fn new(config: *const RegistrationConfig) -> Result { + // We initialize APITABLE at only once. + unsafe { + START_MSQUIC.call_once(|| { + let table: *const ApiTable = ptr::null(); + let status = MsQuicOpenVersion(2, &table); + if Status::failed(status) { + panic!("Failed to open MsQuic: {}", status); + } + APITABLE = table; + }); + } let new_registration: Handle = ptr::null(); - let status = unsafe { ((*api.table).registration_open)(config, &new_registration) }; + let status = unsafe { ((*APITABLE).registration_open)(config, &new_registration) }; if Status::failed(status) { return Err(status); } Ok(Registration { - table: api.table, handle: new_registration, }) } pub fn shutdown(&self) { - unsafe { ((*self.table).registration_shutdown)(self.handle) } + unsafe { ((*APITABLE).registration_shutdown)(self.handle) } } } impl Drop for Registration { fn drop(&mut self) { - unsafe { ((*self.table).registration_close)(self.handle) }; + unsafe { ((*APITABLE).registration_close)(self.handle) }; } } @@ -1464,7 +1491,7 @@ impl Configuration { settings_size = ::std::mem::size_of::() as u32; } let status = unsafe { - ((*registration.table).configuration_open)( + ((*APITABLE).configuration_open)( registration.handle, alpn.as_ptr(), alpn.len() as u32, @@ -1478,14 +1505,13 @@ impl Configuration { return Err(status); } Ok(Configuration { - table: registration.table, handle: new_configuration, }) } pub fn load_credential(&self, cred_config: &CredentialConfig) -> Result<(), u32> { let status = - unsafe { ((*self.table).configuration_load_credential)(self.handle, cred_config) }; + unsafe { ((*APITABLE).configuration_load_credential)(self.handle, cred_config) }; if Status::failed(status) { return Err(status); } @@ -1495,23 +1521,25 @@ impl Configuration { impl Drop for Configuration { fn drop(&mut self) { - unsafe { ((*self.table).configuration_close)(self.handle) }; + unsafe { ((*APITABLE).configuration_close)(self.handle) }; + } +} + +impl Default for Connection { + fn default() -> Self { + Self::new() } } impl Connection { - pub fn new(registration: &Registration) -> Connection { + pub fn new() -> Connection { Connection { - table: registration.table, handle: ptr::null(), } } - pub fn from_parts(handle: Handle, api: &Api) -> Connection { - Connection { - table: api.table, - handle, - } + pub fn from_parts(handle: Handle) -> Connection { + Connection { handle } } pub fn open( @@ -1521,7 +1549,7 @@ impl Connection { context: *const c_void, ) -> Result<(), u32> { let status = unsafe { - ((*self.table).connection_open)(registration.handle, handler, context, &self.handle) + ((*APITABLE).connection_open)(registration.handle, handler, context, &self.handle) }; if Status::failed(status) { return Err(status); @@ -1537,7 +1565,7 @@ impl Connection { ) -> Result<(), u32> { let server_name_safe = std::ffi::CString::new(server_name).unwrap(); let status = unsafe { - ((*self.table).connection_start)( + ((*APITABLE).connection_start)( self.handle, configuration.handle, 0, @@ -1553,23 +1581,23 @@ impl Connection { pub fn close(&self) { unsafe { - ((*self.table).connection_close)(self.handle); + ((*APITABLE).connection_close)(self.handle); } } pub fn shutdown(&self, flags: ConnectionShutdownFlags, error_code: u62) { unsafe { - ((*self.table).connection_shutdown)(self.handle, flags, error_code); + ((*APITABLE).connection_shutdown)(self.handle, flags, error_code); } } pub fn set_param(&self, param: u32, buffer_length: u32, buffer: *const c_void) -> u32 { - unsafe { ((*self.table).set_param)(self.handle, param, buffer_length, buffer) } + unsafe { ((*APITABLE).set_param)(self.handle, param, buffer_length, buffer) } } pub fn stream_close(&self, stream: Handle) { unsafe { - ((*self.table).stream_close)(stream); + ((*APITABLE).stream_close)(stream); } } @@ -1578,7 +1606,7 @@ impl Connection { [0; std::mem::size_of::()]; let stat_size_mut = std::mem::size_of::(); unsafe { - ((*self.table).get_param)( + ((*APITABLE).get_param)( self.handle, PARAM_CONN_STATISTICS, (&stat_size_mut) as *const usize as *const u32 as *mut u32, @@ -1594,7 +1622,7 @@ impl Connection { [0; std::mem::size_of::()]; let stat_size_mut = std::mem::size_of::(); unsafe { - ((*self.table).get_param)( + ((*APITABLE).get_param)( self.handle, PARAM_CONN_STATISTICS_V2, (&stat_size_mut) as *const usize as *const u32 as *mut u32, @@ -1607,7 +1635,7 @@ impl Connection { pub fn set_configuration(&self, configuration: &Configuration) -> Result<(), u32> { let status = unsafe { - ((*self.table).connection_set_configuration)(self.handle, configuration.handle) + ((*APITABLE).connection_set_configuration)(self.handle, configuration.handle) }; if Status::failed(status) { return Err(status); @@ -1617,7 +1645,7 @@ impl Connection { pub fn set_callback_handler(&self, handler: ConnectionEventHandler, context: *const c_void) { unsafe { - ((*self.table).set_callback_handler)(self.handle, handler as *const c_void, context) + ((*APITABLE).set_callback_handler)(self.handle, handler as *const c_void, context) }; } @@ -1628,7 +1656,7 @@ impl Connection { context: *const c_void, ) { unsafe { - ((*self.table).set_callback_handler)(stream_handle, handler as *const c_void, context) + ((*APITABLE).set_callback_handler)(stream_handle, handler as *const c_void, context) }; } @@ -1640,7 +1668,7 @@ impl Connection { client_send_context: *const c_void, ) -> Result<(), u32> { let status = unsafe { - ((*self.table).datagram_send)( + ((*APITABLE).datagram_send)( self.handle, buffer, buffer_count, @@ -1656,7 +1684,7 @@ impl Connection { pub fn resumption_ticket_validation_complete(&self, result: BOOLEAN) -> Result<(), u32> { let status = - unsafe { ((*self.table).resumption_ticket_validation_complete)(self.handle, result) }; + unsafe { ((*APITABLE).resumption_ticket_validation_complete)(self.handle, result) }; if Status::failed(status) { return Err(status); } @@ -1669,7 +1697,7 @@ impl Connection { tls_alert: TlsAlertCode, ) -> Result<(), u32> { let status = unsafe { - ((*self.table).certificate_validation_complete)(self.handle, result, tls_alert) + ((*APITABLE).certificate_validation_complete)(self.handle, result, tls_alert) }; if Status::failed(status) { return Err(status); @@ -1681,7 +1709,7 @@ impl Connection { let mut addr_buffer: [u8; mem::size_of::()] = [0; mem::size_of::()]; let addr_size_mut = mem::size_of::(); let status = unsafe { - ((*self.table).get_param)( + ((*APITABLE).get_param)( self.handle, PARAM_CONN_LOCAL_ADDRESS, (&addr_size_mut) as *const usize as *const u32 as *mut u32, @@ -1698,7 +1726,7 @@ impl Connection { let mut addr_buffer: [u8; mem::size_of::()] = [0; mem::size_of::()]; let addr_size_mut = mem::size_of::(); let status = unsafe { - ((*self.table).get_param)( + ((*APITABLE).get_param)( self.handle, PARAM_CONN_REMOTE_ADDRESS, (&addr_size_mut) as *const usize as *const u32 as *mut u32, @@ -1714,7 +1742,7 @@ impl Connection { impl Drop for Connection { fn drop(&mut self) { - unsafe { ((*self.table).connection_close)(self.handle) }; + unsafe { ((*APITABLE).connection_close)(self.handle) }; } } @@ -1726,26 +1754,20 @@ impl Listener { ) -> Result { let new_listener: Handle = ptr::null(); let status = unsafe { - ((*registration.table).listener_open)( - registration.handle, - handler, - context, - &new_listener, - ) + ((*APITABLE).listener_open)(registration.handle, handler, context, &new_listener) }; if Status::failed(status) { return Err(status); } Ok(Listener { - table: registration.table, handle: new_listener, }) } pub fn start(&self, alpn: &[Buffer], local_address: &Addr) -> Result<(), u32> { let status = unsafe { - ((*self.table).listener_start)( + ((*APITABLE).listener_start)( self.handle, alpn.as_ptr(), alpn.len() as u32, @@ -1760,31 +1782,32 @@ impl Listener { pub fn close(&self) { unsafe { - ((*self.table).listener_close)(self.handle); + ((*APITABLE).listener_close)(self.handle); } } } impl Drop for Listener { fn drop(&mut self) { - unsafe { ((*self.table).listener_close)(self.handle) }; + unsafe { ((*APITABLE).listener_close)(self.handle) }; + } +} + +impl Default for Stream { + fn default() -> Self { + Self::new() } } impl Stream { - pub fn new(context: *const c_void) -> Stream { - let api = unsafe { &*(context as *const Api) }; + pub fn new() -> Stream { Stream { - table: api.table, handle: ptr::null(), } } - pub fn from_parts(handle: Handle, api: &Api) -> Stream { - Stream { - table: api.table, - handle, - } + pub fn from_parts(handle: Handle) -> Stream { + Stream { handle } } pub fn open( @@ -1795,7 +1818,7 @@ impl Stream { context: *const c_void, ) -> Result<(), u32> { let status = unsafe { - ((*self.table).stream_open)(connection.handle, flags, handler, context, &self.handle) + ((*APITABLE).stream_open)(connection.handle, flags, handler, context, &self.handle) }; if Status::failed(status) { return Err(status); @@ -1804,7 +1827,7 @@ impl Stream { } pub fn start(&self, flags: StreamStartFlags) -> Result<(), u32> { - let status = unsafe { ((*self.table).stream_start)(self.handle, flags) }; + let status = unsafe { ((*APITABLE).stream_start)(self.handle, flags) }; if Status::failed(status) { return Err(status); } @@ -1813,7 +1836,7 @@ impl Stream { pub fn close(&self) { unsafe { - ((*self.table).stream_close)(self.handle); + ((*APITABLE).stream_close)(self.handle); } } @@ -1825,7 +1848,7 @@ impl Stream { client_send_context: *const c_void, ) -> Result<(), u32> { let status = unsafe { - ((*self.table).stream_send)( + ((*APITABLE).stream_send)( self.handle, buffer, buffer_count, @@ -1841,14 +1864,14 @@ impl Stream { pub fn set_callback_handler(&self, handler: StreamEventHandler, context: *const c_void) { unsafe { - ((*self.table).set_callback_handler)(self.handle, handler as *const c_void, context) + ((*APITABLE).set_callback_handler)(self.handle, handler as *const c_void, context) }; } } impl Drop for Stream { fn drop(&mut self) { - unsafe { ((*self.table).stream_close)(self.handle) }; + unsafe { ((*APITABLE).stream_close)(self.handle) }; } } @@ -1923,15 +1946,7 @@ extern "C" fn test_stream_callback( #[test] fn test_module() { - let res = Api::new(); - assert!( - res.is_ok(), - "Failed to open API: 0x{:x}", - res.err().unwrap() - ); - let api = res.unwrap(); - - let res = Registration::new(&api, ptr::null()); + let res = Registration::new(ptr::null()); assert!( res.is_ok(), "Failed to open registration: 0x{:x}", @@ -1962,7 +1977,7 @@ fn test_module() { res.err().unwrap() ); - let connection = Connection::new(®istration); + let connection = Connection::new(); let res = connection.open( ®istration, test_conn_callback, From 114e2cfe3afed114b9efd4a4618309d02aeb20e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 09:00:23 -0500 Subject: [PATCH 23/29] Bump submodules/googletest from `f3c355f` to `7d76a23` (#4722) Bumps [submodules/googletest](https://github.com/google/googletest) from `f3c355f` to `7d76a23`. - [Release notes](https://github.com/google/googletest/releases) - [Commits](https://github.com/google/googletest/compare/f3c355f9dd382bc2c323be2713e351a578b68c61...7d76a231b0e29caf86e68d1df858308cd53b2a66) --- updated-dependencies: - dependency-name: submodules/googletest dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- submodules/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/googletest b/submodules/googletest index f3c355f9dd..7d76a231b0 160000 --- a/submodules/googletest +++ b/submodules/googletest @@ -1 +1 @@ -Subproject commit f3c355f9dd382bc2c323be2713e351a578b68c61 +Subproject commit 7d76a231b0e29caf86e68d1df858308cd53b2a66 From e909d8a74b4cf6dd953cdf77667690f7a61b9a4d Mon Sep 17 00:00:00 2001 From: Kai Pastor Date: Tue, 31 Dec 2024 15:08:29 +0100 Subject: [PATCH 24/29] Simplify cmake config chainloading (#4727) * CMake: Remove stray config file * Simplify cmake config chainloading --- CMakeLists.txt | 3 --- src/bin/CMakeLists.txt | 2 +- src/bin/msquic-config-unix.cmake.in | 5 ----- src/bin/msquic-config.cmake.in | 3 +-- 4 files changed, 2 insertions(+), 11 deletions(-) delete mode 100644 src/bin/msquic-config-unix.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 718247224d..a32b057c25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,9 +67,6 @@ elseif (UNIX) endif() message(STATUS "QUIC Platform: ${CX_PLATFORM}") -set(FILENAME_DEP_REPLACE "get_filename_component(SELF_DIR \"$\{CMAKE_CURRENT_LIST_FILE\}\" PATH)") -set(SELF_DIR "$\{SELF_DIR\}") - enable_testing() # Set the default TLS method for each platform. diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt index 6b84d4555c..352536f946 100644 --- a/src/bin/CMakeLists.txt +++ b/src/bin/CMakeLists.txt @@ -269,7 +269,7 @@ else() endif() install(FILES ${PUBLIC_HEADERS} DESTINATION include) -configure_file(msquic-config.cmake.in ${CMAKE_BINARY_DIR}/msquic-config.cmake) +configure_file(msquic-config.cmake.in ${CMAKE_BINARY_DIR}/msquic-config.cmake @ONLY) install(FILES ${CMAKE_BINARY_DIR}/msquic-config.cmake DESTINATION share/msquic) diff --git a/src/bin/msquic-config-unix.cmake.in b/src/bin/msquic-config-unix.cmake.in deleted file mode 100644 index 9292018b12..0000000000 --- a/src/bin/msquic-config-unix.cmake.in +++ /dev/null @@ -1,5 +0,0 @@ -include(CMakeFindDependencyMacro) -@FILENAME_DEP_REPLACE@ - -include(${SELF_DIR}/msquic.cmake) -include(${SELF_DIR}/msquictraceprovider.cmake) diff --git a/src/bin/msquic-config.cmake.in b/src/bin/msquic-config.cmake.in index fba676be99..e61e63feab 100644 --- a/src/bin/msquic-config.cmake.in +++ b/src/bin/msquic-config.cmake.in @@ -1,7 +1,6 @@ include(CMakeFindDependencyMacro) -@FILENAME_DEP_REPLACE@ -include(${SELF_DIR}/msquic.cmake) +include("${CMAKE_CURRENT_LIST_DIR}/msquic.cmake") foreach(_t IN ITEMS msquic msquic_platform) if(TARGET msquic::${_t} AND NOT TARGET ${_t}) From b6ebb83cee48a414d611002dd2b152e7faa89075 Mon Sep 17 00:00:00 2001 From: Kai Pastor Date: Tue, 31 Dec 2024 15:25:00 +0100 Subject: [PATCH 25/29] Export msquic include install dir (#4725) --- src/bin/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt index 352536f946..e69cf51ac5 100644 --- a/src/bin/CMakeLists.txt +++ b/src/bin/CMakeLists.txt @@ -11,6 +11,7 @@ endif() if(BUILD_SHARED_LIBS) add_library(msquic SHARED ${SOURCES}) + target_include_directories(msquic PUBLIC $) target_link_libraries(msquic PRIVATE core msquic_platform inc warnings logging base_link main_binary_link_args) set_target_properties(msquic PROPERTIES OUTPUT_NAME ${QUIC_LIBRARY_NAME}) if (NOT WIN32) From 526944cd7c325dd94f55fab7e033822e13213f2a Mon Sep 17 00:00:00 2001 From: Masahiro Kozuka Date: Wed, 1 Jan 2025 22:27:12 +0900 Subject: [PATCH 26/29] Add missing listener, connection, and stream event structures (#4731) --- src/lib.rs | 140 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 18 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 34a1b1cc76..e65464bbdf 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -910,19 +910,35 @@ pub const PARAM_STREAM_PRIORITY: u32 = 0x08000003; pub type ListenerEventType = u32; pub const LISTENER_EVENT_NEW_CONNECTION: ListenerEventType = 0; +pub const LISTENER_EVENT_STOP_COMPLETE: ListenerEventType = 1; #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ListenerEventNewConnection { pub info: *const NewConnectionInfo, pub connection: Handle, - pub new_negotiated_alpn: *const u8, +} + +bitfield! { + #[repr(C)] + #[derive(Debug, Clone, Copy)] + pub struct ListenerEventStopCompleteBitfields(u8); + // The fields default to u8 + pub app_close_in_progress, _: 0, 0; + _reserved, _: 7, 1; +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ListenerEventStopComplete { + pub bit_flags: ListenerEventStopCompleteBitfields, } #[repr(C)] #[derive(Copy, Clone)] pub union ListenerEventPayload { pub new_connection: ListenerEventNewConnection, + pub stop_complete: ListenerEventStopComplete, } #[repr(C)] @@ -974,10 +990,33 @@ pub struct ConnectionEventConnectionShutdownByPeer { pub error_code: u62, } +bitfield! { + #[repr(C)] + #[derive(Debug, Clone, Copy)] + pub struct ConnectionEventShutdownCompleteBitfields(BOOLEAN); + // The fields default to BOOLEAN + pub handshake_completed, _: 0, 0; + pub peer_acknowledged_shutdown, _: 1, 1; + pub app_close_in_progress, _: 2, 2; + _reserved, _: 7, 3; +} + #[repr(C, packed)] #[derive(Debug, Copy, Clone)] pub struct ConnectionEventShutdownComplete { - pub _bitfield: BOOLEAN, + pub bit_flags: ConnectionEventShutdownCompleteBitfields, +} + +#[repr(C, packed)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventLocalAddressChanged { + pub address: *const Addr, +} + +#[repr(C, packed)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventPeerAddressChanged { + pub address: *const Addr, } #[repr(C)] @@ -987,6 +1026,33 @@ pub struct ConnectionEventPeerStreamStarted { pub flags: StreamOpenFlags, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventStreamsAvailable { + pub bidirectional_count: u16, + pub unidirectional_count: u16, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventPeerNeedsStreams { + pub bidirectional: BOOLEAN, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventIdealProcessorChanged { + pub ideal_processor: u16, + pub partition_index: u16, +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventDatagramStateChanged { + pub send_enabled: BOOLEAN, + pub max_send_length: u16, +} + #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ConnectionEventDatagramReceived { @@ -1001,6 +1067,13 @@ pub struct ConnectionEventDatagramSendStateChanged { pub state: DatagramSendState, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventResumed { + pub resumption_state_length: u16, + pub resumption_state: *const u8, +} + #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ConnectionEventResumptionTicketReceived { @@ -1008,6 +1081,15 @@ pub struct ConnectionEventResumptionTicketReceived { pub resumption_ticket: *const u8, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ConnectionEventPeerCertificateReceived { + pub certificate: *const Certificate, + pub deferred_error_flags: u32, + pub deferred_status: u32, + pub chain: *const CertificateChain, +} + #[repr(C)] #[derive(Copy, Clone)] pub union ConnectionEventPayload { @@ -1015,17 +1097,18 @@ pub union ConnectionEventPayload { pub shutdown_initiated_by_transport: ConnectionEventConnectionShutdownByTransport, pub shutdown_initiated_by_peer: ConnectionEventConnectionShutdownByPeer, pub shutdown_complete: ConnectionEventShutdownComplete, - //pub local_address_changed: ConnectionEventLocalAddressChanged, - //pub peer_address_changed: ConnectionEventPeerAddressChanged, + pub local_address_changed: ConnectionEventLocalAddressChanged, + pub peer_address_changed: ConnectionEventPeerAddressChanged, pub peer_stream_started: ConnectionEventPeerStreamStarted, - //pub streams_available: ConnectionEventStreamsAvailable, - //pub ideal_processor_changed: ConnectionEventIdealProcessorChanged, - //pub datagram_state_changed: ConnectionEventDatagramStateChanged, + pub streams_available: ConnectionEventStreamsAvailable, + pub peer_needs_streams: ConnectionEventPeerNeedsStreams, + pub ideal_processor_changed: ConnectionEventIdealProcessorChanged, + pub datagram_state_changed: ConnectionEventDatagramStateChanged, pub datagram_received: ConnectionEventDatagramReceived, pub datagram_send_state_changed: ConnectionEventDatagramSendStateChanged, - //pub resumed: ConnectionEventResumed, + pub resumed: ConnectionEventResumed, pub resumption_ticket_received: ConnectionEventResumptionTicketReceived, - //pub peer_certificated_received: ConnectionEventPeerCertificateReceived, + pub peer_certificated_received: ConnectionEventPeerCertificateReceived, } #[repr(C)] @@ -1049,13 +1132,23 @@ pub const STREAM_EVENT_SEND_SHUTDOWN_COMPLETE: StreamEventType = 6; pub const STREAM_EVENT_SHUTDOWN_COMPLETE: StreamEventType = 7; pub const STREAM_EVENT_IDEAL_SEND_BUFFER_SIZE: StreamEventType = 8; pub const STREAM_EVENT_PEER_ACCEPTED: StreamEventType = 9; +pub const STREAM_EVENT_CANCEL_ON_LOSS: StreamEventType = 10; + +bitfield! { + #[repr(C)] + #[derive(Debug, Clone, Copy)] + pub struct StreamEventStartCompleteBitfields(u8); + // The fields default to u8 + pub peer_accepted, _: 0, 0; + _reserved, _: 7, 1; +} #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct StreamEventStartComplete { - pub status: u64, + pub status: u32, pub id: u62, - pub bit_flags: u8, + pub bit_flags: StreamEventStartCompleteBitfields, } #[repr(C)] @@ -1078,13 +1171,13 @@ pub struct StreamEventSendComplete { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct StreamEventPeerSendAborted { - pub error_code: u64, + pub error_code: u62, } #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct StreamEventPeerReceiveAborted { - pub error_code: u64, + pub error_code: u62, } #[repr(C)] @@ -1096,17 +1189,21 @@ pub struct StreamEventSendShutdownComplete { bitfield! { #[repr(C)] #[derive(Clone, Copy)] - struct StreamEventShutdownCompleteBitfields(u8); + pub struct StreamEventShutdownCompleteBitfields(u8); // The fields default to u8 - app_close_in_progress, _: 1, 0; - _reserved, _: 7, 1; + pub app_close_in_progress, _: 0, 0; + pub conn_shutdown_by_app, _: 1, 1; + pub conn_closed_remotely, _: 2, 2; + _reserved, _: 7, 3; } #[repr(C)] #[derive(Copy, Clone)] pub struct StreamEventShutdownComplete { - connection_shutdown: bool, - flags: StreamEventShutdownCompleteBitfields, + pub connection_shutdown: bool, + pub bit_flags: StreamEventShutdownCompleteBitfields, + pub connection_error_code: u62, + pub connection_close_status: u32, } #[repr(C)] @@ -1115,6 +1212,12 @@ pub struct StreamEventIdealSendBufferSize { pub byte_count: u64, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct StreamEventCancelOnLoss { + pub error_code: u62, +} + #[repr(C)] #[derive(Copy, Clone)] pub union StreamEventPayload { @@ -1126,6 +1229,7 @@ pub union StreamEventPayload { pub send_shutdown_complete: StreamEventSendShutdownComplete, pub shutdown_complete: StreamEventShutdownComplete, pub ideal_send_buffer_size: StreamEventIdealSendBufferSize, + pub cancel_on_loss: StreamEventCancelOnLoss, } #[repr(C)] From f16a46b02e7798e5d01211995839cf1ee3e71456 Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Wed, 1 Jan 2025 18:15:23 -0600 Subject: [PATCH 27/29] Fix Path Classifiers in CodeQL YML (#4733) --- .CodeQL.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.CodeQL.yml b/.CodeQL.yml index 1455700093..1ccd4b8022 100644 --- a/.CodeQL.yml +++ b/.CodeQL.yml @@ -2,13 +2,14 @@ # https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/codeql/troubleshooting/bugs/generated-library-code # (Access restricted to Microsoft employees only.) -# The following paths are explicitly classified which indicates they should no +# The following paths are explicitly classified which indicates they should not # be analyzed by CodeQL and generate alerts. path_classifiers: docs: - docs generated: + - build - src/cs - src/generated submodules: - - subodules + - submodules From 38469af1328ffe88d8455679d942bbc97eafbc58 Mon Sep 17 00:00:00 2001 From: Masahiro Kozuka Date: Thu, 2 Jan 2025 21:26:11 +0900 Subject: [PATCH 28/29] Add preview API feature (#4730) --- Cargo.toml | 1 + src/lib.rs | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 031eea7812..ad41247b71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ include = [ [features] default = [] static = [] +preview-api = [] [build-dependencies] cmake = "0.1" diff --git a/src/lib.rs b/src/lib.rs index e65464bbdf..beb5cea64b 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -826,6 +826,7 @@ pub struct Settings { pub mtu_operations_per_drain: u8, pub mtu_discovery_missing_probe_count: u8, pub dest_cid_update_idle_timeout_ms: u32, + pub other2_flags: u64, } pub const PARAM_GLOBAL_RETRY_MEMORY_PERCENT: u32 = 0x01000000; @@ -1454,6 +1455,12 @@ impl Settings { self.other_flags |= (value as u8) << 3; self } + #[cfg(feature = "preview-api")] + pub fn set_stream_multi_receive_enabled(&mut self, value: bool) -> &mut Settings { + self.is_set_flags |= 1 << 42; + self.other2_flags |= (value as u64) << 5; + self + } } impl CredentialConfig { @@ -2062,6 +2069,12 @@ fn test_module() { let res = Configuration::new( ®istration, &alpn, + #[cfg(feature = "preview-api")] + Settings::new() + .set_peer_bidi_stream_count(100) + .set_peer_unidi_stream_count(3) + .set_stream_multi_receive_enabled(true), + #[cfg(not(feature = "preview-api"))] Settings::new() .set_peer_bidi_stream_count(100) .set_peer_unidi_stream_count(3), From 453fb178725efb45b11e7274dd8d5dfbc7dce7a1 Mon Sep 17 00:00:00 2001 From: Masahiro Kozuka Date: Thu, 2 Jan 2025 22:10:20 +0900 Subject: [PATCH 29/29] Refactor lib.rs (#4729) * Implement default for Listener and enhance its methods for better functionality * Add shutdown and parameter retrieval methods to Stream; clean up Listener methods * Implement Sync and Send traits for QUIC structures --- src/lib.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index beb5cea64b..9a5e00b1d3 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -1367,26 +1367,36 @@ pub struct Api { pub struct Registration { handle: Handle, } +unsafe impl Sync for Registration {} +unsafe impl Send for Registration {} /// Specifies how to configure a connection. pub struct Configuration { handle: Handle, } +unsafe impl Sync for Configuration {} +unsafe impl Send for Configuration {} /// A single QUIC connection. pub struct Connection { handle: Handle, } +unsafe impl Sync for Connection {} +unsafe impl Send for Connection {} /// A single server listener pub struct Listener { handle: Handle, } +unsafe impl Sync for Listener {} +unsafe impl Send for Listener {} /// A single QUIC stream on a parent connection. pub struct Stream { handle: Handle, } +unsafe impl Sync for Stream {} +unsafe impl Send for Stream {} impl From<&str> for Buffer { fn from(data: &str) -> Buffer { @@ -1857,32 +1867,43 @@ impl Drop for Connection { } } +impl Default for Listener { + fn default() -> Self { + Self::new() + } +} + impl Listener { - pub fn new( + pub fn new() -> Listener { + Listener { + handle: ptr::null(), + } + } + + pub fn open( + &self, registration: &Registration, handler: ListenerEventHandler, context: *const c_void, - ) -> Result { - let new_listener: Handle = ptr::null(); + ) -> Result<(), u32> { let status = unsafe { - ((*APITABLE).listener_open)(registration.handle, handler, context, &new_listener) + ((*APITABLE).listener_open)(registration.handle, handler, context, &self.handle) }; if Status::failed(status) { return Err(status); } - - Ok(Listener { - handle: new_listener, - }) + Ok(()) } - pub fn start(&self, alpn: &[Buffer], local_address: &Addr) -> Result<(), u32> { + pub fn start(&self, alpn: &[Buffer], local_address: Option<&Addr>) -> Result<(), u32> { let status = unsafe { ((*APITABLE).listener_start)( self.handle, alpn.as_ptr(), alpn.len() as u32, - local_address, + local_address + .map(|addr| addr as *const _) + .unwrap_or(ptr::null()), ) }; if Status::failed(status) { @@ -1891,6 +1912,29 @@ impl Listener { Ok(()) } + pub fn stop(&self) { + unsafe { + ((*APITABLE).listener_stop)(self.handle); + } + } + + pub fn get_local_addr(&self) -> Result { + let mut addr_buffer: [u8; mem::size_of::()] = [0; mem::size_of::()]; + let addr_size_mut = mem::size_of::(); + let status = unsafe { + ((*APITABLE).get_param)( + self.handle, + PARAM_LISTENER_LOCAL_ADDRESS, + (&addr_size_mut) as *const usize as *const u32 as *mut u32, + addr_buffer.as_mut_ptr() as *const c_void, + ) + }; + if Status::failed(status) { + return Err(status); + } + Ok(unsafe { *(addr_buffer.as_ptr() as *const c_void as *const Addr) }) + } + pub fn close(&self) { unsafe { ((*APITABLE).listener_close)(self.handle); @@ -1945,6 +1989,14 @@ impl Stream { Ok(()) } + pub fn shutdown(&self, flags: StreamShutdownFlags, error_code: u62) -> Result<(), u32> { + let status = unsafe { ((*APITABLE).stream_shutdown)(self.handle, flags, error_code) }; + if Status::failed(status) { + return Err(status); + } + Ok(()) + } + pub fn close(&self) { unsafe { ((*APITABLE).stream_close)(self.handle); @@ -1978,6 +2030,27 @@ impl Stream { ((*APITABLE).set_callback_handler)(self.handle, handler as *const c_void, context) }; } + + pub fn get_param( + &self, + param: u32, + buffer_length: *mut u32, + buffer: *const c_void, + ) -> Result<(), u32> { + let status = unsafe { ((*APITABLE).get_param)(self.handle, param, buffer_length, buffer) }; + if Status::failed(status) { + return Err(status); + } + Ok(()) + } + + pub fn receive_complete(&self, buffer_length: u64) -> Result<(), u32> { + let status = unsafe { ((*APITABLE).stream_receive_complete)(self.handle, buffer_length) }; + if Status::failed(status) { + return Err(status); + } + Ok(()) + } } impl Drop for Stream {