diff --git a/src/platform/datapath_raw.c b/src/platform/datapath_raw.c
index f9b827eafd..0750b17fae 100644
--- a/src/platform/datapath_raw.c
+++ b/src/platform/datapath_raw.c
@@ -189,7 +189,7 @@ RawSocketDelete(
{
CxPlatDpRawPlumbRulesOnSocket(Socket, FALSE);
CxPlatRemoveSocket(&Socket->RawDatapath->SocketPool, Socket);
- CxPlatRundownReleaseAndWait(&Socket->Rundown);
+ CxPlatRundownReleaseAndWait(&Socket->RawRundown);
if (Socket->PausedTcpSend) {
CxPlatDpRawTxFree(Socket->PausedTcpSend);
}
@@ -269,7 +269,7 @@ CxPlatDpRawRxEthernet(
CxPlatDpRawRxFree(PacketChain);
}
- CxPlatRundownRelease(&Socket->Rundown);
+ CxPlatRundownRelease(&Socket->RawRundown);
} else {
CxPlatDpRawRxFree(PacketChain);
}
diff --git a/src/platform/datapath_raw.h b/src/platform/datapath_raw.h
index c23d63d449..c77f42ced9 100644
--- a/src/platform/datapath_raw.h
+++ b/src/platform/datapath_raw.h
@@ -260,7 +260,7 @@ CxPlatDpRawTxEnqueue(
typedef struct CXPLAT_SOCKET_RAW {
CXPLAT_HASHTABLE_ENTRY Entry;
- CXPLAT_RUNDOWN_REF Rundown;
+ CXPLAT_RUNDOWN_REF RawRundown;
CXPLAT_DATAPATH_RAW* RawDatapath;
SOCKET AuxSocket;
BOOLEAN Wildcard; // Using a wildcard local address. Optimization
@@ -392,43 +392,6 @@ CxPlatFramingWriteHeaders(
#pragma pack(push)
#pragma pack(1)
-typedef struct ETHERNET_HEADER {
- uint8_t Destination[6];
- uint8_t Source[6];
- uint16_t Type;
- uint8_t Data[0];
-} ETHERNET_HEADER;
-
-typedef struct IPV4_HEADER {
- uint8_t VersionAndHeaderLength;
- union {
- uint8_t TypeOfServiceAndEcnField;
- struct {
- uint8_t EcnField : 2;
- uint8_t TypeOfService : 6;
- };
- };
- uint16_t TotalLength;
- uint16_t Identification;
- uint16_t FlagsAndFragmentOffset;
- uint8_t TimeToLive;
- uint8_t Protocol;
- uint16_t HeaderChecksum;
- uint8_t Source[4];
- uint8_t Destination[4];
- uint8_t Data[0];
-} IPV4_HEADER;
-
-typedef struct IPV6_HEADER {
- uint32_t VersionClassEcnFlow;
- uint16_t PayloadLength;
- uint8_t NextHeader;
- uint8_t HopLimit;
- uint8_t Source[16];
- uint8_t Destination[16];
- uint8_t Data[0];
-} IPV6_HEADER;
-
typedef struct IPV6_EXTENSION {
uint8_t NextHeader;
uint8_t Length;
@@ -474,11 +437,52 @@ typedef struct TCP_HEADER {
#define TH_CWR 0x80
#define IPV4_VERSION 4
-#define IPV6_VERSION 6
#define IPV4_VERSION_BYTE (IPV4_VERSION << 4)
-#define IPV4_DEFAULT_VERHLEN ((IPV4_VERSION_BYTE) | (sizeof(IPV4_HEADER) / sizeof(uint32_t)))
#define IP_DEFAULT_HOP_LIMIT 128
+#ifndef _KERNEL_MODE
+typedef struct ETHERNET_HEADER {
+ uint8_t Destination[6];
+ uint8_t Source[6];
+ uint16_t Type;
+ uint8_t Data[0];
+} ETHERNET_HEADER;
+
+typedef struct IPV4_HEADER {
+ uint8_t VersionAndHeaderLength;
+ union {
+ uint8_t TypeOfServiceAndEcnField;
+ struct {
+ uint8_t EcnField : 2;
+ uint8_t TypeOfService : 6;
+ };
+ };
+ uint16_t TotalLength;
+ uint16_t Identification;
+ uint16_t FlagsAndFragmentOffset;
+ uint8_t TimeToLive;
+ uint8_t Protocol;
+ uint16_t HeaderChecksum;
+ uint8_t Source[4];
+ uint8_t Destination[4];
+ uint8_t Data[0];
+} IPV4_HEADER;
+
+typedef struct IPV6_HEADER {
+ uint32_t VersionClassEcnFlow;
+ uint16_t PayloadLength;
+ uint8_t NextHeader;
+ uint8_t HopLimit;
+ uint8_t Source[16];
+ uint8_t Destination[16];
+ uint8_t Data[0];
+} IPV6_HEADER;
+
+#define IPV6_VERSION 6
+#define IPV4_DEFAULT_VERHLEN ((IPV4_VERSION_BYTE) | (sizeof(IPV4_HEADER) / sizeof(uint32_t)))
+
#define ETHERNET_TYPE_IPV4 0x0008
#define ETHERNET_TYPE_IPV6 0xdd86
+
+#endif
\ No newline at end of file
diff --git a/src/platform/datapath_raw_linux.c b/src/platform/datapath_raw_linux.c
index 06c712c6cc..02fbf05dd4 100644
--- a/src/platform/datapath_raw_linux.c
+++ b/src/platform/datapath_raw_linux.c
@@ -112,7 +112,7 @@ RawSocketCreateUdp(
{
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
- CxPlatRundownInitialize(&NewSocket->Rundown);
+ CxPlatRundownInitialize(&NewSocket->RawRundown);
NewSocket->RawDatapath = Raw;
NewSocket->CibirIdLength = Config->CibirIdLength;
NewSocket->CibirIdOffsetSrc = Config->CibirIdOffsetSrc;
@@ -169,7 +169,7 @@ RawSocketCreateUdp(
if (QUIC_FAILED(Status)) {
if (NewSocket != NULL) {
- CxPlatRundownUninitialize(&NewSocket->Rundown);
+ CxPlatRundownUninitialize(&NewSocket->RawRundown);
CxPlatZeroMemory(NewSocket, sizeof(CXPLAT_SOCKET_RAW) - sizeof(CXPLAT_SOCKET));
NewSocket = NULL;
}
diff --git a/src/platform/datapath_raw_socket.c b/src/platform/datapath_raw_socket.c
index e0a31c07da..7e33b932c9 100644
--- a/src/platform/datapath_raw_socket.c
+++ b/src/platform/datapath_raw_socket.c
@@ -62,7 +62,7 @@ CxPlatGetSocket(
while (Entry != NULL) {
CXPLAT_SOCKET_RAW* Temp = CXPLAT_CONTAINING_RECORD(Entry, CXPLAT_SOCKET_RAW, Entry);
if (CxPlatSocketCompare(Temp, LocalAddress, RemoteAddress)) {
- if (CxPlatRundownAcquire(&Temp->Rundown)) {
+ if (CxPlatRundownAcquire(&Temp->RawRundown)) {
Socket = Temp;
}
break;
diff --git a/src/platform/datapath_raw_win.c b/src/platform/datapath_raw_win.c
index c5aa8b18bb..d3f01926cd 100644
--- a/src/platform/datapath_raw_win.c
+++ b/src/platform/datapath_raw_win.c
@@ -113,7 +113,7 @@ RawSocketCreateUdp(
CXPLAT_DBG_ASSERT(Socket != NULL);
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
- CxPlatRundownInitialize(&Socket->Rundown);
+ CxPlatRundownInitialize(&Socket->RawRundown);
Socket->RawDatapath = Raw;
Socket->CibirIdLength = Config->CibirIdLength;
Socket->CibirIdOffsetSrc = Config->CibirIdOffsetSrc;
@@ -167,7 +167,7 @@ RawSocketCreateUdp(
if (QUIC_FAILED(Status)) {
if (Socket != NULL) {
- CxPlatRundownUninitialize(&Socket->Rundown);
+ CxPlatRundownUninitialize(&Socket->RawRundown);
CxPlatZeroMemory(Socket, sizeof(CXPLAT_SOCKET_RAW) - sizeof(CXPLAT_SOCKET));
Socket = NULL;
}
diff --git a/src/platform/datapath_win.c b/src/platform/datapath_win.c
index 6cab97b861..6512dc98ab 100644
--- a/src/platform/datapath_win.c
+++ b/src/platform/datapath_win.c
@@ -15,334 +15,6 @@
#include "datapath_winuser.c.clog.h"
#endif
-_IRQL_requires_max_(PASSIVE_LEVEL)
-_Success_(QUIC_SUCCEEDED(return))
-QUIC_STATUS
-CxPlatDataPathGetLocalAddresses(
- _In_ CXPLAT_DATAPATH* Datapath,
- _Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
- CXPLAT_ADAPTER_ADDRESS** Addresses,
- _Out_ uint32_t* AddressesCount
- )
-{
- const ULONG Flags =
- GAA_FLAG_INCLUDE_ALL_INTERFACES |
- GAA_FLAG_SKIP_ANYCAST |
- GAA_FLAG_SKIP_MULTICAST |
- GAA_FLAG_SKIP_DNS_SERVER |
- GAA_FLAG_SKIP_FRIENDLY_NAME |
- GAA_FLAG_SKIP_DNS_INFO;
-
- UNREFERENCED_PARAMETER(Datapath);
-
- ULONG AdapterAddressesSize = 0;
- PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
- uint32_t Index = 0;
-
- QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
- ULONG Error;
- do {
- Error =
- GetAdaptersAddresses(
- AF_UNSPEC,
- Flags,
- NULL,
- AdapterAddresses,
- &AdapterAddressesSize);
- if (Error == ERROR_BUFFER_OVERFLOW) {
- if (AdapterAddresses) {
- CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
- }
- AdapterAddresses = CXPLAT_ALLOC_NONPAGED(AdapterAddressesSize, QUIC_POOL_DATAPATH_ADDRESSES);
- if (!AdapterAddresses) {
- Error = ERROR_NOT_ENOUGH_MEMORY;
- QuicTraceEvent(
- AllocFailure,
- "Allocation of '%s' failed. (%llu bytes)",
- "PIP_ADAPTER_ADDRESSES",
- AdapterAddressesSize);
- }
- }
- } while (Error == ERROR_BUFFER_OVERFLOW);
-
- if (Error != ERROR_SUCCESS) {
- QuicTraceEvent(
- LibraryErrorStatus,
- "[ lib] ERROR, %u, %s.",
- Error,
- "GetAdaptersAddresses");
- Status = HRESULT_FROM_WIN32(Error);
- goto Exit;
- }
-
- for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
- for (PIP_ADAPTER_UNICAST_ADDRESS_LH Iter2 = Iter->FirstUnicastAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
- Index++;
- }
- }
-
- if (Index == 0) {
- QuicTraceEvent(
- LibraryError,
- "[ lib] ERROR, %s.",
- "No local unicast addresses found");
- Status = QUIC_STATUS_NOT_FOUND;
- goto Exit;
- }
-
- *Addresses = CXPLAT_ALLOC_NONPAGED(Index * sizeof(CXPLAT_ADAPTER_ADDRESS), QUIC_POOL_DATAPATH_ADDRESSES);
- if (*Addresses == NULL) {
- Status = QUIC_STATUS_OUT_OF_MEMORY;
- QuicTraceEvent(
- AllocFailure,
- "Allocation of '%s' failed. (%llu bytes)",
- "Addresses",
- Index * sizeof(CXPLAT_ADAPTER_ADDRESS));
- goto Exit;
- }
-
- CxPlatZeroMemory(*Addresses, Index * sizeof(CXPLAT_ADAPTER_ADDRESS));
- *AddressesCount = Index;
- Index = 0;
-
- for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
- for (PIP_ADAPTER_UNICAST_ADDRESS_LH Iter2 = Iter->FirstUnicastAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
- CxPlatCopyMemory(
- &(*Addresses)[Index].Address,
- Iter2->Address.lpSockaddr,
- sizeof(QUIC_ADDR));
- (*Addresses)[Index].InterfaceIndex =
- Iter2->Address.lpSockaddr->sa_family == AF_INET ?
- (uint32_t)Iter->IfIndex : (uint32_t)Iter->Ipv6IfIndex;
- (*Addresses)[Index].InterfaceType = (uint16_t)Iter->IfType;
- (*Addresses)[Index].OperationStatus = (CXPLAT_OPERATION_STATUS)Iter->OperStatus;
- Index++;
- }
- }
-
-Exit:
-
- if (AdapterAddresses) {
- CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
- }
-
- return Status;
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-_Success_(QUIC_SUCCEEDED(return))
-QUIC_STATUS
-CxPlatDataPathGetGatewayAddresses(
- _In_ CXPLAT_DATAPATH* Datapath,
- _Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
- QUIC_ADDR** GatewayAddresses,
- _Out_ uint32_t* GatewayAddressesCount
- )
-{
- const ULONG Flags =
- GAA_FLAG_INCLUDE_GATEWAYS |
- GAA_FLAG_INCLUDE_ALL_INTERFACES |
- GAA_FLAG_SKIP_DNS_SERVER |
- GAA_FLAG_SKIP_MULTICAST;
-
- UNREFERENCED_PARAMETER(Datapath);
-
- ULONG AdapterAddressesSize = 0;
- PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
- uint32_t Index = 0;
-
- QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
- ULONG Error;
- do {
- Error =
- GetAdaptersAddresses(
- AF_UNSPEC,
- Flags,
- NULL,
- AdapterAddresses,
- &AdapterAddressesSize);
- if (Error == ERROR_BUFFER_OVERFLOW) {
- if (AdapterAddresses) {
- CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
- }
- AdapterAddresses = CXPLAT_ALLOC_NONPAGED(AdapterAddressesSize, QUIC_POOL_DATAPATH_ADDRESSES);
- if (!AdapterAddresses) {
- Error = ERROR_NOT_ENOUGH_MEMORY;
- QuicTraceEvent(
- AllocFailure,
- "Allocation of '%s' failed. (%llu bytes)",
- "PIP_ADAPTER_ADDRESSES",
- AdapterAddressesSize);
- }
- }
- } while (Error == ERROR_BUFFER_OVERFLOW);
-
- if (Error != ERROR_SUCCESS) {
- QuicTraceEvent(
- LibraryErrorStatus,
- "[ lib] ERROR, %u, %s.",
- Error,
- "GetAdaptersAddresses");
- Status = HRESULT_FROM_WIN32(Error);
- goto Exit;
- }
-
- for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
- for (PIP_ADAPTER_GATEWAY_ADDRESS_LH Iter2 = Iter->FirstGatewayAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
- Index++;
- }
- }
-
- if (Index == 0) {
- QuicTraceEvent(
- LibraryError,
- "[ lib] ERROR, %s.",
- "No gateway server addresses found");
- Status = QUIC_STATUS_NOT_FOUND;
- goto Exit;
- }
-
- *GatewayAddresses = CXPLAT_ALLOC_NONPAGED(Index * sizeof(QUIC_ADDR), QUIC_POOL_DATAPATH_ADDRESSES);
- if (*GatewayAddresses == NULL) {
- Status = QUIC_STATUS_OUT_OF_MEMORY;
- QuicTraceEvent(
- AllocFailure,
- "Allocation of '%s' failed. (%llu bytes)",
- "GatewayAddresses",
- Index * sizeof(QUIC_ADDR));
- goto Exit;
- }
-
- CxPlatZeroMemory(*GatewayAddresses, Index * sizeof(QUIC_ADDR));
- *GatewayAddressesCount = Index;
- Index = 0;
-
- for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
- for (PIP_ADAPTER_GATEWAY_ADDRESS_LH Iter2 = Iter->FirstGatewayAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
- CxPlatCopyMemory(
- &(*GatewayAddresses)[Index],
- Iter2->Address.lpSockaddr,
- sizeof(QUIC_ADDR));
- Index++;
- }
- }
-
-Exit:
-
- if (AdapterAddresses) {
- CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
- }
-
- return Status;
-}
-
-// private func
-void
-CxPlatDataPathPopulateTargetAddress(
- _In_ ADDRESS_FAMILY Family,
- _In_ ADDRINFOW *Ai,
- _Out_ SOCKADDR_INET* Address
- )
-{
- if (Ai->ai_addr->sa_family == QUIC_ADDRESS_FAMILY_INET6) {
- //
- // Is this a mapped ipv4 one?
- //
- PSOCKADDR_IN6 SockAddr6 = (PSOCKADDR_IN6)Ai->ai_addr;
-
- if (Family == QUIC_ADDRESS_FAMILY_UNSPEC && IN6ADDR_ISV4MAPPED(SockAddr6))
- {
- PSOCKADDR_IN SockAddr4 = &Address->Ipv4;
- //
- // Get the ipv4 address from the mapped address.
- //
- SockAddr4->sin_family = QUIC_ADDRESS_FAMILY_INET;
- SockAddr4->sin_addr =
- *(IN_ADDR UNALIGNED *)
- IN6_GET_ADDR_V4MAPPED(&SockAddr6->sin6_addr);
- SockAddr4->sin_port = SockAddr6->sin6_port;
- return;
- }
- }
-
- CxPlatCopyMemory(Address, Ai->ai_addr, Ai->ai_addrlen);
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-QUIC_STATUS
-CxPlatDataPathResolveAddress(
- _In_ CXPLAT_DATAPATH* Datapath,
- _In_z_ const char* HostName,
- _Inout_ QUIC_ADDR* Address
- )
-{
- QUIC_STATUS Status;
- PWSTR HostNameW = NULL;
- ADDRINFOW Hints = { 0 };
- ADDRINFOW *Ai;
-
- Status =
- CxPlatUtf8ToWideChar(
- HostName,
- QUIC_POOL_PLATFORM_TMP_ALLOC,
- &HostNameW);
- if (QUIC_FAILED(Status)) {
- QuicTraceEvent(
- LibraryErrorStatus,
- "[ lib] ERROR, %u, %s.",
- Status,
- "Convert HostName to unicode");
- goto Exit;
- }
-
- //
- // Prepopulate hint with input family. It might be unspecified.
- //
- Hints.ai_family = Address->si_family;
-
- //
- // Try numeric name first.
- //
- Hints.ai_flags = AI_NUMERICHOST;
- if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
- CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
- FreeAddrInfoW(Ai);
- Status = QUIC_STATUS_SUCCESS;
- goto Exit;
- }
-
- //
- // Try canonical host name.
- //
- Hints.ai_flags = AI_CANONNAME;
- if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
- CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
- FreeAddrInfoW(Ai);
- Status = QUIC_STATUS_SUCCESS;
- goto Exit;
- }
-
- QuicTraceEvent(
- LibraryError,
- "[ lib] ERROR, %s.",
- "Resolving hostname to IP");
- QuicTraceLogError(
- DatapathResolveHostNameFailed,
- "[%p] Couldn't resolve hostname '%s' to an IP address",
- Datapath,
- HostName);
- Status = HRESULT_FROM_WIN32(WSAHOST_NOT_FOUND);
-
-Exit:
-
- if (HostNameW != NULL) {
- CXPLAT_FREE(HostNameW, QUIC_POOL_PLATFORM_TMP_ALLOC);
- }
-
- return Status;
-}
-
-
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
CxPlatSocketUpdateQeo(
diff --git a/src/platform/datapath_winkernel.c b/src/platform/datapath_winkernel.c
index 111b72890e..03a458f64f 100644
--- a/src/platform/datapath_winkernel.c
+++ b/src/platform/datapath_winkernel.c
@@ -273,158 +273,6 @@ CxPlatDataPathSocketReceive(
_In_opt_ PWSK_DATAGRAM_INDICATION DataIndication
);
-typedef struct _WSK_DATAGRAM_SOCKET {
- const WSK_PROVIDER_DATAGRAM_DISPATCH* Dispatch;
-} WSK_DATAGRAM_SOCKET, * PWSK_DATAGRAM_SOCKET;
-
-//
-// Per-port state.
-//
-typedef struct CXPLAT_SOCKET {
-
- //
- // Flag indicates the binding has a default remote destination.
- //
- BOOLEAN Connected : 1;
-
- //
- // Flag indicates the binding is being used for PCP.
- //
- BOOLEAN PcpBinding : 1;
-
- //
- // Parent datapath.
- //
- CXPLAT_DATAPATH* Datapath;
-
- //
- // UDP socket used for sending/receiving datagrams.
- //
- union {
- PWSK_SOCKET Socket;
- PWSK_DATAGRAM_SOCKET DgrmSocket;
- };
-
- //
- // Event used to wait for completion of socket functions.
- //
- CXPLAT_EVENT WskCompletionEvent;
-
- //
- // The local address and UDP port.
- //
- SOCKADDR_INET LocalAddress;
-
- //
- // The remote address and UDP port.
- //
- SOCKADDR_INET RemoteAddress;
-
- //
- // The local interface's MTU.
- //
- UINT16 Mtu;
-
- //
- // Client context pointer.
- //
- void *ClientContext;
-
- //
- // IRP used for socket functions.
- //
- union {
- IRP Irp;
- UCHAR IrpBuffer[sizeof(IRP) + sizeof(IO_STACK_LOCATION)];
- };
-
- CXPLAT_RUNDOWN_REF Rundown[0]; // Per-proc
-
-} CXPLAT_SOCKET;
-
-//
-// Represents the per-processor state of the datapath context.
-//
-typedef struct CXPLAT_DATAPATH_PROC_CONTEXT {
-
- //
- // Pool of send contexts to be shared by all sockets on this core.
- //
- CXPLAT_POOL SendDataPool;
-
- //
- // Pool of send buffers to be shared by all sockets on this core.
- //
- CXPLAT_POOL SendBufferPool;
-
- //
- // Pool of large segmented send buffers to be shared by all sockets on this
- // core.
- //
- CXPLAT_POOL LargeSendBufferPool;
-
- //
- // Pool of receive datagram contexts and buffers to be shared by all sockets
- // on this core. Index 0 is regular, Index 1 is URO.
- //
- //
- CXPLAT_POOL RecvDatagramPools[2];
-
- //
- // Pool of receive data buffers. Index 0 is 4096, Index 1 is 65536.
- //
- CXPLAT_POOL RecvBufferPools[2];
-
- int64_t OutstandingPendingBytes;
-
-} CXPLAT_DATAPATH_PROC_CONTEXT;
-
-//
-// Structure that maintains all the internal state for the
-// CxPlatDataPath interface.
-//
-typedef struct CXPLAT_DATAPATH {
-
- //
- // Set of supported features.
- //
- uint32_t Features;
-
- //
- // The registration with WinSock Kernel.
- //
- WSK_REGISTRATION WskRegistration;
- WSK_PROVIDER_NPI WskProviderNpi;
- WSK_CLIENT_DATAGRAM_DISPATCH WskDispatch;
-
- //
- // The UDP callback function pointers.
- //
- CXPLAT_UDP_DATAPATH_CALLBACKS UdpHandlers;
-
- //
- // The size of the buffer to allocate for client's receive context structure.
- //
- uint32_t ClientRecvDataLength;
-
- //
- // The size of each receive datagram array element, including client context,
- // internal context, and padding.
- //
- uint32_t DatagramStride;
-
- //
- // The number of processors.
- //
- uint32_t ProcCount;
-
- //
- // Per-processor completion contexts.
- //
- CXPLAT_DATAPATH_PROC_CONTEXT ProcContexts[0];
-
-} CXPLAT_DATAPATH;
-
_IRQL_requires_same_
_Function_class_(ALLOCATE_FUNCTION_EX)
PVOID
@@ -789,7 +637,7 @@ CxPlatDataPathQuerySockoptSupport(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
-CxPlatDataPathInitialize(
+DataPathInitialize(
_In_ uint32_t ClientRecvDataLength,
_In_opt_ const CXPLAT_UDP_DATAPATH_CALLBACKS* UdpCallbacks,
_In_opt_ const CXPLAT_TCP_DATAPATH_CALLBACKS* TcpCallbacks,
@@ -1008,7 +856,7 @@ CxPlatDataPathInitialize(
_IRQL_requires_max_(PASSIVE_LEVEL)
void
-CxPlatDataPathUninitialize(
+DataPathUninitialize(
_In_ CXPLAT_DATAPATH* Datapath
)
{
@@ -1032,7 +880,7 @@ CxPlatDataPathUninitialize(
_IRQL_requires_max_(PASSIVE_LEVEL)
void
-CxPlatDataPathUpdateConfig(
+DataPathUpdateConfig(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ QUIC_EXECUTION_CONFIG* Config
)
@@ -1043,7 +891,7 @@ CxPlatDataPathUpdateConfig(
_IRQL_requires_max_(DISPATCH_LEVEL)
uint32_t
-CxPlatDataPathGetSupportedFeatures(
+DataPathGetSupportedFeatures(
_In_ CXPLAT_DATAPATH* Datapath
)
{
@@ -1052,12 +900,10 @@ CxPlatDataPathGetSupportedFeatures(
_IRQL_requires_max_(DISPATCH_LEVEL)
BOOLEAN
-CxPlatDataPathIsPaddingPreferred(
- _In_ CXPLAT_DATAPATH* Datapath,
- _In_ CXPLAT_SEND_DATA* SendData
+DataPathIsPaddingPreferred(
+ _In_ CXPLAT_DATAPATH* Datapath
)
{
- UNREFERENCED_PARAMETER(SendData);
return !!(Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_SEGMENTATION);
}
@@ -1384,7 +1230,7 @@ CxPlatDataPathSetControlSocket(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
-CxPlatSocketCreateUdp(
+SocketCreateUdp(
_In_ CXPLAT_DATAPATH* Datapath,
_In_ const CXPLAT_UDP_CONFIG* Config,
_Out_ CXPLAT_SOCKET** NewBinding
@@ -1868,7 +1714,7 @@ CxPlatSocketCreateUdp(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
-CxPlatSocketCreateTcp(
+SocketCreateTcp(
_In_ CXPLAT_DATAPATH* Datapath,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_ const QUIC_ADDR* RemoteAddress,
@@ -1886,7 +1732,7 @@ CxPlatSocketCreateTcp(
_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
-CxPlatSocketCreateTcpListener(
+SocketCreateTcpListener(
_In_ CXPLAT_DATAPATH* Datapath,
_In_opt_ const QUIC_ADDR* LocalAddress,
_In_opt_ void* CallbackContext,
@@ -1954,7 +1800,7 @@ CxPlatDataPathCloseSocketIoCompletion(
_IRQL_requires_max_(PASSIVE_LEVEL)
void
-CxPlatSocketDelete(
+SocketDelete(
_In_ CXPLAT_SOCKET* Binding
)
{
@@ -2002,21 +1848,6 @@ CxPlatSocketDelete(
CxPlatSocketDeleteComplete(Binding);
}
-_IRQL_requires_max_(PASSIVE_LEVEL)
-QUIC_STATUS
-CxPlatSocketUpdateQeo(
- _In_ CXPLAT_SOCKET* Socket,
- _In_reads_(OffloadCount)
- const CXPLAT_QEO_CONNECTION* Offloads,
- _In_ uint32_t OffloadCount
- )
-{
- UNREFERENCED_PARAMETER(Socket);
- UNREFERENCED_PARAMETER(Offloads);
- UNREFERENCED_PARAMETER(OffloadCount);
- return QUIC_STATUS_NOT_SUPPORTED;
-}
-
_IRQL_requires_max_(DISPATCH_LEVEL)
BOOLEAN
CxPlatSocketSetContext(
@@ -2045,48 +1876,6 @@ CxPlatSocketGetContext(
return Binding->ClientContext;
}
-_IRQL_requires_max_(DISPATCH_LEVEL)
-UINT16
-CxPlatSocketGetLocalMtu(
- _In_ CXPLAT_SOCKET* Binding
- )
-{
- CXPLAT_DBG_ASSERT(Binding != NULL);
- return Binding->Mtu;
-}
-
-_IRQL_requires_max_(DISPATCH_LEVEL)
-void
-CxPlatSocketGetLocalAddress(
- _In_ CXPLAT_SOCKET* Binding,
- _Out_ QUIC_ADDR* Address
- )
-{
- CXPLAT_DBG_ASSERT(Binding != NULL);
- *Address = Binding->LocalAddress;
-}
-
-_IRQL_requires_max_(DISPATCH_LEVEL)
-void
-CxPlatSocketGetRemoteAddress(
- _In_ CXPLAT_SOCKET* Binding,
- _Out_ QUIC_ADDR* Address
- )
-{
- CXPLAT_DBG_ASSERT(Binding != NULL);
- *Address = Binding->RemoteAddress;
-}
-
-_IRQL_requires_max_(DISPATCH_LEVEL)
-BOOLEAN
-CxPlatSocketRawSocketAvailable(
- _In_ CXPLAT_SOCKET* Socket
- )
-{
- UNREFERENCED_PARAMETER(Socket);
- return FALSE;
-}
-
_IRQL_requires_max_(DISPATCH_LEVEL)
DATAPATH_RX_IO_BLOCK*
CxPlatSocketAllocRxIoBlock(
@@ -2513,8 +2302,8 @@ CxPlatDataPathSocketReceive(
_IRQL_requires_max_(DISPATCH_LEVEL)
void
-CxPlatRecvDataReturn(
- _In_opt_ CXPLAT_RECV_DATA* RecvDataChain
+RecvDataReturn(
+ _In_ CXPLAT_RECV_DATA* RecvDataChain
)
{
CXPLAT_SOCKET* Binding = NULL;
@@ -2589,7 +2378,7 @@ CxPlatRecvDataReturn(
_IRQL_requires_max_(DISPATCH_LEVEL)
_Success_(return != NULL)
CXPLAT_SEND_DATA*
-CxPlatSendDataAlloc(
+SendDataAlloc(
_In_ CXPLAT_SOCKET* Binding,
_Inout_ CXPLAT_SEND_CONFIG* Config
)
@@ -2621,7 +2410,7 @@ CxPlatSendDataAlloc(
_IRQL_requires_max_(DISPATCH_LEVEL)
void
-CxPlatSendDataFree(
+SendDataFree(
_In_ CXPLAT_SEND_DATA* SendData
)
{
@@ -2858,7 +2647,7 @@ CxPlatSendDataAllocSegmentBuffer(
_IRQL_requires_max_(DISPATCH_LEVEL)
_Success_(return != NULL)
QUIC_BUFFER*
-CxPlatSendDataAllocBuffer(
+SendDataAllocBuffer(
_In_ CXPLAT_SEND_DATA* SendData,
_In_ UINT16 MaxBufferLength
)
@@ -2912,7 +2701,7 @@ CxPlatSendDataFreeSendBuffer(
_IRQL_requires_max_(DISPATCH_LEVEL)
void
-CxPlatSendDataFreeBuffer(
+SendDataFreeBuffer(
_In_ CXPLAT_SEND_DATA* SendData,
_In_ QUIC_BUFFER* Buffer
)
@@ -2943,7 +2732,7 @@ CxPlatSendDataFreeBuffer(
_IRQL_requires_max_(DISPATCH_LEVEL)
BOOLEAN
-CxPlatSendDataIsFull(
+SendDataIsFull(
_In_ CXPLAT_SEND_DATA* SendData
)
{
@@ -2976,7 +2765,7 @@ CxPlatDataPathSendComplete(
}
IoCleanupIrp(&SendData->Irp);
- CxPlatSendDataFree(SendData);
+ SendDataFree(SendData);
return STATUS_MORE_PROCESSING_REQUIRED;
}
@@ -3005,7 +2794,7 @@ CxPlatSocketPrepareSendData(
_IRQL_requires_max_(DISPATCH_LEVEL)
void
-CxPlatSocketSend(
+SocketSend(
_In_ CXPLAT_SOCKET* Binding,
_In_ const CXPLAT_ROUTE* Route,
_In_ CXPLAT_SEND_DATA* SendData
@@ -3136,55 +2925,11 @@ CxPlatSocketGetTcpStatistics(
return QUIC_STATUS_NOT_SUPPORTED;
}
-_IRQL_requires_max_(PASSIVE_LEVEL)
-void
-QuicCopyRouteInfo(
- _Inout_ CXPLAT_ROUTE* DstRoute,
- _In_ CXPLAT_ROUTE* SrcRoute
- )
-{
- *DstRoute = *SrcRoute;
-}
-
void
-CxPlatResolveRouteComplete(
- _In_ void* Context,
- _Inout_ CXPLAT_ROUTE* Route,
- _In_reads_bytes_(6) const uint8_t* PhysicalAddress,
- _In_ uint8_t PathId
+DataPathProcessCqe(
+ _In_ CXPLAT_CQE* Cqe
)
{
- UNREFERENCED_PARAMETER(Context);
- UNREFERENCED_PARAMETER(Route);
- UNREFERENCED_PARAMETER(PhysicalAddress);
- UNREFERENCED_PARAMETER(PathId);
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-QUIC_STATUS
-CxPlatResolveRoute(
- _In_ CXPLAT_SOCKET* Socket,
- _Inout_ CXPLAT_ROUTE* Route,
- _In_ uint8_t PathId,
- _In_ void* Context,
- _In_ CXPLAT_ROUTE_RESOLUTION_CALLBACK_HANDLER Callback
- )
-{
- UNREFERENCED_PARAMETER(Socket);
- UNREFERENCED_PARAMETER(PathId);
- UNREFERENCED_PARAMETER(Context);
- UNREFERENCED_PARAMETER(Callback);
- Route->State = RouteResolved;
- return QUIC_STATUS_SUCCESS;
-}
-
-_IRQL_requires_max_(PASSIVE_LEVEL)
-void
-CxPlatUpdateRoute(
- _Inout_ CXPLAT_ROUTE* DstRoute,
- _In_ CXPLAT_ROUTE* SrcRoute
- )
-{
- UNREFERENCED_PARAMETER(DstRoute);
- UNREFERENCED_PARAMETER(SrcRoute);
-}
+ UNREFERENCED_PARAMETER(Cqe);
+ CXPLAT_DBG_ASSERT(FALSE);
+}
\ No newline at end of file
diff --git a/src/platform/datapath_winuser.c b/src/platform/datapath_winuser.c
index bfaafb947d..c0f78159a7 100644
--- a/src/platform/datapath_winuser.c
+++ b/src/platform/datapath_winuser.c
@@ -1081,6 +1081,334 @@ DataPathIsPaddingPreferred(
return !!(Datapath->Features & CXPLAT_DATAPATH_FEATURE_SEND_SEGMENTATION);
}
+_IRQL_requires_max_(PASSIVE_LEVEL)
+_Success_(QUIC_SUCCEEDED(return))
+QUIC_STATUS
+CxPlatDataPathGetLocalAddresses(
+ _In_ CXPLAT_DATAPATH* Datapath,
+ _Outptr_ _At_(*Addresses, __drv_allocatesMem(Mem))
+ CXPLAT_ADAPTER_ADDRESS** Addresses,
+ _Out_ uint32_t* AddressesCount
+ )
+{
+ const ULONG Flags =
+ GAA_FLAG_INCLUDE_ALL_INTERFACES |
+ GAA_FLAG_SKIP_ANYCAST |
+ GAA_FLAG_SKIP_MULTICAST |
+ GAA_FLAG_SKIP_DNS_SERVER |
+ GAA_FLAG_SKIP_FRIENDLY_NAME |
+ GAA_FLAG_SKIP_DNS_INFO;
+
+ UNREFERENCED_PARAMETER(Datapath);
+
+ ULONG AdapterAddressesSize = 0;
+ PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
+ uint32_t Index = 0;
+
+ QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
+ ULONG Error;
+ do {
+ Error =
+ GetAdaptersAddresses(
+ AF_UNSPEC,
+ Flags,
+ NULL,
+ AdapterAddresses,
+ &AdapterAddressesSize);
+ if (Error == ERROR_BUFFER_OVERFLOW) {
+ if (AdapterAddresses) {
+ CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
+ }
+ AdapterAddresses = CXPLAT_ALLOC_NONPAGED(AdapterAddressesSize, QUIC_POOL_DATAPATH_ADDRESSES);
+ if (!AdapterAddresses) {
+ Error = ERROR_NOT_ENOUGH_MEMORY;
+ QuicTraceEvent(
+ AllocFailure,
+ "Allocation of '%s' failed. (%llu bytes)",
+ "PIP_ADAPTER_ADDRESSES",
+ AdapterAddressesSize);
+ }
+ }
+ } while (Error == ERROR_BUFFER_OVERFLOW);
+
+ if (Error != ERROR_SUCCESS) {
+ QuicTraceEvent(
+ LibraryErrorStatus,
+ "[ lib] ERROR, %u, %s.",
+ Error,
+ "GetAdaptersAddresses");
+ Status = HRESULT_FROM_WIN32(Error);
+ goto Exit;
+ }
+
+ for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
+ for (PIP_ADAPTER_UNICAST_ADDRESS_LH Iter2 = Iter->FirstUnicastAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
+ Index++;
+ }
+ }
+
+ if (Index == 0) {
+ QuicTraceEvent(
+ LibraryError,
+ "[ lib] ERROR, %s.",
+ "No local unicast addresses found");
+ Status = QUIC_STATUS_NOT_FOUND;
+ goto Exit;
+ }
+
+ *Addresses = CXPLAT_ALLOC_NONPAGED(Index * sizeof(CXPLAT_ADAPTER_ADDRESS), QUIC_POOL_DATAPATH_ADDRESSES);
+ if (*Addresses == NULL) {
+ Status = QUIC_STATUS_OUT_OF_MEMORY;
+ QuicTraceEvent(
+ AllocFailure,
+ "Allocation of '%s' failed. (%llu bytes)",
+ "Addresses",
+ Index * sizeof(CXPLAT_ADAPTER_ADDRESS));
+ goto Exit;
+ }
+
+ CxPlatZeroMemory(*Addresses, Index * sizeof(CXPLAT_ADAPTER_ADDRESS));
+ *AddressesCount = Index;
+ Index = 0;
+
+ for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
+ for (PIP_ADAPTER_UNICAST_ADDRESS_LH Iter2 = Iter->FirstUnicastAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
+ CxPlatCopyMemory(
+ &(*Addresses)[Index].Address,
+ Iter2->Address.lpSockaddr,
+ sizeof(QUIC_ADDR));
+ (*Addresses)[Index].InterfaceIndex =
+ Iter2->Address.lpSockaddr->sa_family == AF_INET ?
+ (uint32_t)Iter->IfIndex : (uint32_t)Iter->Ipv6IfIndex;
+ (*Addresses)[Index].InterfaceType = (uint16_t)Iter->IfType;
+ (*Addresses)[Index].OperationStatus = (CXPLAT_OPERATION_STATUS)Iter->OperStatus;
+ Index++;
+ }
+ }
+
+Exit:
+
+ if (AdapterAddresses) {
+ CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
+ }
+
+ return Status;
+}
+
+
+_IRQL_requires_max_(PASSIVE_LEVEL)
+_Success_(QUIC_SUCCEEDED(return))
+QUIC_STATUS
+CxPlatDataPathGetGatewayAddresses(
+ _In_ CXPLAT_DATAPATH* Datapath,
+ _Outptr_ _At_(*GatewayAddresses, __drv_allocatesMem(Mem))
+ QUIC_ADDR** GatewayAddresses,
+ _Out_ uint32_t* GatewayAddressesCount
+ )
+{
+ const ULONG Flags =
+ GAA_FLAG_INCLUDE_GATEWAYS |
+ GAA_FLAG_INCLUDE_ALL_INTERFACES |
+ GAA_FLAG_SKIP_DNS_SERVER |
+ GAA_FLAG_SKIP_MULTICAST;
+
+ UNREFERENCED_PARAMETER(Datapath);
+
+ ULONG AdapterAddressesSize = 0;
+ PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
+ uint32_t Index = 0;
+
+ QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
+ ULONG Error;
+ do {
+ Error =
+ GetAdaptersAddresses(
+ AF_UNSPEC,
+ Flags,
+ NULL,
+ AdapterAddresses,
+ &AdapterAddressesSize);
+ if (Error == ERROR_BUFFER_OVERFLOW) {
+ if (AdapterAddresses) {
+ CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
+ }
+ AdapterAddresses = CXPLAT_ALLOC_NONPAGED(AdapterAddressesSize, QUIC_POOL_DATAPATH_ADDRESSES);
+ if (!AdapterAddresses) {
+ Error = ERROR_NOT_ENOUGH_MEMORY;
+ QuicTraceEvent(
+ AllocFailure,
+ "Allocation of '%s' failed. (%llu bytes)",
+ "PIP_ADAPTER_ADDRESSES",
+ AdapterAddressesSize);
+ }
+ }
+ } while (Error == ERROR_BUFFER_OVERFLOW);
+
+ if (Error != ERROR_SUCCESS) {
+ QuicTraceEvent(
+ LibraryErrorStatus,
+ "[ lib] ERROR, %u, %s.",
+ Error,
+ "GetAdaptersAddresses");
+ Status = HRESULT_FROM_WIN32(Error);
+ goto Exit;
+ }
+
+ for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
+ for (PIP_ADAPTER_GATEWAY_ADDRESS_LH Iter2 = Iter->FirstGatewayAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
+ Index++;
+ }
+ }
+
+ if (Index == 0) {
+ QuicTraceEvent(
+ LibraryError,
+ "[ lib] ERROR, %s.",
+ "No gateway server addresses found");
+ Status = QUIC_STATUS_NOT_FOUND;
+ goto Exit;
+ }
+
+ *GatewayAddresses = CXPLAT_ALLOC_NONPAGED(Index * sizeof(QUIC_ADDR), QUIC_POOL_DATAPATH_ADDRESSES);
+ if (*GatewayAddresses == NULL) {
+ Status = QUIC_STATUS_OUT_OF_MEMORY;
+ QuicTraceEvent(
+ AllocFailure,
+ "Allocation of '%s' failed. (%llu bytes)",
+ "GatewayAddresses",
+ Index * sizeof(QUIC_ADDR));
+ goto Exit;
+ }
+
+ CxPlatZeroMemory(*GatewayAddresses, Index * sizeof(QUIC_ADDR));
+ *GatewayAddressesCount = Index;
+ Index = 0;
+
+ for (PIP_ADAPTER_ADDRESSES Iter = AdapterAddresses; Iter != NULL; Iter = Iter->Next) {
+ for (PIP_ADAPTER_GATEWAY_ADDRESS_LH Iter2 = Iter->FirstGatewayAddress; Iter2 != NULL; Iter2 = Iter2->Next) {
+ CxPlatCopyMemory(
+ &(*GatewayAddresses)[Index],
+ Iter2->Address.lpSockaddr,
+ sizeof(QUIC_ADDR));
+ Index++;
+ }
+ }
+
+Exit:
+
+ if (AdapterAddresses) {
+ CXPLAT_FREE(AdapterAddresses, QUIC_POOL_DATAPATH_ADDRESSES);
+ }
+
+ return Status;
+}
+
+// private func
+void
+CxPlatDataPathPopulateTargetAddress(
+ _In_ ADDRESS_FAMILY Family,
+ _In_ ADDRINFOW *Ai,
+ _Out_ SOCKADDR_INET* Address
+ )
+{
+ if (Ai->ai_addr->sa_family == QUIC_ADDRESS_FAMILY_INET6) {
+ //
+ // Is this a mapped ipv4 one?
+ //
+ PSOCKADDR_IN6 SockAddr6 = (PSOCKADDR_IN6)Ai->ai_addr;
+
+ if (Family == QUIC_ADDRESS_FAMILY_UNSPEC && IN6ADDR_ISV4MAPPED(SockAddr6))
+ {
+ PSOCKADDR_IN SockAddr4 = &Address->Ipv4;
+ //
+ // Get the ipv4 address from the mapped address.
+ //
+ SockAddr4->sin_family = QUIC_ADDRESS_FAMILY_INET;
+ SockAddr4->sin_addr =
+ *(IN_ADDR UNALIGNED *)
+ IN6_GET_ADDR_V4MAPPED(&SockAddr6->sin6_addr);
+ SockAddr4->sin_port = SockAddr6->sin6_port;
+ return;
+ }
+ }
+
+ CxPlatCopyMemory(Address, Ai->ai_addr, Ai->ai_addrlen);
+}
+
+_IRQL_requires_max_(PASSIVE_LEVEL)
+QUIC_STATUS
+CxPlatDataPathResolveAddress(
+ _In_ CXPLAT_DATAPATH* Datapath,
+ _In_z_ const char* HostName,
+ _Inout_ QUIC_ADDR* Address
+ )
+{
+ QUIC_STATUS Status;
+ PWSTR HostNameW = NULL;
+ ADDRINFOW Hints = { 0 };
+ ADDRINFOW *Ai;
+
+ Status =
+ CxPlatUtf8ToWideChar(
+ HostName,
+ QUIC_POOL_PLATFORM_TMP_ALLOC,
+ &HostNameW);
+ if (QUIC_FAILED(Status)) {
+ QuicTraceEvent(
+ LibraryErrorStatus,
+ "[ lib] ERROR, %u, %s.",
+ Status,
+ "Convert HostName to unicode");
+ goto Exit;
+ }
+
+ //
+ // Prepopulate hint with input family. It might be unspecified.
+ //
+ Hints.ai_family = Address->si_family;
+
+ //
+ // Try numeric name first.
+ //
+ Hints.ai_flags = AI_NUMERICHOST;
+ if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
+ CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
+ FreeAddrInfoW(Ai);
+ Status = QUIC_STATUS_SUCCESS;
+ goto Exit;
+ }
+
+ //
+ // Try canonical host name.
+ //
+ Hints.ai_flags = AI_CANONNAME;
+ if (GetAddrInfoW(HostNameW, NULL, &Hints, &Ai) == 0) {
+ CxPlatDataPathPopulateTargetAddress((ADDRESS_FAMILY)Hints.ai_family, Ai, Address);
+ FreeAddrInfoW(Ai);
+ Status = QUIC_STATUS_SUCCESS;
+ goto Exit;
+ }
+
+ QuicTraceEvent(
+ LibraryError,
+ "[ lib] ERROR, %s.",
+ "Resolving hostname to IP");
+ QuicTraceLogError(
+ DatapathResolveHostNameFailed,
+ "[%p] Couldn't resolve hostname '%s' to an IP address",
+ Datapath,
+ HostName);
+ Status = HRESULT_FROM_WIN32(WSAHOST_NOT_FOUND);
+
+Exit:
+
+ if (HostNameW != NULL) {
+ CXPLAT_FREE(HostNameW, QUIC_POOL_PLATFORM_TMP_ALLOC);
+ }
+
+ return Status;
+}
+
void
CxPlatSocketArmRioNotify(
_In_ CXPLAT_SOCKET_PROC* SocketProc
diff --git a/src/platform/platform.kernel.vcxproj b/src/platform/platform.kernel.vcxproj
index 765fdf67af..6e1f4506de 100644
--- a/src/platform/platform.kernel.vcxproj
+++ b/src/platform/platform.kernel.vcxproj
@@ -22,6 +22,9 @@
+
+
+
diff --git a/src/platform/platform_internal.h b/src/platform/platform_internal.h
index be58ef523d..142d6e0f63 100644
--- a/src/platform/platform_internal.h
+++ b/src/platform/platform_internal.h
@@ -137,6 +137,10 @@ typedef enum CXPLAT_SOCKET_TYPE {
#define CXPLAT_BASE_REG_PATH L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\MsQuic\\Parameters\\"
+// TODO: remove guard?
+#define SOCKET PWSK_SOCKET
+#define INVALID_SOCKET NULL
+
typedef struct CX_PLATFORM {
//
@@ -159,6 +163,178 @@ typedef struct CX_PLATFORM {
} CX_PLATFORM;
+typedef struct _WSK_DATAGRAM_SOCKET {
+ const WSK_PROVIDER_DATAGRAM_DISPATCH* Dispatch;
+} WSK_DATAGRAM_SOCKET, * PWSK_DATAGRAM_SOCKET;
+
+//
+// Per-port state.
+//
+typedef struct CXPLAT_SOCKET {
+ // CXPLAT_SOCKET_COMMON;
+
+ //
+ // Flag indicates the binding has a default remote destination.
+ //
+ BOOLEAN Connected : 1;
+
+ //
+ // Flag indicates the binding is being used for PCP.
+ //
+ BOOLEAN PcpBinding : 1;
+
+ //
+ // Parent datapath.
+ //
+ CXPLAT_DATAPATH* Datapath;
+
+ //
+ // UDP socket used for sending/receiving datagrams.
+ //
+ union {
+ PWSK_SOCKET Socket;
+ PWSK_DATAGRAM_SOCKET DgrmSocket;
+ };
+
+ //
+ // Event used to wait for completion of socket functions.
+ //
+ CXPLAT_EVENT WskCompletionEvent;
+
+ // TODO: set. use QUICADDR by using CXPLAT_SOCKET_COMMON ---
+ //
+ // The local address and UDP port.
+ //
+ SOCKADDR_INET LocalAddress;
+
+ //
+ // The remote address and UDP port.
+ //
+ SOCKADDR_INET RemoteAddress;
+
+ //
+ // The local interface's MTU.
+ //
+ UINT16 Mtu;
+
+ //
+ // Client context pointer.
+ //
+ void *ClientContext;
+
+ //
+ // IRP used for socket functions.
+ //
+ union {
+ IRP Irp;
+ UCHAR IrpBuffer[sizeof(IRP) + sizeof(IO_STACK_LOCATION)];
+ };
+
+ uint8_t UseTcp : 1; // always false?
+ uint8_t RawSocketAvailable : 1;
+
+ CXPLAT_RUNDOWN_REF Rundown[0]; // Per-proc
+
+} CXPLAT_SOCKET;
+
+//
+// Represents the per-processor state of the datapath context.
+//
+typedef struct CXPLAT_DATAPATH_PROC_CONTEXT {
+
+ //
+ // Pool of send contexts to be shared by all sockets on this core.
+ //
+ CXPLAT_POOL SendDataPool;
+
+ //
+ // Pool of send buffers to be shared by all sockets on this core.
+ //
+ CXPLAT_POOL SendBufferPool;
+
+ //
+ // Pool of large segmented send buffers to be shared by all sockets on this
+ // core.
+ //
+ CXPLAT_POOL LargeSendBufferPool;
+
+ //
+ // Pool of receive datagram contexts and buffers to be shared by all sockets
+ // on this core. Index 0 is regular, Index 1 is URO.
+ //
+ //
+ CXPLAT_POOL RecvDatagramPools[2];
+
+ //
+ // Pool of receive data buffers. Index 0 is 4096, Index 1 is 65536.
+ //
+ CXPLAT_POOL RecvBufferPools[2];
+
+ int64_t OutstandingPendingBytes;
+
+} CXPLAT_DATAPATH_PROC_CONTEXT;
+
+//
+// Structure that maintains all the internal state for the
+// CxPlatDataPath interface.
+//
+typedef struct CXPLAT_DATAPATH {
+ CXPLAT_DATAPATH_COMMON;
+
+ //
+ // Set of supported features.
+ //
+ uint32_t Features;
+
+ //
+ // The registration with WinSock Kernel.
+ //
+ WSK_REGISTRATION WskRegistration;
+ WSK_PROVIDER_NPI WskProviderNpi;
+ WSK_CLIENT_DATAGRAM_DISPATCH WskDispatch;
+
+ //
+ // The UDP callback function pointers.
+ //
+ // CXPLAT_UDP_DATAPATH_CALLBACKS UdpHandlers;
+
+ //
+ // The size of the buffer to allocate for client's receive context structure.
+ //
+ uint32_t ClientRecvDataLength;
+
+ //
+ // The size of each receive datagram array element, including client context,
+ // internal context, and padding.
+ //
+ uint32_t DatagramStride;
+
+ //
+ // The number of processors.
+ //
+ uint32_t ProcCount;
+
+ uint8_t UseTcp : 1; // TODO: set. always false?
+
+ CXPLAT_DATAPATH_RAW* RawDataPath; // TODO: set.
+
+ //
+ // Per-processor completion contexts.
+ //
+ CXPLAT_DATAPATH_PROC_CONTEXT ProcContexts[0];
+
+} CXPLAT_DATAPATH;
+
+#ifndef htonl
+#define htonl _byteswap_ulong
+#endif
+
+// TODO: unify accross all platforms?
+#define IS_LOOPBACK(Address) ((Address.si_family == QUIC_ADDRESS_FAMILY_INET && \
+ Address.Ipv4.sin_addr.S_un.S_addr == htonl(INADDR_LOOPBACK)) || \
+ (Address.si_family == QUIC_ADDRESS_FAMILY_INET6 && \
+ IN6_IS_ADDR_LOOPBACK(&Address.Ipv6.sin6_addr)))
+
#elif _WIN32
#pragma warning(push)