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

Add support for setting TypeOfService/TrafficClass on connections #4757

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions docs/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ These parameters are accessed by calling [GetParam](./api/GetParam.md) or [SetPa
| `QUIC_PARAM_CONN_STATISTICS_V2`<br> 22 | QUIC_STATISTICS_V2 | Get-only | Connection-level statistics, version 2. |
| `QUIC_PARAM_CONN_STATISTICS_V2_PLAT`<br> 23 | QUIC_STATISTICS_V2 | Get-only | Connection-level statistics with platform-specific time format, version 2. |
| `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. |
| `QUIC_PARAM_CONN_DSCP` <br> 25 | uint8_t | Both | The value put in the Type of Service/Traffic Class field on packets sent from this connection. |

### QUIC_PARAM_CONN_STATISTICS_V2

Expand Down
49 changes: 49 additions & 0 deletions src/core/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -6623,6 +6623,27 @@ QuicConnParamSet(
return QUIC_STATUS_SUCCESS;
}

case QUIC_PARAM_CONN_DSCP:
{
if (BufferLength != sizeof(uint8_t) || Buffer == NULL) {
Status = QUIC_STATUS_INVALID_PARAMETER;
break;
}

uint8_t DSCP = 0;
CxPlatCopyMemory(&DSCP, Buffer, BufferLength);

if (DSCP > CXPLAT_MAX_DSCP) {
Status = QUIC_STATUS_INVALID_PARAMETER;
break;
}

Connection->DSCP = DSCP;

Status = QUIC_STATUS_SUCCESS;
break;
}

//
// Private
//
Expand Down Expand Up @@ -7207,27 +7228,55 @@ QuicConnParamGet(
}

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;

case QUIC_PARAM_CONN_DSCP:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should GetParam return the last-set DSCP value, or the most recently received DSCP value?
Or should getting the received DSCP value be a separate, get-only param?


if (*BufferLength < sizeof(Connection->DSCP)) {
Status = QUIC_STATUS_BUFFER_TOO_SMALL;
*BufferLength = sizeof(Connection->DSCP);
break;
}

if (Buffer == NULL) {
Status = QUIC_STATUS_INVALID_PARAMETER;
break;
}

CxPlatCopyMemory(
Buffer,
&Connection->DSCP,
sizeof(Connection->DSCP));

*BufferLength = sizeof(Connection->DSCP);
Status = QUIC_STATUS_SUCCESS;
break;

Expand Down
6 changes: 6 additions & 0 deletions src/core/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,12 @@ typedef struct QUIC_CONNECTION {
//
uint8_t PeerReorderingThreshold;

//
// DSCP value to set on all sends from this connection.
// Default value of 0.
//
uint8_t DSCP;

//
// The ACK frequency sequence number we are currently using to send.
//
Expand Down
3 changes: 2 additions & 1 deletion src/core/packet_builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ QuicPacketBuilderPrepare(
DatagramSize),
Builder->EcnEctSet ? CXPLAT_ECN_ECT_0 : CXPLAT_ECN_NON_ECT,
Builder->Connection->Registration->ExecProfile == QUIC_EXECUTION_PROFILE_TYPE_MAX_THROUGHPUT ?
CXPLAT_SEND_FLAGS_MAX_THROUGHPUT : CXPLAT_SEND_FLAGS_NONE
CXPLAT_SEND_FLAGS_MAX_THROUGHPUT : CXPLAT_SEND_FLAGS_NONE,
Connection->DSCP
};
Builder->SendData =
CxPlatSendDataAlloc(Builder->Path->Binding->Socket, &SendConfig);
Expand Down
3 changes: 3 additions & 0 deletions src/cs/lib/msquic_generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3447,6 +3447,9 @@ internal static unsafe partial class MsQuic
[NativeTypeName("#define QUIC_PARAM_CONN_ORIG_DEST_CID 0x05000018")]
internal const uint QUIC_PARAM_CONN_ORIG_DEST_CID = 0x05000018;

[NativeTypeName("#define QUIC_PARAM_CONN_DSCP 0x50000019")]
internal const uint QUIC_PARAM_CONN_DSCP = 0x50000019;

[NativeTypeName("#define QUIC_PARAM_TLS_HANDSHAKE_INFO 0x06000000")]
internal const uint QUIC_PARAM_TLS_HANDSHAKE_INFO = 0x06000000;

Expand Down
36 changes: 36 additions & 0 deletions src/generated/linux/datapath_winkernel.c.clog.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,42 @@ tracepoint(CLOG_DATAPATH_WINKERNEL_C, DatapathQueryRecvMaxCoalescedSizeFailedAsy



/*----------------------------------------------------------
// Decoder Ring for DatapathTestSetIpv6TrafficClassFailed
// [data] Test setting IPV6_TCLASS failed, 0x%x
// QuicTraceLogWarning(
DatapathTestSetIpv6TrafficClassFailed,
"[data] Test setting IPV6_TCLASS failed, 0x%x",
Status);
// arg2 = arg2 = Status = arg2
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_DatapathTestSetIpv6TrafficClassFailed
#define _clog_3_ARGS_TRACE_DatapathTestSetIpv6TrafficClassFailed(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_WINKERNEL_C, DatapathTestSetIpv6TrafficClassFailed , arg2);\

#endif




/*----------------------------------------------------------
// Decoder Ring for DatapathTestSetIpv6TrafficClassFailedAsync
// [data] Test setting IPV6_TCLASS failed (async), 0x%x
// QuicTraceLogWarning(
DatapathTestSetIpv6TrafficClassFailedAsync,
"[data] Test setting IPV6_TCLASS failed (async), 0x%x",
Status);
// arg2 = arg2 = Status = arg2
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_DatapathTestSetIpv6TrafficClassFailedAsync
#define _clog_3_ARGS_TRACE_DatapathTestSetIpv6TrafficClassFailedAsync(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_WINKERNEL_C, DatapathTestSetIpv6TrafficClassFailedAsync , arg2);\

#endif




/*----------------------------------------------------------
// Decoder Ring for DatapathDropEmptyMdl
// [%p] Dropping datagram with empty mdl.
Expand Down
38 changes: 38 additions & 0 deletions src/generated/linux/datapath_winkernel.c.clog.h.lttng.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,44 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_WINKERNEL_C, DatapathQueryRecvMaxCoalescedSizeFai



/*----------------------------------------------------------
// Decoder Ring for DatapathTestSetIpv6TrafficClassFailed
// [data] Test setting IPV6_TCLASS failed, 0x%x
// QuicTraceLogWarning(
DatapathTestSetIpv6TrafficClassFailed,
"[data] Test setting IPV6_TCLASS failed, 0x%x",
Status);
// arg2 = arg2 = Status = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_WINKERNEL_C, DatapathTestSetIpv6TrafficClassFailed,
TP_ARGS(
unsigned int, arg2),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
)
)



/*----------------------------------------------------------
// Decoder Ring for DatapathTestSetIpv6TrafficClassFailedAsync
// [data] Test setting IPV6_TCLASS failed (async), 0x%x
// QuicTraceLogWarning(
DatapathTestSetIpv6TrafficClassFailedAsync,
"[data] Test setting IPV6_TCLASS failed (async), 0x%x",
Status);
// arg2 = arg2 = Status = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_WINKERNEL_C, DatapathTestSetIpv6TrafficClassFailedAsync,
TP_ARGS(
unsigned int, arg2),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
)
)



/*----------------------------------------------------------
// Decoder Ring for DatapathDropEmptyMdl
// [%p] Dropping datagram with empty mdl.
Expand Down
36 changes: 36 additions & 0 deletions src/generated/linux/datapath_winuser.c.clog.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,42 @@ tracepoint(CLOG_DATAPATH_WINUSER_C, DatapathQueryRecvMaxCoalescedSizeFailed , ar



/*----------------------------------------------------------
// Decoder Ring for DatapathOpenUdpv6SocketFailed
// [data] UDPv6 helper socket failed to open, 0x%x
// QuicTraceLogWarning(
DatapathOpenUdpv6SocketFailed,
"[data] UDPv6 helper socket failed to open, 0x%x",
WsaError);
// arg2 = arg2 = WsaError = arg2
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_DatapathOpenUdpv6SocketFailed
#define _clog_3_ARGS_TRACE_DatapathOpenUdpv6SocketFailed(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_WINUSER_C, DatapathOpenUdpv6SocketFailed , arg2);\

#endif




/*----------------------------------------------------------
// Decoder Ring for DatapathTestSetIpv6TrafficClassFailed
// [data] Test setting IPV6_TCLASS failed, 0x%x
// QuicTraceLogWarning(
DatapathTestSetIpv6TrafficClassFailed,
"[data] Test setting IPV6_TCLASS failed, 0x%x",
WsaError);
// arg2 = arg2 = WsaError = arg2
----------------------------------------------------------*/
#ifndef _clog_3_ARGS_TRACE_DatapathTestSetIpv6TrafficClassFailed
#define _clog_3_ARGS_TRACE_DatapathTestSetIpv6TrafficClassFailed(uniqueId, encoded_arg_string, arg2)\
tracepoint(CLOG_DATAPATH_WINUSER_C, DatapathTestSetIpv6TrafficClassFailed , arg2);\

#endif




/*----------------------------------------------------------
// Decoder Ring for DatapathRecvEmpty
// [data][%p] Dropping datagram with empty payload.
Expand Down
38 changes: 38 additions & 0 deletions src/generated/linux/datapath_winuser.c.clog.h.lttng.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,44 @@ TRACEPOINT_EVENT(CLOG_DATAPATH_WINUSER_C, DatapathQueryRecvMaxCoalescedSizeFaile



/*----------------------------------------------------------
// Decoder Ring for DatapathOpenUdpv6SocketFailed
// [data] UDPv6 helper socket failed to open, 0x%x
// QuicTraceLogWarning(
DatapathOpenUdpv6SocketFailed,
"[data] UDPv6 helper socket failed to open, 0x%x",
WsaError);
// arg2 = arg2 = WsaError = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_WINUSER_C, DatapathOpenUdpv6SocketFailed,
TP_ARGS(
unsigned int, arg2),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
)
)



/*----------------------------------------------------------
// Decoder Ring for DatapathTestSetIpv6TrafficClassFailed
// [data] Test setting IPV6_TCLASS failed, 0x%x
// QuicTraceLogWarning(
DatapathTestSetIpv6TrafficClassFailed,
"[data] Test setting IPV6_TCLASS failed, 0x%x",
WsaError);
// arg2 = arg2 = WsaError = arg2
----------------------------------------------------------*/
TRACEPOINT_EVENT(CLOG_DATAPATH_WINUSER_C, DatapathTestSetIpv6TrafficClassFailed,
TP_ARGS(
unsigned int, arg2),
TP_FIELDS(
ctf_integer(unsigned int, arg2, arg2)
)
)



/*----------------------------------------------------------
// Decoder Ring for DatapathRecvEmpty
// [data][%p] Dropping datagram with empty payload.
Expand Down
1 change: 1 addition & 0 deletions src/inc/msquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@ typedef struct QUIC_SCHANNEL_CREDENTIAL_ATTRIBUTE_W {
#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[]
#define QUIC_PARAM_CONN_DSCP 0x50000019 // uint8_t

//
// Parameters for TLS.
Expand Down
13 changes: 13 additions & 0 deletions src/inc/quic_datapath.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ typedef enum CXPLAT_ECN_TYPE {
//
#define CXPLAT_ECN_FROM_TOS(ToS) (CXPLAT_ECN_TYPE)((ToS) & 0x3)

//
// Helper to get the DSCP value from the Type of Service field of received data.
//
#define CXPLAT_DSCP_FROM_TOS(ToS) (uint8_t)((ToS) >> 2)

//
// Define the maximum type of service value allowed.
// Note: this is without the ECN bits included
//
#define CXPLAT_MAX_DSCP 63

//
// The maximum IP MTU this implementation supports for QUIC.
//
Expand Down Expand Up @@ -444,6 +455,7 @@ CxPlatDataPathUpdateConfig(
#define CXPLAT_DATAPATH_FEATURE_TCP 0x0020
#define CXPLAT_DATAPATH_FEATURE_RAW 0x0040
#define CXPLAT_DATAPATH_FEATURE_TTL 0x0080
#define CXPLAT_DATAPATH_FEATURE_DSCP 0x0100

//
// Queries the currently supported features of the datapath.
Expand Down Expand Up @@ -675,6 +687,7 @@ typedef struct CXPLAT_SEND_CONFIG {
uint16_t MaxPacketSize;
uint8_t ECN; // CXPLAT_ECN_TYPE
uint8_t Flags; // CXPLAT_SEND_FLAGS
uint8_t DSCP;
} CXPLAT_SEND_CONFIG;

//
Expand Down
Loading
Loading