diff --git a/docs/Settings.md b/docs/Settings.md index 7aa2db9a03..36c0349f18 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -168,6 +168,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa | `QUIC_PARAM_CONN_CIBIR_ID`
21 | uint8_t[] | Set-only | The CIBIR well-known identifier. | | `QUIC_PARAM_CONN_STATISTICS_V2`
22 | QUIC_STATISTICS_V2 | Get-only | Connection-level statistics, version 2. | | `QUIC_PARAM_CONN_STATISTICS_V2_PLAT`
23 | QUIC_STATISTICS_V2 | Get-only | Connection-level statistics with platform-specific time format, version 2. | +| `QUIC_PARAM_CONN_ORIG_DEST_CID`
24 | uint8_t[] | Get-only | The original destination connection ID used by the client to connect to the server. | ### QUIC_PARAM_CONN_STATISTICS_V2 diff --git a/src/core/connection.c b/src/core/connection.c index 79d2f47a2d..5e60e126e5 100644 --- a/src/core/connection.c +++ b/src/core/connection.c @@ -7170,6 +7170,31 @@ QuicConnParamGet( break; } + case QUIC_PARAM_CONN_ORIG_DEST_CID: + if (Connection->OrigDestCID == NULL) { + Status = QUIC_STATUS_INVALID_STATE; + break; + } + if (*BufferLength < Connection->OrigDestCID->Length) { + Status = QUIC_STATUS_BUFFER_TOO_SMALL; + *BufferLength = Connection->OrigDestCID->Length; + break; + } + if (Buffer == NULL) { + Status = QUIC_STATUS_INVALID_PARAMETER; + break; + } + CxPlatCopyMemory( + Buffer, + Connection->OrigDestCID->Data, + Connection->OrigDestCID->Length); + // + // Tell app how much buffer we copied. + // + *BufferLength = Connection->OrigDestCID->Length; + Status = QUIC_STATUS_SUCCESS; + break; + default: Status = QUIC_STATUS_INVALID_PARAMETER; break; diff --git a/src/cs/lib/msquic_generated.cs b/src/cs/lib/msquic_generated.cs index c9cc2c9255..5893eff899 100644 --- a/src/cs/lib/msquic_generated.cs +++ b/src/cs/lib/msquic_generated.cs @@ -3110,6 +3110,9 @@ internal static unsafe partial class MsQuic [NativeTypeName("#define QUIC_PARAM_CONN_STATISTICS_V2_PLAT 0x05000017")] internal const uint QUIC_PARAM_CONN_STATISTICS_V2_PLAT = 0x05000017; + [NativeTypeName("#define QUIC_PARAM_CONN_ORIG_DEST_CID 0x05000018")] + internal const uint QUIC_PARAM_CONN_ORIG_DEST_CID = 0x05000018; + [NativeTypeName("#define QUIC_PARAM_TLS_HANDSHAKE_INFO 0x06000000")] internal const uint QUIC_PARAM_TLS_HANDSHAKE_INFO = 0x06000000; diff --git a/src/inc/msquic.h b/src/inc/msquic.h index 5f26d70fd7..ad9c5b4a14 100644 --- a/src/inc/msquic.h +++ b/src/inc/msquic.h @@ -889,6 +889,7 @@ typedef struct QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W { #endif #define QUIC_PARAM_CONN_STATISTICS_V2 0x05000016 // QUIC_STATISTICS_V2 #define QUIC_PARAM_CONN_STATISTICS_V2_PLAT 0x05000017 // QUIC_STATISTICS_V2 +#define QUIC_PARAM_CONN_ORIG_DEST_CID 0x05000018 // uint8_t[] // // Parameters for TLS. diff --git a/src/test/lib/ApiTest.cpp b/src/test/lib/ApiTest.cpp index 0db436989e..7a28f9cf33 100644 --- a/src/test/lib/ApiTest.cpp +++ b/src/test/lib/ApiTest.cpp @@ -4227,6 +4227,138 @@ void QuicTest_QUIC_PARAM_CONN_STATISTICS_V2_PLAT(MsQuicRegistration& Registratio } } + +void QuicTest_QUIC_PARAM_CONN_ORIG_DEST_CID(MsQuicRegistration& Registration, MsQuicConfiguration& ClientConfiguration) { + // + // This is the unit test for checking to see if a server has the correct original dest CID. + // + TestScopeLogger LogScope0("QUIC_PARAM_CONN_ORIG_DEST_CID"); + { + MsQuicConnection Connection(Registration); + TEST_QUIC_SUCCEEDED(Connection.GetInitStatus()); + TEST_QUIC_SUCCEEDED( + Connection.Start( + ClientConfiguration, + QUIC_ADDRESS_FAMILY_INET, + "localhost", + 4433)); + MsQuic->ConnectionSetConfiguration(Connection.Handle, ClientConfiguration); + // + // 8 bytes is the expected minimum size of the CID. + // + uint32_t SizeOfBuffer = 8; + uint8_t Buffer[8] = {0}; + uint8_t ZeroBuffer[8] = {0}; + TestScopeLogger LogScope1("GetParam test success case"); + TEST_QUIC_STATUS( + QUIC_STATUS_SUCCESS, + Connection.GetParam( + QUIC_PARAM_CONN_ORIG_DEST_CID, + &SizeOfBuffer, + Buffer + ) + ) + TEST_NOT_EQUAL(memcmp(Buffer, ZeroBuffer, sizeof(Buffer)), 0); + } + { + MsQuicConnection Connection(Registration); + TEST_QUIC_SUCCEEDED(Connection.GetInitStatus()); + TEST_QUIC_SUCCEEDED( + Connection.Start( + ClientConfiguration, + QUIC_ADDRESS_FAMILY_INET, + "localhost", + 4433)); + uint32_t SizeOfBuffer = 8; + TestScopeLogger LogScope1("GetParam null buffer check"); + TEST_QUIC_STATUS( + QUIC_STATUS_INVALID_PARAMETER, + Connection.GetParam( + QUIC_PARAM_CONN_ORIG_DEST_CID, + &SizeOfBuffer, + nullptr + ) + ) + } + { + MsQuicConnection Connection(Registration); + TEST_QUIC_SUCCEEDED(Connection.GetInitStatus()); + TEST_QUIC_SUCCEEDED( + Connection.Start( + ClientConfiguration, + QUIC_ADDRESS_FAMILY_INET, + "localhost", + 4433)); + uint32_t SizeOfBuffer = 1; + TestScopeLogger LogScope1("GetParam buffer too small check"); + uint8_t Buffer[1]; + TEST_QUIC_STATUS( + QUIC_STATUS_BUFFER_TOO_SMALL, + Connection.GetParam( + QUIC_PARAM_CONN_ORIG_DEST_CID, + &SizeOfBuffer, + Buffer + ) + ) + } + { + MsQuicConnection Connection(Registration); + TEST_QUIC_SUCCEEDED(Connection.GetInitStatus()); + TEST_QUIC_SUCCEEDED( + Connection.Start( + ClientConfiguration, + QUIC_ADDRESS_FAMILY_INET, + "localhost", + 4433)); + uint32_t SizeOfBuffer = 100; + uint8_t Buffer[100] = {0}; + uint8_t ZeroBuffer[100] = {0}; + TestScopeLogger LogScope1("GetParam size of buffer bigger than needed"); + TEST_QUIC_STATUS( + QUIC_STATUS_SUCCESS, + Connection.GetParam( + QUIC_PARAM_CONN_ORIG_DEST_CID, + &SizeOfBuffer, + Buffer + ) + ) + TEST_NOT_EQUAL(memcmp(Buffer, ZeroBuffer, sizeof(Buffer)), 0); + // + // There is no way the CID written should be 100 bytes according to the RFC. + // + TEST_TRUE(SizeOfBuffer < 100); + } + { + MsQuicConnection Connection(Registration); + TEST_QUIC_SUCCEEDED(Connection.GetInitStatus()); + TEST_QUIC_SUCCEEDED( + Connection.Start( + ClientConfiguration, + QUIC_ADDRESS_FAMILY_INET, + "localhost", + 4433)); + uint32_t SizeOfBuffer = 0; + TestScopeLogger LogScope1("GetParam check OrigDestCID size with nullptr"); + TEST_QUIC_STATUS( + QUIC_STATUS_BUFFER_TOO_SMALL, + Connection.GetParam( + QUIC_PARAM_CONN_ORIG_DEST_CID, + &SizeOfBuffer, + nullptr + ) + ) + TEST_TRUE(SizeOfBuffer >= 8); + TEST_QUIC_STATUS( + QUIC_STATUS_INVALID_PARAMETER, + Connection.GetParam( + QUIC_PARAM_CONN_ORIG_DEST_CID, + &SizeOfBuffer, + nullptr + ) + ) + } +} + void QuicTestConnectionParam() { MsQuicAlpn Alpn("MsQuicTest"); @@ -4259,6 +4391,7 @@ void QuicTestConnectionParam() QuicTest_QUIC_PARAM_CONN_CIBIR_ID(Registration, ClientConfiguration); QuicTest_QUIC_PARAM_CONN_STATISTICS_V2(Registration); QuicTest_QUIC_PARAM_CONN_STATISTICS_V2_PLAT(Registration); + QuicTest_QUIC_PARAM_CONN_ORIG_DEST_CID(Registration, ClientConfiguration); } //