Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch Param Id's to not be overlapping #1758

Merged
merged 5 commits into from
Jun 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/core/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,8 @@ MsQuicStreamReceiveComplete(
return Status;
}

#define QUIC_PARAM_GENERATOR(Level, Value) (((Level + 1) & 0x3F) << 26 | (Value & 0x3FFFFFF))

_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QUIC_API
Expand All @@ -1284,6 +1286,25 @@ MsQuicSetParam(
{
CXPLAT_PASSIVE_CODE();

if ((Param & 0xFC000000) != 0) {
//
// Has level embedded parameter. Validate matches passed in level.
//
QUIC_PARAM_LEVEL ParamContainedLevel = ((Param >> 26) & 0x3F) - 1;
if (ParamContainedLevel != Level) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"Param level does not match param value");
return QUIC_STATUS_INVALID_PARAMETER;
ThadHouse marked this conversation as resolved.
Show resolved Hide resolved
}
} else {
//
// Missing level embedded parameter. Inject level into parameter.
//
Param = QUIC_PARAM_GENERATOR(Level, Param);
}

if ((Handle == NULL) ^ (Level == QUIC_PARAM_LEVEL_GLOBAL)) {
return QUIC_STATUS_INVALID_PARAMETER;
}
Expand Down Expand Up @@ -1394,6 +1415,25 @@ MsQuicGetParam(
{
CXPLAT_PASSIVE_CODE();

if ((Param & 0xFC000000) != 0) {
//
// Has level embedded parameter. Validate matches passed in level.
//
QUIC_PARAM_LEVEL ParamContainedLevel = ((Param >> 26) & 0x3F) - 1;
if (ParamContainedLevel != Level) {
QuicTraceEvent(
LibraryError,
"[ lib] ERROR, %s.",
"Param level does not match param value");
return QUIC_STATUS_INVALID_PARAMETER;
}
} else {
//
// Missing level embedded parameter. Inject level into parameter.
//
Param = QUIC_PARAM_GENERATOR(Level, Param);
}

if (((Handle == NULL) ^ (Level == QUIC_PARAM_LEVEL_GLOBAL)) ||
BufferLength == NULL) {
return QUIC_STATUS_INVALID_PARAMETER;
Expand Down
74 changes: 39 additions & 35 deletions src/inc/msquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,56 +593,60 @@ typedef enum QUIC_PARAM_LEVEL {
QUIC_PARAM_LEVEL_STREAM,
} QUIC_PARAM_LEVEL;

//
// Top 6 bits of param are Level + 1, bottom 26 bits are parameter Id.
//

//
// Parameters for QUIC_PARAM_LEVEL_GLOBAL.
//
#define QUIC_PARAM_GLOBAL_RETRY_MEMORY_PERCENT 0 // uint16_t
#define QUIC_PARAM_GLOBAL_SUPPORTED_VERSIONS 1 // uint32_t[] - network byte order
#define QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE 2 // uint16_t - QUIC_LOAD_BALANCING_MODE
#define QUIC_PARAM_GLOBAL_PERF_COUNTERS 3 // uint64_t[] - Array size is QUIC_PERF_COUNTER_MAX
#define QUIC_PARAM_GLOBAL_SETTINGS 4 // QUIC_SETTINGS
#define QUIC_PARAM_GLOBAL_VERSION 5 // uint32_t[4]
#define QUIC_PARAM_GLOBAL_RETRY_MEMORY_PERCENT 0x4000000 // uint16_t
#define QUIC_PARAM_GLOBAL_SUPPORTED_VERSIONS 0x4000001 // uint32_t[] - network byte order
#define QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE 0x4000002 // uint16_t - QUIC_LOAD_BALANCING_MODE
#define QUIC_PARAM_GLOBAL_PERF_COUNTERS 0x4000003 // uint64_t[] - Array size is QUIC_PERF_COUNTER_MAX
#define QUIC_PARAM_GLOBAL_SETTINGS 0x4000004 // QUIC_SETTINGS
#define QUIC_PARAM_GLOBAL_VERSION 0x4000005 // uint32_t[4]

//
// Parameters for QUIC_PARAM_LEVEL_REGISTRATION.
//
#define QUIC_PARAM_REGISTRATION_CID_PREFIX 0 // uint8_t[]
#define QUIC_PARAM_REGISTRATION_CID_PREFIX 0x8000000 // uint8_t[]

//
// Parameters for QUIC_PARAM_LEVEL_CONFIGURATION.
//
#define QUIC_PARAM_CONFIGURATION_SETTINGS 0 // QUIC_SETTINGS
#define QUIC_PARAM_CONFIGURATION_TICKET_KEYS 1 // QUIC_TICKET_KEY_CONFIG[]
#define QUIC_PARAM_CONFIGURATION_SETTINGS 0xC000000 // QUIC_SETTINGS
#define QUIC_PARAM_CONFIGURATION_TICKET_KEYS 0xC000001 // QUIC_TICKET_KEY_CONFIG[]

//
// Parameters for QUIC_PARAM_LEVEL_LISTENER.
//
#define QUIC_PARAM_LISTENER_LOCAL_ADDRESS 0 // QUIC_ADDR
#define QUIC_PARAM_LISTENER_STATS 1 // QUIC_LISTENER_STATISTICS
#define QUIC_PARAM_LISTENER_LOCAL_ADDRESS 0x10000000 // QUIC_ADDR
#define QUIC_PARAM_LISTENER_STATS 0x10000001 // QUIC_LISTENER_STATISTICS

//
// Parameters for QUIC_PARAM_LEVEL_CONNECTION.
//
#define QUIC_PARAM_CONN_QUIC_VERSION 0 // uint32_t
#define QUIC_PARAM_CONN_LOCAL_ADDRESS 1 // QUIC_ADDR
#define QUIC_PARAM_CONN_REMOTE_ADDRESS 2 // QUIC_ADDR
#define QUIC_PARAM_CONN_IDEAL_PROCESSOR 3 // uint16_t
#define QUIC_PARAM_CONN_SETTINGS 4 // QUIC_SETTINGS
#define QUIC_PARAM_CONN_STATISTICS 5 // QUIC_STATISTICS
#define QUIC_PARAM_CONN_STATISTICS_PLAT 6 // QUIC_STATISTICS
#define QUIC_PARAM_CONN_SHARE_UDP_BINDING 7 // uint8_t (BOOLEAN)
#define QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT 8 // uint16_t
#define QUIC_PARAM_CONN_LOCAL_UNIDI_STREAM_COUNT 9 // uint16_t
#define QUIC_PARAM_CONN_MAX_STREAM_IDS 10 // uint64_t[4]
#define QUIC_PARAM_CONN_CLOSE_REASON_PHRASE 11 // char[]
#define QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME 12 // QUIC_STREAM_SCHEDULING_SCHEME
#define QUIC_PARAM_CONN_DATAGRAM_RECEIVE_ENABLED 13 // uint8_t (BOOLEAN)
#define QUIC_PARAM_CONN_DATAGRAM_SEND_ENABLED 14 // uint8_t (BOOLEAN)
#define QUIC_PARAM_CONN_QUIC_VERSION 0x14000000 // uint32_t
#define QUIC_PARAM_CONN_LOCAL_ADDRESS 0x14000001 // QUIC_ADDR
#define QUIC_PARAM_CONN_REMOTE_ADDRESS 0x14000002 // QUIC_ADDR
#define QUIC_PARAM_CONN_IDEAL_PROCESSOR 0x14000003 // uint16_t
#define QUIC_PARAM_CONN_SETTINGS 0x14000004 // QUIC_SETTINGS
#define QUIC_PARAM_CONN_STATISTICS 0x14000005 // QUIC_STATISTICS
#define QUIC_PARAM_CONN_STATISTICS_PLAT 0x14000006 // QUIC_STATISTICS
#define QUIC_PARAM_CONN_SHARE_UDP_BINDING 0x14000007 // uint8_t (BOOLEAN)
#define QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT 0x14000008 // uint16_t
#define QUIC_PARAM_CONN_LOCAL_UNIDI_STREAM_COUNT 0x14000009 // uint16_t
#define QUIC_PARAM_CONN_MAX_STREAM_IDS 0x1400000A // uint64_t[4]
#define QUIC_PARAM_CONN_CLOSE_REASON_PHRASE 0x1400000B // char[]
#define QUIC_PARAM_CONN_STREAM_SCHEDULING_SCHEME 0x1400000C // QUIC_STREAM_SCHEDULING_SCHEME
#define QUIC_PARAM_CONN_DATAGRAM_RECEIVE_ENABLED 0x1400000D // uint8_t (BOOLEAN)
#define QUIC_PARAM_CONN_DATAGRAM_SEND_ENABLED 0x1400000E // uint8_t (BOOLEAN)
#ifdef QUIC_API_ENABLE_INSECURE_FEATURES
#define QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION 15 // uint8_t (BOOLEAN)
#define QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION 0x1400000F // uint8_t (BOOLEAN)
#endif
#define QUIC_PARAM_CONN_RESUMPTION_TICKET 16 // uint8_t[]
#define QUIC_PARAM_CONN_PEER_CERTIFICATE_VALID 17 // uint8_t (BOOLEAN)
#define QUIC_PARAM_CONN_RESUMPTION_TICKET 0x14000010 // uint8_t[]
#define QUIC_PARAM_CONN_PEER_CERTIFICATE_VALID 0x14000011 // uint8_t (BOOLEAN)

//
// Parameters for QUIC_PARAM_LEVEL_TLS.
Expand All @@ -652,17 +656,17 @@ typedef struct QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W {
unsigned long Attribute;
void* Buffer;
} QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W;
#define QUIC_PARAM_TLS_SCHANNEL_CONTEXT_ATTRIBUTE_W 0x1000000 // QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W
#define QUIC_PARAM_TLS_SCHANNEL_CONTEXT_ATTRIBUTE_W 0x19000000 // QUIC_SCHANNEL_CONTEXT_ATTRIBUTE_W
#endif
#define QUIC_PARAM_TLS_HANDSHAKE_INFO 0 // QUIC_HANDSHAKE_INFO
#define QUIC_PARAM_TLS_NEGOTIATED_ALPN 1 // uint8_t[] (max 255 bytes)
#define QUIC_PARAM_TLS_HANDSHAKE_INFO 0x18000000 // QUIC_HANDSHAKE_INFO
#define QUIC_PARAM_TLS_NEGOTIATED_ALPN 0x18000001 // uint8_t[] (max 255 bytes)

//
// Parameters for QUIC_PARAM_LEVEL_STREAM.
//
#define QUIC_PARAM_STREAM_ID 0 // QUIC_UINT62
#define QUIC_PARAM_STREAM_0RTT_LENGTH 1 // uint64_t
#define QUIC_PARAM_STREAM_IDEAL_SEND_BUFFER_SIZE 2 // uint64_t - bytes
#define QUIC_PARAM_STREAM_ID 0x1C000000 // QUIC_UINT62
#define QUIC_PARAM_STREAM_0RTT_LENGTH 0x1C000001 // uint64_t
#define QUIC_PARAM_STREAM_IDEAL_SEND_BUFFER_SIZE 0x1C000002 // uint64_t - bytes

typedef
_IRQL_requires_max_(PASSIVE_LEVEL)
Expand Down
14 changes: 7 additions & 7 deletions src/inc/msquicp.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,18 @@ typedef struct CXPLAT_TLS_SECRETS {
// The different private parameters for QUIC_PARAM_LEVEL_GLOBAL.
//

#define QUIC_PARAM_GLOBAL_TEST_DATAPATH_HOOKS 0x80000001 // QUIC_TEST_DATAPATH_HOOKS*
#define QUIC_PARAM_GLOBAL_ALLOC_FAIL_DENOMINATOR 0x80000002 // uint32_t
#define QUIC_PARAM_GLOBAL_ALLOC_FAIL_CYCLE 0x80000003 // uint32_t
#define QUIC_PARAM_GLOBAL_TEST_DATAPATH_HOOKS 0x5000001 // QUIC_TEST_DATAPATH_HOOKS*
#define QUIC_PARAM_GLOBAL_ALLOC_FAIL_DENOMINATOR 0x5000002 // uint32_t
#define QUIC_PARAM_GLOBAL_ALLOC_FAIL_CYCLE 0x5000003 // uint32_t

//
// The different private parameters for QUIC_PARAM_LEVEL_CONNECTION.
//

#define QUIC_PARAM_CONN_FORCE_KEY_UPDATE 0x80000001 // No payload
#define QUIC_PARAM_CONN_FORCE_CID_UPDATE 0x80000002 // No payload
#define QUIC_PARAM_CONN_TEST_TRANSPORT_PARAMETER 0x80000003 // QUIC_PRIVATE_TRANSPORT_PARAMETER
#define QUIC_PARAM_CONN_TLS_SECRETS 0x80000004 // CXPLAT_TLS_SECRETS (SSLKEYLOGFILE compatible)
#define QUIC_PARAM_CONN_FORCE_KEY_UPDATE 0x15000001 // No payload
#define QUIC_PARAM_CONN_FORCE_CID_UPDATE 0x15000002 // No payload
#define QUIC_PARAM_CONN_TEST_TRANSPORT_PARAMETER 0x15000003 // QUIC_PRIVATE_TRANSPORT_PARAMETER
#define QUIC_PARAM_CONN_TLS_SECRETS 0x15000004 // CXPLAT_TLS_SECRETS (SSLKEYLOGFILE compatible)

#if defined(__cplusplus)
}
Expand Down
6 changes: 5 additions & 1 deletion src/test/MsQuicTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void QuicTestValidateConnection();
void QuicTestValidateStream(bool Connect);
void QuicTestGetPerfCounters();
void QuicTestDesiredVersionSettings();
void QuicTestValidateParamApi();

//
// Event Validation Tests
Expand Down Expand Up @@ -864,4 +865,7 @@ typedef struct {
QUIC_CTL_CODE(70, METHOD_BUFFERED, FILE_WRITE_DATA)
// int - Family

#define QUIC_MAX_IOCTL_FUNC_CODE 70
#define IOCTL_QUIC_RUN_VALIDATE_PARAM_API \
QUIC_CTL_CODE(71, METHOD_BUFFERED, FILE_WRITE_DATA)

#define QUIC_MAX_IOCTL_FUNC_CODE 71
9 changes: 9 additions & 0 deletions src/test/bin/quic_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,15 @@ TEST(ParameterValidation, ValidateDesiredVersionSettings) {
}
}

TEST(ParameterValidation, ValidateParamApi) {
TestLogger Logger("QuicTestValidateParamApi");
if (TestingKernelMode) {
ASSERT_TRUE(DriverClient.Run(IOCTL_QUIC_RUN_VALIDATE_PARAM_API));
} else {
QuicTestValidateParamApi();
}
}

TEST(Basic, CreateListener) {
TestLogger Logger("QuicTestCreateListener");
if (TestingKernelMode) {
Expand Down
5 changes: 5 additions & 0 deletions src/test/bin/winkernel/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ size_t QUIC_IOCTL_BUFFER_SIZES[] =
sizeof(QUIC_RUN_MTU_DISCOVERY_PARAMS),
sizeof(INT32),
sizeof(INT32),
0
};

CXPLAT_STATIC_ASSERT(
Expand Down Expand Up @@ -1073,6 +1074,10 @@ QuicTestCtlEvtIoDeviceControl(
QuicTestCtlRun(QuicTestClientSharedLocalPort(Params->Family));
break;

case IOCTL_QUIC_RUN_VALIDATE_PARAM_API:
QuicTestCtlRun(QuicTestValidateParamApi());
break;

default:
Status = STATUS_NOT_IMPLEMENTED;
break;
Expand Down
66 changes: 66 additions & 0 deletions src/test/lib/ApiTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1820,3 +1820,69 @@ QuicTestDesiredVersionSettings()
}
}
}

void
QuicTestValidateParamApi()
{
//
// Test backwards compatibility.
//
uint16_t LoadBalancingMode, LoadBalancingMode2;
uint32_t BufferSize = sizeof(LoadBalancingMode);

TEST_QUIC_STATUS(
QUIC_STATUS_INVALID_PARAMETER,
MsQuic->GetParam(
nullptr,
QUIC_PARAM_LEVEL_CONFIGURATION,
QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE,
&BufferSize,
(void*)&LoadBalancingMode));

BufferSize = sizeof(LoadBalancingMode);
TEST_QUIC_SUCCEEDED(
MsQuic->GetParam(
nullptr,
QUIC_PARAM_LEVEL_GLOBAL,
2, // Special case to test backwards compatiblity
&BufferSize,
(void*)&LoadBalancingMode));

BufferSize = sizeof(LoadBalancingMode2);
TEST_QUIC_SUCCEEDED(
MsQuic->GetParam(
nullptr,
QUIC_PARAM_LEVEL_GLOBAL,
QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE,
&BufferSize,
(void*)&LoadBalancingMode2));

TEST_EQUAL(LoadBalancingMode, LoadBalancingMode2);

TEST_QUIC_STATUS(
QUIC_STATUS_INVALID_PARAMETER,
MsQuic->SetParam(
nullptr,
QUIC_PARAM_LEVEL_CONFIGURATION,
QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE,
BufferSize,
(void*)&LoadBalancingMode));

BufferSize = sizeof(LoadBalancingMode);
TEST_QUIC_SUCCEEDED(
MsQuic->SetParam(
nullptr,
QUIC_PARAM_LEVEL_GLOBAL,
2, // Special case to test backwards compatiblity
BufferSize,
(void*)&LoadBalancingMode));

BufferSize = sizeof(LoadBalancingMode2);
TEST_QUIC_SUCCEEDED(
MsQuic->SetParam(
nullptr,
QUIC_PARAM_LEVEL_GLOBAL,
QUIC_PARAM_GLOBAL_LOAD_BALACING_MODE,
BufferSize,
(void*)&LoadBalancingMode2));
}