Skip to content

Commit dd842c9

Browse files
authored
Added GetParam for Network Statistics (#5119)
1 parent 63c9229 commit dd842c9

File tree

12 files changed

+213
-143
lines changed

12 files changed

+213
-143
lines changed

docs/Settings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa
183183
| `QUIC_PARAM_CONN_STATISTICS_V2_PLAT`<br> 23 | QUIC_STATISTICS_V2 | Get-only | Connection-level statistics with platform-specific time format, version 2. |
184184
| `QUIC_PARAM_CONN_ORIG_DEST_CID` <br> 24 | uint8_t[] | Get-only | The original destination connection ID used by the client to connect to the server. |
185185
| `QUIC_PARAM_CONN_SEND_DSCP` <br> 25 | uint8_t | Both | The DiffServ Code Point put in the DiffServ field (formerly TypeOfService/TrafficClass) on packets sent from this connection. |
186+
| `QUIC_PARAM_CONN_NETWORK_STATISTICS` <br> 20 | QUIC_NETWORK_STATISTICS | Get-only | Returns Connection level network statistics |
186187

187188
### QUIC_PARAM_CONN_STATISTICS_V2
188189

docs/api/QUIC_CONNECTION_EVENT.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,7 @@ typedef struct QUIC_CONNECTION_EVENT {
112112
BOOLEAN SendNegotiated; // TRUE if sending one-way delay timestamps is negotiated.
113113
BOOLEAN ReceiveNegotiated; // TRUE if receiving one-way delay timestamps is negotiated.
114114
} ONE_WAY_DELAY_NEGOTIATED;
115-
struct {
116-
uint32_t BytesInFlight; // Bytes that were sent on the wire, but not yet acked
117-
uint64_t PostedBytes; // Total bytes queued, but not yet acked. These may contain sent bytes that may have potentially lost too.
118-
uint64_t IdealBytes; // Ideal number of bytes required to be available to avoid limiting throughput
119-
uint64_t SmoothedRTT; // Smoothed RTT value
120-
uint32_t CongestionWindow; // Congestion Window
121-
uint64_t Bandwidth; // Estimated bandwidth
122-
} NETWORK_STATISTICS;
115+
QUIC_NETWORK_STATISTICS NETWORK_STATISTICS;
123116
#endif
124117

125118
};
@@ -450,7 +443,7 @@ This event is only indicated if QUIC_SETTINGS.EnableNetStatsEvent is TRUE. This
450443

451444
### NETWORK_STATISTICS
452445

453-
Detailed networking statistics are passed in the `NETWORK_STATISTICS` struct/union.
446+
Detailed networking statistics are passed in the `QUIC_NETWORK_STATISTICS` struct/union.
454447

455448
`BytesInFlight`
456449

src/core/bbr.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -299,23 +299,36 @@ QuicConnLogBbr(
299299
BbrCongestionControlIsAppLimited(Cc));
300300
}
301301

302+
_IRQL_requires_max_(DISPATCH_LEVEL)
303+
void
304+
BbrCongestionControlGetNetworkStatistics(
305+
_In_ const QUIC_CONNECTION* const Connection,
306+
_In_ const QUIC_CONGESTION_CONTROL* const Cc,
307+
_Out_ QUIC_NETWORK_STATISTICS* NetworkStatistics
308+
)
309+
{
310+
const QUIC_CONGESTION_CONTROL_BBR* Bbr = &Cc->Bbr;
311+
const QUIC_PATH* Path = &Connection->Paths[0];
312+
313+
NetworkStatistics->BytesInFlight = Bbr->BytesInFlight;
314+
NetworkStatistics->PostedBytes = Connection->SendBuffer.PostedBytes;
315+
NetworkStatistics->IdealBytes = Connection->SendBuffer.IdealBytes;
316+
NetworkStatistics->SmoothedRTT = Path->SmoothedRtt;
317+
NetworkStatistics->CongestionWindow = BbrCongestionControlGetCongestionWindow(Cc);
318+
NetworkStatistics->Bandwidth = BbrCongestionControlGetBandwidth(Cc) / BW_UNIT;
319+
}
320+
302321
_IRQL_requires_max_(DISPATCH_LEVEL)
303322
void
304323
BbrCongestionControlIndicateConnectionEvent(
305324
_In_ QUIC_CONNECTION* const Connection,
306325
_In_ const QUIC_CONGESTION_CONTROL* Cc
307326
)
308327
{
309-
const QUIC_CONGESTION_CONTROL_BBR* Bbr = &Cc->Bbr;
310-
const QUIC_PATH* Path = &Connection->Paths[0];
311328
QUIC_CONNECTION_EVENT Event;
312329
Event.Type = QUIC_CONNECTION_EVENT_NETWORK_STATISTICS;
313-
Event.NETWORK_STATISTICS.BytesInFlight = Bbr->BytesInFlight;
314-
Event.NETWORK_STATISTICS.PostedBytes = Connection->SendBuffer.PostedBytes;
315-
Event.NETWORK_STATISTICS.IdealBytes = Connection->SendBuffer.IdealBytes;
316-
Event.NETWORK_STATISTICS.SmoothedRTT = Path->SmoothedRtt;
317-
Event.NETWORK_STATISTICS.CongestionWindow = BbrCongestionControlGetCongestionWindow(Cc);
318-
Event.NETWORK_STATISTICS.Bandwidth = BbrCongestionControlGetBandwidth(Cc) / BW_UNIT;
330+
331+
BbrCongestionControlGetNetworkStatistics(Connection, Cc, &Event.NETWORK_STATISTICS);
319332

320333
QuicTraceLogConnVerbose(
321334
IndicateDataAcked,
@@ -1068,6 +1081,7 @@ static const QUIC_CONGESTION_CONTROL QuicCongestionControlBbr = {
10681081
.QuicCongestionControlGetBytesInFlightMax = BbrCongestionControlGetBytesInFlightMax,
10691082
.QuicCongestionControlIsAppLimited = BbrCongestionControlIsAppLimited,
10701083
.QuicCongestionControlSetAppLimited = BbrCongestionControlSetAppLimited,
1084+
.QuicCongestionControlGetNetworkStatistics = BbrCongestionControlGetNetworkStatistics
10711085
};
10721086

10731087
_IRQL_requires_max_(DISPATCH_LEVEL)

src/core/congestion_control.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ typedef struct QUIC_CONGESTION_CONTROL {
155155
_In_ struct QUIC_CONGESTION_CONTROL* Cc
156156
);
157157

158+
void (*QuicCongestionControlGetNetworkStatistics)(
159+
_In_ const QUIC_CONNECTION* const Connection,
160+
_In_ const struct QUIC_CONGESTION_CONTROL* const Cc,
161+
_Out_ struct QUIC_NETWORK_STATISTICS* NetworkStatistics
162+
);
163+
158164
//
159165
// Algorithm specific state.
160166
//

src/core/connection.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6926,6 +6926,33 @@ QuicConnGetV2Statistics(
69266926
return QUIC_STATUS_SUCCESS;
69276927
}
69286928

6929+
_IRQL_requires_max_(PASSIVE_LEVEL)
6930+
static
6931+
QUIC_STATUS
6932+
QuicConnGetNetworkStatistics(
6933+
_In_ const QUIC_CONNECTION* Connection,
6934+
_Inout_ uint32_t* StatsLength,
6935+
_Out_writes_bytes_opt_(*StatsLength)
6936+
QUIC_NETWORK_STATISTICS* Stats
6937+
)
6938+
{
6939+
if (*StatsLength < sizeof(QUIC_NETWORK_STATISTICS)) {
6940+
*StatsLength = sizeof(QUIC_NETWORK_STATISTICS);
6941+
return QUIC_STATUS_BUFFER_TOO_SMALL;
6942+
}
6943+
6944+
if (Stats == NULL) {
6945+
return QUIC_STATUS_INVALID_PARAMETER;
6946+
}
6947+
6948+
CxPlatZeroMemory(Stats, sizeof(QUIC_NETWORK_STATISTICS));
6949+
6950+
Connection->CongestionControl.QuicCongestionControlGetNetworkStatistics(
6951+
Connection, &Connection->CongestionControl, Stats);
6952+
6953+
return QUIC_STATUS_SUCCESS;
6954+
}
6955+
69296956
_IRQL_requires_max_(PASSIVE_LEVEL)
69306957
QUIC_STATUS
69316958
QuicConnParamGet(
@@ -7344,6 +7371,11 @@ QuicConnParamGet(
73447371
Status = QUIC_STATUS_SUCCESS;
73457372
break;
73467373

7374+
case QUIC_PARAM_CONN_NETWORK_STATISTICS:
7375+
Status =
7376+
QuicConnGetNetworkStatistics(Connection, BufferLength, (QUIC_NETWORK_STATISTICS *)Buffer);
7377+
break;
7378+
73477379
default:
73487380
Status = QUIC_STATUS_INVALID_PARAMETER;
73497381
break;

src/core/cubic.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,25 @@ CubicCongestionControlOnDataInvalidated(
414414
return CubicCongestionControlUpdateBlockedState(Cc, PreviousCanSendState);
415415
}
416416

417+
_IRQL_requires_max_(DISPATCH_LEVEL)
418+
void
419+
CubicCongestionControlGetNetworkStatistics(
420+
_In_ const QUIC_CONNECTION* const Connection,
421+
_In_ const QUIC_CONGESTION_CONTROL* const Cc,
422+
_Out_ QUIC_NETWORK_STATISTICS* NetworkStatistics
423+
)
424+
{
425+
const QUIC_CONGESTION_CONTROL_CUBIC* Cubic = &Cc->Cubic;
426+
const QUIC_PATH* Path = &Connection->Paths[0];
427+
428+
NetworkStatistics->BytesInFlight = Cubic->BytesInFlight;
429+
NetworkStatistics->PostedBytes = Connection->SendBuffer.PostedBytes;
430+
NetworkStatistics->IdealBytes = Connection->SendBuffer.IdealBytes;
431+
NetworkStatistics->SmoothedRTT = Path->SmoothedRtt;
432+
NetworkStatistics->CongestionWindow = Cubic->CongestionWindow;
433+
NetworkStatistics->Bandwidth = Cubic->CongestionWindow / Path->SmoothedRtt;
434+
}
435+
417436
_IRQL_requires_max_(DISPATCH_LEVEL)
418437
BOOLEAN
419438
CubicCongestionControlOnDataAcknowledged(
@@ -888,6 +907,7 @@ static const QUIC_CONGESTION_CONTROL QuicCongestionControlCubic = {
888907
.QuicCongestionControlIsAppLimited = CubicCongestionControlIsAppLimited,
889908
.QuicCongestionControlSetAppLimited = CubicCongestionControlSetAppLimited,
890909
.QuicCongestionControlGetCongestionWindow = CubicCongestionControlGetCongestionWindow,
910+
.QuicCongestionControlGetNetworkStatistics = CubicCongestionControlGetNetworkStatistics
891911
};
892912

893913
_IRQL_requires_max_(DISPATCH_LEVEL)

src/cs/lib/msquic_generated.cs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,27 @@ internal uint RESERVED
926926
internal uint RttVariance;
927927
}
928928

929+
internal partial struct QUIC_NETWORK_STATISTICS
930+
{
931+
[NativeTypeName("uint32_t")]
932+
internal uint BytesInFlight;
933+
934+
[NativeTypeName("uint64_t")]
935+
internal ulong PostedBytes;
936+
937+
[NativeTypeName("uint64_t")]
938+
internal ulong IdealBytes;
939+
940+
[NativeTypeName("uint64_t")]
941+
internal ulong SmoothedRTT;
942+
943+
[NativeTypeName("uint32_t")]
944+
internal uint CongestionWindow;
945+
946+
[NativeTypeName("uint64_t")]
947+
internal ulong Bandwidth;
948+
}
949+
929950
internal partial struct QUIC_LISTENER_STATISTICS
930951
{
931952
[NativeTypeName("uint64_t")]
@@ -2762,7 +2783,7 @@ internal ref _Anonymous_e__Union._ONE_WAY_DELAY_NEGOTIATED_e__Struct ONE_WAY_DEL
27622783
}
27632784
}
27642785

2765-
internal ref _Anonymous_e__Union._NETWORK_STATISTICS_e__Struct NETWORK_STATISTICS
2786+
internal ref QUIC_NETWORK_STATISTICS NETWORK_STATISTICS
27662787
{
27672788
get
27682789
{
@@ -2846,8 +2867,7 @@ internal partial struct _Anonymous_e__Union
28462867
internal _ONE_WAY_DELAY_NEGOTIATED_e__Struct ONE_WAY_DELAY_NEGOTIATED;
28472868

28482869
[FieldOffset(0)]
2849-
[NativeTypeName("struct (anonymous struct)")]
2850-
internal _NETWORK_STATISTICS_e__Struct NETWORK_STATISTICS;
2870+
internal QUIC_NETWORK_STATISTICS NETWORK_STATISTICS;
28512871

28522872
internal unsafe partial struct _CONNECTED_e__Struct
28532873
{
@@ -3038,27 +3058,6 @@ internal partial struct _ONE_WAY_DELAY_NEGOTIATED_e__Struct
30383058
[NativeTypeName("BOOLEAN")]
30393059
internal byte ReceiveNegotiated;
30403060
}
3041-
3042-
internal partial struct _NETWORK_STATISTICS_e__Struct
3043-
{
3044-
[NativeTypeName("uint32_t")]
3045-
internal uint BytesInFlight;
3046-
3047-
[NativeTypeName("uint64_t")]
3048-
internal ulong PostedBytes;
3049-
3050-
[NativeTypeName("uint64_t")]
3051-
internal ulong IdealBytes;
3052-
3053-
[NativeTypeName("uint64_t")]
3054-
internal ulong SmoothedRTT;
3055-
3056-
[NativeTypeName("uint32_t")]
3057-
internal uint CongestionWindow;
3058-
3059-
[NativeTypeName("uint64_t")]
3060-
internal ulong Bandwidth;
3061-
}
30623061
}
30633062
}
30643063

@@ -3717,6 +3716,9 @@ internal static unsafe partial class MsQuic
37173716
[NativeTypeName("#define QUIC_PARAM_CONN_SEND_DSCP 0x05000019")]
37183717
internal const uint QUIC_PARAM_CONN_SEND_DSCP = 0x05000019;
37193718

3719+
[NativeTypeName("#define QUIC_PARAM_CONN_NETWORK_STATISTICS 0x05000020")]
3720+
internal const uint QUIC_PARAM_CONN_NETWORK_STATISTICS = 0x05000020;
3721+
37203722
[NativeTypeName("#define QUIC_PARAM_TLS_HANDSHAKE_INFO 0x06000000")]
37213723
internal const uint QUIC_PARAM_TLS_HANDSHAKE_INFO = 0x06000000;
37223724

src/inc/msquic.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,17 @@ typedef struct QUIC_STATISTICS_V2 {
641641

642642
} QUIC_STATISTICS_V2;
643643

644+
typedef struct QUIC_NETWORK_STATISTICS
645+
{
646+
uint32_t BytesInFlight; // Bytes that were sent on the wire, but not yet acked
647+
uint64_t PostedBytes; // Total bytes queued, but not yet acked. These may contain sent bytes that may have potentially lost too.
648+
uint64_t IdealBytes; // Ideal number of bytes required to be available to avoid limiting throughput
649+
uint64_t SmoothedRTT; // Smoothed RTT value
650+
uint32_t CongestionWindow; // Congestion Window
651+
uint64_t Bandwidth; // Estimated bandwidth
652+
653+
} QUIC_NETWORK_STATISTICS;
654+
644655
#define QUIC_STRUCT_SIZE_THRU_FIELD(Struct, Field) \
645656
(FIELD_OFFSET(Struct, Field) + sizeof(((Struct*)0)->Field))
646657

@@ -1011,6 +1022,9 @@ typedef struct QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W {
10111022
#define QUIC_PARAM_CONN_STATISTICS_V2_PLAT 0x05000017 // QUIC_STATISTICS_V2
10121023
#define QUIC_PARAM_CONN_ORIG_DEST_CID 0x05000018 // uint8_t[]
10131024
#define QUIC_PARAM_CONN_SEND_DSCP 0x05000019 // uint8_t
1025+
#ifdef QUIC_API_ENABLE_PREVIEW_FEATURES
1026+
#define QUIC_PARAM_CONN_NETWORK_STATISTICS 0x05000020 // struct QUIC_NETWORK_STATISTICS
1027+
#endif
10141028

10151029
//
10161030
// Parameters for TLS.
@@ -1360,14 +1374,7 @@ typedef struct QUIC_CONNECTION_EVENT {
13601374
BOOLEAN SendNegotiated; // TRUE if sending one-way delay timestamps is negotiated.
13611375
BOOLEAN ReceiveNegotiated; // TRUE if receiving one-way delay timestamps is negotiated.
13621376
} ONE_WAY_DELAY_NEGOTIATED;
1363-
struct {
1364-
uint32_t BytesInFlight; // Bytes that were sent on the wire, but not yet acked
1365-
uint64_t PostedBytes; // Total bytes queued, but not yet acked. These may contain sent bytes that may have potentially lost too.
1366-
uint64_t IdealBytes; // Ideal number of bytes required to be available to avoid limiting throughput
1367-
uint64_t SmoothedRTT; // Smoothed RTT value
1368-
uint32_t CongestionWindow; // Congestion Window
1369-
uint64_t Bandwidth; // Estimated bandwidth
1370-
} NETWORK_STATISTICS;
1377+
QUIC_NETWORK_STATISTICS NETWORK_STATISTICS;
13711378
#endif
13721379
};
13731380
} QUIC_CONNECTION_EVENT;

0 commit comments

Comments
 (0)