Skip to content

Commit bb17196

Browse files
authored
Add Support for GetParam for Stat Sizes (#5111)
1 parent 0298f93 commit bb17196

File tree

8 files changed

+161
-0
lines changed

8 files changed

+161
-0
lines changed

docs/Settings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa
118118
| `QUIC_PARAM_GLOBAL_EXECUTION_CONFIG`<br> 9 (preview) | QUIC_GLOBAL_EXECUTION_CONFIG | Both | Globally configure the execution model used for QUIC. Must be set before opening registration. |
119119
| `QUIC_PARAM_GLOBAL_TLS_PROVIDER`<br> 10 | QUIC_TLS_PROVIDER | Get-Only | The TLS provider being used by MsQuic for the TLS handshake. |
120120
| `QUIC_PARAM_GLOBAL_STATELESS_RESET_KEY`<br> 11 | uint8_t[] | Set-Only | Globally change the stateless reset key for all subsequent connections. |
121+
| `QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES`<br> 12 | uint32_t[] | Get-only | Array of well-known sizes for each version of the QUIC_STATISTICS_V2 struct. The output array length is variable; pass a buffer of uint32_t and check BufferLength for the number of sizes returned. See GetParam documentation for usage details. |
121122
| `QUIC_PARAM_GLOBAL_VERSION_NEGOTIATION_ENABLED`<br> (preview) | uint8_t (BOOLEAN) | Both | Globally enable the version negotiation extension for all client and server connections. |
122123

123124
## Registration Parameters

docs/api/GetParam.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,38 @@ Sample of double-call:
7171
}
7272
```
7373

74+
# Special Parameters
75+
76+
## QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES
77+
78+
Returns an array of well-known sizes (in bytes) for each version of the `QUIC_STATISTICS_V2` struct. This allows applications to determine the correct buffer size for statistics queries, even as new versions are added in future MsQuic releases.
79+
80+
> **Note** - Most applications should **not** leverage this and instead directly call to query the `QUIC_STATISTICS_V2`. This API is only necessary for layers on top of MsQuic that need to pass through this information to additional layers on top of them.
81+
82+
- **Type:** `uint32_t[]` (array of struct sizes)
83+
- **Get-only**
84+
- **Variable-length:** The number of sizes returned may change in future versions. The caller should pass a buffer of `uint32_t` and use the double-call pattern to determine the required buffer size.
85+
86+
**Sample usage:**
87+
```c
88+
uint32_t Sizes[8]; // Large enough for future growth
89+
uint32_t BufferLength = sizeof(Sizes);
90+
QUIC_STATUS Status =
91+
MsQuic->GetParam(
92+
NULL,
93+
QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES,
94+
&BufferLength,
95+
Sizes);
96+
if (Status == QUIC_STATUS_BUFFER_TOO_SMALL) {
97+
// BufferLength is set to required size (in bytes)
98+
// Allocate a larger buffer and call again
99+
}
100+
uint32_t NumSizes = BufferLength / sizeof(uint32_t);
101+
// Sizes[0..NumSizes-1] now contains the struct sizes for each version
102+
```
103+
104+
See also: [Settings.md](../Settings.md#global-parameters)
105+
74106
# See Also
75107
76108
[Settings](../Settings.md#api-object-parameters)<br>

src/core/library.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,32 @@ QuicLibraryGetGlobalParam(
14981498
Status = QUIC_STATUS_SUCCESS;
14991499
break;
15001500

1501+
case QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES: {
1502+
static const uint32_t StatSizes[] = {
1503+
QUIC_STATISTICS_V2_SIZE_1,
1504+
QUIC_STATISTICS_V2_SIZE_2,
1505+
QUIC_STATISTICS_V2_SIZE_3,
1506+
QUIC_STATISTICS_V2_SIZE_4
1507+
};
1508+
static const uint32_t NumStatSizes = ARRAYSIZE(StatSizes);
1509+
uint32_t MaxSizes = *BufferLength / sizeof(uint32_t);
1510+
if (MaxSizes == 0) {
1511+
*BufferLength = NumStatSizes * sizeof(uint32_t); // Indicate the max size.
1512+
Status = QUIC_STATUS_BUFFER_TOO_SMALL;
1513+
break;
1514+
}
1515+
if (Buffer == NULL) {
1516+
Status = QUIC_STATUS_INVALID_PARAMETER;
1517+
break;
1518+
}
1519+
const uint32_t ToCopy =
1520+
CXPLAT_MIN(MaxSizes, NumStatSizes) * sizeof(uint32_t);
1521+
CxPlatCopyMemory(Buffer, StatSizes, ToCopy);
1522+
*BufferLength = ToCopy;
1523+
Status = QUIC_STATUS_SUCCESS;
1524+
break;
1525+
}
1526+
15011527
default:
15021528
Status = QUIC_STATUS_INVALID_PARAMETER;
15031529
break;

src/cs/lib/msquic_generated.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3612,6 +3612,9 @@ internal static unsafe partial class MsQuic
36123612
[NativeTypeName("#define QUIC_PARAM_GLOBAL_STATELESS_RESET_KEY 0x0100000B")]
36133613
internal const uint QUIC_PARAM_GLOBAL_STATELESS_RESET_KEY = 0x0100000B;
36143614

3615+
[NativeTypeName("#define QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES 0x0100000C")]
3616+
internal const uint QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES = 0x0100000C;
3617+
36153618
[NativeTypeName("#define QUIC_PARAM_CONFIGURATION_SETTINGS 0x03000000")]
36163619
internal const uint QUIC_PARAM_CONFIGURATION_SETTINGS = 0x03000000;
36173620

src/inc/msquic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ void
946946
#endif
947947
#define QUIC_PARAM_GLOBAL_TLS_PROVIDER 0x0100000A // QUIC_TLS_PROVIDER
948948
#define QUIC_PARAM_GLOBAL_STATELESS_RESET_KEY 0x0100000B // uint8_t[] - Array size is QUIC_STATELESS_RESET_KEY_LENGTH
949+
#define QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES 0x0100000C // uint32_t[] - Array of sizes for each QUIC_STATISTICS_V2 version. Get-only. Pass a buffer of uint32_t, output count is variable. See documentation for details.
949950

950951
//
951952
// Parameters for Registration.

src/rs/ffi/linux_bindings.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ pub const QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH: u32 = 16777224;
174174
pub const QUIC_PARAM_GLOBAL_EXECUTION_CONFIG: u32 = 16777225;
175175
pub const QUIC_PARAM_GLOBAL_TLS_PROVIDER: u32 = 16777226;
176176
pub const QUIC_PARAM_GLOBAL_STATELESS_RESET_KEY: u32 = 16777227;
177+
pub const QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES: u32 = 16777228;
177178
pub const QUIC_PARAM_CONFIGURATION_SETTINGS: u32 = 50331648;
178179
pub const QUIC_PARAM_CONFIGURATION_TICKET_KEYS: u32 = 50331649;
179180
pub const QUIC_PARAM_CONFIGURATION_VERSION_SETTINGS: u32 = 50331650;

src/rs/ffi/win_bindings.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ pub const QUIC_PARAM_GLOBAL_LIBRARY_GIT_HASH: u32 = 16777224;
168168
pub const QUIC_PARAM_GLOBAL_EXECUTION_CONFIG: u32 = 16777225;
169169
pub const QUIC_PARAM_GLOBAL_TLS_PROVIDER: u32 = 16777226;
170170
pub const QUIC_PARAM_GLOBAL_STATELESS_RESET_KEY: u32 = 16777227;
171+
pub const QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES: u32 = 16777228;
171172
pub const QUIC_PARAM_CONFIGURATION_SETTINGS: u32 = 50331648;
172173
pub const QUIC_PARAM_CONFIGURATION_TICKET_KEYS: u32 = 50331649;
173174
pub const QUIC_PARAM_CONFIGURATION_VERSION_SETTINGS: u32 = 50331650;

src/test/lib/ApiTest.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2787,6 +2787,102 @@ void QuicTestGlobalParam()
27872787
nullptr));
27882788
}
27892789

2790+
//
2791+
// QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES
2792+
//
2793+
{
2794+
TestScopeLogger LogScope0("QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES");
2795+
const uint32_t Expected[] = {
2796+
QUIC_STATISTICS_V2_SIZE_1,
2797+
QUIC_STATISTICS_V2_SIZE_2,
2798+
QUIC_STATISTICS_V2_SIZE_3,
2799+
QUIC_STATISTICS_V2_SIZE_4
2800+
};
2801+
2802+
//
2803+
// Expect buffer too small
2804+
//
2805+
uint32_t Length = 0;
2806+
TEST_QUIC_STATUS(
2807+
QUIC_STATUS_BUFFER_TOO_SMALL,
2808+
MsQuic->GetParam(
2809+
nullptr,
2810+
QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES,
2811+
&Length,
2812+
nullptr));
2813+
TEST_TRUE(Length >= sizeof(Expected));
2814+
2815+
//
2816+
// NULL pointer output error case
2817+
//
2818+
Length = sizeof(uint32_t);
2819+
TEST_QUIC_STATUS(
2820+
QUIC_STATUS_INVALID_PARAMETER,
2821+
MsQuic->GetParam(
2822+
nullptr,
2823+
QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES,
2824+
&Length,
2825+
nullptr));
2826+
2827+
//
2828+
// Retrieve the sizes
2829+
//
2830+
uint32_t Sizes[8] = {0};
2831+
Length = sizeof(Sizes);
2832+
TEST_QUIC_SUCCEEDED(
2833+
MsQuic->GetParam(
2834+
nullptr,
2835+
QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES,
2836+
&Length,
2837+
Sizes));
2838+
TEST_TRUE(Length % sizeof(uint32_t) == 0);
2839+
TEST_TRUE(Length >= sizeof(Expected));
2840+
for (uint32_t i = 0; i < ARRAYSIZE(Expected); ++i) {
2841+
TEST_EQUAL(Sizes[i], Expected[i]);
2842+
}
2843+
2844+
//
2845+
// Partial retrieve
2846+
//
2847+
uint32_t SingleSize = 0;
2848+
Length = sizeof(SingleSize);
2849+
TEST_QUIC_SUCCEEDED(
2850+
MsQuic->GetParam(
2851+
nullptr,
2852+
QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES,
2853+
&Length,
2854+
&SingleSize));
2855+
TEST_EQUAL(Length, sizeof(uint32_t));
2856+
TEST_EQUAL(SingleSize, QUIC_STATISTICS_V2_SIZE_1);
2857+
2858+
//
2859+
// Non-multiple of sizeof(uin32_t)
2860+
//
2861+
Length = sizeof(uint32_t) + 1;
2862+
TEST_QUIC_SUCCEEDED(
2863+
MsQuic->GetParam(
2864+
nullptr,
2865+
QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES,
2866+
&Length,
2867+
Sizes));
2868+
TEST_EQUAL(Length, sizeof(uint32_t));
2869+
TEST_EQUAL(Sizes[0], QUIC_STATISTICS_V2_SIZE_1);
2870+
2871+
//
2872+
// Too Small Receive
2873+
//
2874+
uint8_t SmallSingleSize = 0;
2875+
Length = sizeof(SmallSingleSize);
2876+
TEST_QUIC_STATUS(
2877+
QUIC_STATUS_BUFFER_TOO_SMALL,
2878+
MsQuic->GetParam(
2879+
nullptr,
2880+
QUIC_PARAM_GLOBAL_STATISTICS_V2_SIZES,
2881+
&Length,
2882+
&SmallSingleSize));
2883+
TEST_TRUE(Length >= sizeof(Expected));
2884+
}
2885+
27902886
QuicTestStatefulGlobalSetParam();
27912887
}
27922888

0 commit comments

Comments
 (0)