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);
}
//