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 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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_TYPE_OF_SERVICE` <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
58 changes: 58 additions & 0 deletions src/core/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1837,6 +1837,7 @@ QuicConnStart(
UdpConfig.Flags = Connection->State.ShareBinding ? CXPLAT_SOCKET_FLAG_SHARE : 0;
UdpConfig.InterfaceIndex = Connection->State.LocalInterfaceSet ? (uint32_t)Path->Route.LocalAddress.Ipv6.sin6_scope_id : 0, // NOLINT(google-readability-casting)
UdpConfig.PartitionIndex = QuicPartitionIdGetIndex(Connection->PartitionID);
UdpConfig.TypeOfService = Connection->TypeOfService;
#ifdef QUIC_COMPARTMENT_ID
UdpConfig.CompartmentId = Configuration->CompartmentId;
#endif
Expand Down Expand Up @@ -6218,6 +6219,7 @@ QuicConnParamSet(
UdpConfig.RemoteAddress = &Connection->Paths[0].Route.RemoteAddress;
UdpConfig.Flags = Connection->State.ShareBinding ? CXPLAT_SOCKET_FLAG_SHARE : 0;
UdpConfig.InterfaceIndex = 0;
UdpConfig.TypeOfService = Connection->TypeOfService;
#ifdef QUIC_COMPARTMENT_ID
UdpConfig.CompartmentId = Connection->Configuration->CompartmentId;
#endif
Expand Down Expand Up @@ -6623,6 +6625,34 @@ QuicConnParamSet(
return QUIC_STATUS_SUCCESS;
}

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

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

if (TypeOfService > CXPLAT_MAX_TYPE_OF_SERVICE) {
Status = QUIC_STATUS_INVALID_PARAMETER;
break;
}

Connection->TypeOfService = TypeOfService;

if (Connection->State.Started) {
Status =
CxPlatSocketSetTypeOfService(
Connection->Paths[0].Binding->Socket,
TypeOfService);
} else {
Status = QUIC_STATUS_SUCCESS;
}
break;
}

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

case QUIC_PARAM_CONN_ORIG_DEST_CID:

Copy link
Member

Choose a reason for hiding this comment

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

nit: don't modify code that's not relevant to this PR?

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_TYPE_OF_SERVICE:

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

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

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

*BufferLength = sizeof(Connection->TypeOfService);
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;

//
// Type of Service value to set on the socket when the connection is started.
// Default value of 0.
//
uint8_t TypeOfService;

//
// The ACK frequency sequence number we are currently using to send.
//
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_TYPE_OF_SERVICE 0x50000019")]
internal const uint QUIC_PARAM_CONN_TYPE_OF_SERVICE = 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_TYPE_OF_SERVICE 0x50000019 // uint8_t

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

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

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

//
// Queries the currently supported features of the datapath.
Expand Down Expand Up @@ -544,6 +551,7 @@ typedef struct CXPLAT_UDP_CONFIG {
#ifdef QUIC_OWNING_PROCESS
QUIC_PROCESS OwningProcess; // Kernel client-only
#endif
uint8_t TypeOfService; // Default 0. Optional.

// used for RAW datapath
uint8_t CibirIdLength; // CIBIR ID length. Value of 0 indicates CIBIR isn't used
Expand Down Expand Up @@ -646,6 +654,17 @@ CxPlatSocketGetRemoteAddress(
_Out_ QUIC_ADDR* Address
);

//
// Sets TypeOfService on the socket. May fail if insufficient privileges exist
// to set the desired value on the socket.
//
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatSocketSetTypeOfService(
_In_ CXPLAT_SOCKET* Socket,
_In_ uint8_t TypeOfService
);

//
// Queries a raw socket availability.
//
Expand Down
Loading
Loading