Skip to content

Commit

Permalink
Switch to Ancillary Data
Browse files Browse the repository at this point in the history
  • Loading branch information
anrossi committed Jan 25, 2025
1 parent 35949c1 commit 6bc1acc
Show file tree
Hide file tree
Showing 19 changed files with 89 additions and 391 deletions.
2 changes: 1 addition & 1 deletion docs/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +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_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
33 changes: 12 additions & 21 deletions src/core/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1837,7 +1837,6 @@ 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 @@ -6219,7 +6218,6 @@ 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 @@ -6625,31 +6623,24 @@ QuicConnParamSet(
return QUIC_STATUS_SUCCESS;
}

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

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

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

Connection->TypeOfService = TypeOfService;
Connection->DSCP = DSCP;

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

Expand Down Expand Up @@ -7267,11 +7258,11 @@ QuicConnParamGet(
Status = QUIC_STATUS_SUCCESS;
break;

case QUIC_PARAM_CONN_TYPE_OF_SERVICE:
case QUIC_PARAM_CONN_DSCP:

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

Expand All @@ -7282,10 +7273,10 @@ QuicConnParamGet(

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

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

Expand Down
4 changes: 2 additions & 2 deletions src/core/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,10 +463,10 @@ typedef struct QUIC_CONNECTION {
uint8_t PeerReorderingThreshold;

//
// Type of Service value to set on the socket when the connection is started.
// DSCP value to set on all sends from this connection.
// Default value of 0.
//
uint8_t TypeOfService;
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
4 changes: 2 additions & 2 deletions src/cs/lib/msquic_generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3447,8 +3447,8 @@ 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_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
2 changes: 1 addition & 1 deletion src/inc/msquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +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
#define QUIC_PARAM_CONN_DSCP 0x50000019 // uint8_t

//
// Parameters for TLS.
Expand Down
22 changes: 8 additions & 14 deletions src/inc/quic_datapath.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,16 @@ 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_TYPE_OF_SERVICE 63
#define CXPLAT_MAX_DSCP 63

//
// The maximum IP MTU this implementation supports for QUIC.
Expand Down Expand Up @@ -450,7 +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_TYPE_OF_SERVICE 0x0100
#define CXPLAT_DATAPATH_FEATURE_DSCP 0x0100

//
// Queries the currently supported features of the datapath.
Expand Down Expand Up @@ -551,7 +556,6 @@ 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 @@ -654,17 +658,6 @@ 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 Expand Up @@ -694,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
99 changes: 3 additions & 96 deletions src/platform/datapath_epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ CxPlatDataPathCalculateFeatureSupport(

Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TCP;
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TTL;
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TYPE_OF_SERVICE;
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_DSCP;
}

void
Expand Down Expand Up @@ -888,46 +888,6 @@ CxPlatSocketContextInitialize(
goto Exit;
}

if (Config->TypeOfService != 0) {
Option = Config->TypeOfService;
Result =
setsockopt(
SocketContext->SocketFd,
IPPROTO_IP,
IP_TOS,
(const void*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
Status = errno;
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Binding,
Status,
"setsockopt(IP_TOS) failed");
goto Exit;
}

Option = Config->TypeOfService;
Result =
setsockopt(
SocketContext->SocketFd,
IPPROTO_IPV6,
IPV6_TCLASS,
(const void*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
Status = errno;
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Binding,
Status,
"setsockopt(IPV6_TCLASS) failed");
goto Exit;
}
}

#ifdef UDP_GRO
if (SocketContext->DatapathPartition->Datapath->Features & CXPLAT_DATAPATH_FEATURE_RECV_COALESCING) {
Option = TRUE;
Expand Down Expand Up @@ -2304,6 +2264,7 @@ SendDataAlloc(
SendData->AlreadySentCount = 0;
SendData->ControlBufferLength = 0;
SendData->ECN = Config->ECN;
SendData->DSCP = Config->DSCP;
SendData->Flags = Config->Flags;
SendData->OnConnectedSocket = Socket->Connected;
SendData->SegmentationSupported =
Expand Down Expand Up @@ -2495,60 +2456,6 @@ SocketSend(
}
}

_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
SocketSetTypeOfService(
_In_ CXPLAT_SOCKET* Socket,
_In_ uint8_t TypeOfService
)
{
const uint16_t SocketCount = Socket->NumPerProcessorSockets ? (uint16_t)CxPlatProcCount() : 1;
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
for (uint16_t i = 0; i < SocketCount; i++) {
CXPLAT_SOCKET_CONTEXT* SocketContext = &Socket->SocketContexts[i];
int Option = TypeOfService;
int if (Config->TypeOfService != 0) {
Option = Config->TypeOfService;
Result =
setsockopt(
SocketContext->SocketFd,
IPPROTO_IP,
IP_TOS,
(const void*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
Status = errno;
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Binding,
Status,
"setsockopt(IP_TOS) failed");
break;
}

Option = TypeOfService;
Result =
setsockopt(
SocketContext->SocketFd,
IPPROTO_IPV6,
IPV6_TCLASS,
(const void*)&Option,
sizeof(Option));
if (Result == SOCKET_ERROR) {
Status = errno;
QuicTraceEvent(
DatapathErrorStatus,
"[data][%p] ERROR, %u, %s.",
Binding,
Status,
"setsockopt(IPV6_TCLASS) failed");
break;
}
}
}
return Status;
}
//
// This is defined and used instead of CMSG_NXTHDR because (1) we've already
// done the work to ensure the necessary space is available and (2) CMSG_NXTHDR
Expand All @@ -2572,7 +2479,7 @@ CxPlatSendDataPopulateAncillaryData(
CMsg->cmsg_level = SendData->LocalAddress.Ip.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
CMsg->cmsg_type = SendData->LocalAddress.Ip.sa_family == AF_INET ? IP_TOS : IPV6_TCLASS;
CMsg->cmsg_len = CMSG_LEN(sizeof(int));
*(int*)CMSG_DATA(CMsg) = SendData->ECN;
*(int*)CMSG_DATA(CMsg) = SendData->ECN | (SendData->DSCP << 2);

if (!SendData->OnConnectedSocket) {
if (SendData->LocalAddress.Ip.sa_family == AF_INET) {
Expand Down
3 changes: 2 additions & 1 deletion src/platform/datapath_kqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,7 @@ CxPlatSendDataAlloc(
CxPlatZeroMemory(SendData, sizeof(*SendData));
SendData->Owner = SocketContext->DatapathPartition;
SendData->ECN = Config->ECN;
SendData->DSCP = Config->DSCP;
SendData->SegmentSize =
(Socket->Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_SEGMENTATION)
? Config->MaxPacketSize : 0;
Expand Down Expand Up @@ -1981,7 +1982,7 @@ CxPlatSocketSendInternal(
CMsg->cmsg_level = RemoteAddress->Ip.sa_family == QUIC_ADDRESS_FAMILY_INET ? IPPROTO_IP : IPPROTO_IPV6;
CMsg->cmsg_type = RemoteAddress->Ip.sa_family == QUIC_ADDRESS_FAMILY_INET ? IP_TOS : IPV6_TCLASS;
CMsg->cmsg_len = CMSG_LEN(sizeof(int));
*(int *)CMSG_DATA(CMsg) = SendData->ECN;
*(int *)CMSG_DATA(CMsg) = SendData->ECN | (SendData->DSCP << 2);

if (!SocketContext->Binding->Connected) {
Mhdr.msg_name = &MappedRemoteAddress;
Expand Down
14 changes: 1 addition & 13 deletions src/platform/datapath_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ RawSocketSend(
const CXPLAT_INTERFACE* Interface = CxPlatDpRawGetInterfaceFromQueue(Route->Queue);

CxPlatFramingWriteHeaders(
Socket, Route, &SendData->Buffer, SendData->ECN, Socket->TypeOfService,
Socket, Route, &SendData->Buffer, SendData->ECN, SendData->DSCP,
Interface->OffloadStatus.Transmit.NetworkLayerXsum,
Interface->OffloadStatus.Transmit.TransportLayerXsum,
Route->TcpState.SequenceNumber,
Expand All @@ -380,15 +380,3 @@ RawSocketSend(
CxPlatDpRawTxEnqueue(SendData);
return QUIC_STATUS_SUCCESS;
}


_IRQL_requires_max_(DISPATCH_LEVEL)
QUIC_STATUS
RawSocketSetTypeOfService(
_In_ CXPLAT_SOCKET_RAW* Socket,
_In_ uint8_t TypeOfService
)
{
Socket->TypeOfService = TypeOfService;
return QUIC_STATUS_SUCCESS;
}
3 changes: 1 addition & 2 deletions src/platform/datapath_raw.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ typedef struct CXPLAT_SOCKET_RAW {
SOCKET AuxSocket;
BOOLEAN Wildcard; // Using a wildcard local address. Optimization
// to avoid always reading LocalAddress.
uint8_t TypeOfService; // IP TypeOfService/IPv6 Traffic Class value. Default 0.
uint8_t CibirIdLength; // CIBIR ID length. Value of 0 indicates CIBIR isn't used
uint8_t CibirIdOffsetSrc; // CIBIR ID offset in source CID
uint8_t CibirIdOffsetDst; // CIBIR ID offset in destination CID
Expand Down Expand Up @@ -378,7 +377,7 @@ CxPlatFramingWriteHeaders(
_In_ const CXPLAT_ROUTE* Route,
_Inout_ QUIC_BUFFER* Buffer,
_In_ CXPLAT_ECN_TYPE ECN,
_In_ uint8_t TypeOfService,
_In_ uint8_t DSCP,
_In_ BOOLEAN SkipNetworkLayerXsum,
_In_ BOOLEAN SkipTransportLayerXsum,
_In_ uint32_t TcpSeqNum,
Expand Down
1 change: 0 additions & 1 deletion src/platform/datapath_raw_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ RawSocketCreateUdp(
NewSocket->CibirIdLength = Config->CibirIdLength;
NewSocket->CibirIdOffsetSrc = Config->CibirIdOffsetSrc;
NewSocket->CibirIdOffsetDst = Config->CibirIdOffsetDst;
NewSocket->TypeOfService = Config->TypeOfService;
NewSocket->AuxSocket = INVALID_SOCKET;
NewSocket->UseTcp = Raw->UseTcp;
if (Config->CibirIdLength) {
Expand Down
Loading

0 comments on commit 6bc1acc

Please sign in to comment.