Skip to content

Commit

Permalink
[Expose TTL Follow up PR] move version logic to platform_xyz instead …
Browse files Browse the repository at this point in the history
…of datapath (#4740)
  • Loading branch information
ProjectsByJackHe authored Jan 10, 2025
1 parent bffa118 commit 0d9dd69
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 80 deletions.
16 changes: 3 additions & 13 deletions src/platform/datapath_epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ typedef struct CXPLAT_SEND_DATA {

typedef struct CXPLAT_RECV_MSG_CONTROL_BUFFER {
char Data[CMSG_SPACE(sizeof(struct in6_pktinfo)) + // IP_PKTINFO
2 * CMSG_SPACE(sizeof(int)) // TOS
+ CMSG_SPACE(sizeof(int))]; // IP_TTL
3 * CMSG_SPACE(sizeof(int))]; // TOS + IP_TTL

} CXPLAT_RECV_MSG_CONTROL_BUFFER;

#ifdef DEBUG
Expand All @@ -205,7 +205,7 @@ typedef struct CXPLAT_RECV_MSG_CONTROL_BUFFER {
#else
#define CXPLAT_DBG_ASSERT_CMSG(CMsg, type)
#endif

CXPLAT_EVENT_COMPLETION CxPlatSocketContextUninitializeEventComplete;
CXPLAT_EVENT_COMPLETION CxPlatSocketContextFlushTxEventComplete;
CXPLAT_EVENT_COMPLETION CxPlatSocketContextIoEventComplete;
Expand Down Expand Up @@ -339,9 +339,6 @@ CxPlatDataPathCalculateFeatureSupport(
}

Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TCP;
//
// TTL should always be available / enabled on Linux.
//
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TTL;
}

Expand Down Expand Up @@ -849,10 +846,6 @@ CxPlatSocketContextInitialize(
goto Exit;
}

//
// TTL should always be available / enabled on Linux.
//

//
// On Linux, IP_HOPLIMIT does not exist. So we will use IP_RECVTTL, IPV6_RECVHOPLIMIT instead.
//
Expand Down Expand Up @@ -1895,9 +1888,6 @@ CxPlatSocketContextRecvComplete(

CXPLAT_FRE_ASSERT(FoundLocalAddr);
CXPLAT_FRE_ASSERT(FoundTOS);
//
// TTL should always be available/enabled on Linux.
//
CXPLAT_FRE_ASSERT(FoundTTL);

QuicTraceEvent(
Expand Down
5 changes: 1 addition & 4 deletions src/platform/datapath_kqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ typedef struct CXPLAT_DATAPATH {
CXPLAT_DATAPATH_PARTITION Partitions[];

} CXPLAT_DATAPATH;

CXPLAT_EVENT_COMPLETION CxPlatSocketContextUninitializeEventComplete;
CXPLAT_EVENT_COMPLETION CxPlatSocketContextIoEventComplete;

Expand Down Expand Up @@ -567,9 +567,6 @@ CxPlatDataPathGetSupportedFeatures(
_In_ CXPLAT_DATAPATH* Datapath
)
{
//
// Intentionally not enabling Feature_TTL on MacOS for now.
//
return Datapath->Features;
}

Expand Down
3 changes: 0 additions & 3 deletions src/platform/datapath_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,6 @@ RawDataPathGetSupportedFeatures(
)
{
UNREFERENCED_PARAMETER(Datapath);
//
// TTL should always be available / enabled for XDP.
//
return CXPLAT_DATAPATH_FEATURE_RAW | CXPLAT_DATAPATH_FEATURE_TTL;
}

Expand Down
22 changes: 5 additions & 17 deletions src/platform/datapath_winkernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,24 +600,12 @@ CxPlatDataPathQuerySockoptSupport(

} while (FALSE);

do {
RTL_OSVERSIONINFOW osInfo;
RtlZeroMemory(&osInfo, sizeof(osInfo));
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
NTSTATUS status = RtlGetVersion(&osInfo);
if (NT_SUCCESS(status)) {
DWORD BuildNumber = osInfo.dwBuildNumber;
//
// Some USO/URO bug blocks TTL feature support on Windows Server 2022.
//
if (BuildNumber == 20348) {
break;
}
} else {
break;
}
//
// Some USO/URO bug blocks TTL feature support on Windows Server 2022.
//
if (CxPlatform.dwBuildNumber != 20348) {
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TTL;
} while (FALSE);
}

Error:

Expand Down
52 changes: 10 additions & 42 deletions src/platform/datapath_winuser.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ void
SocketDelete(
_In_ CXPLAT_SOCKET* Socket
);

CXPLAT_EVENT_COMPLETION CxPlatIoRecvEventComplete;
CXPLAT_EVENT_COMPLETION CxPlatIoRecvFailureEventComplete;
CXPLAT_EVENT_COMPLETION CxPlatIoSendEventComplete;
Expand Down Expand Up @@ -524,12 +524,6 @@ CxPlatDataPathQueryRssScalabilityInfo(
}
}

//
// To determine the OS version, we are going to use RtlGetVersion API
// since GetVersion call can be shimmed on Win8.1+.
//
typedef LONG (WINAPI *FuncRtlGetVersion)(RTL_OSVERSIONINFOW *);

QUIC_STATUS
CxPlatDataPathQuerySockoptSupport(
_Inout_ CXPLAT_DATAPATH* Datapath
Expand Down Expand Up @@ -706,27 +700,12 @@ CxPlatDataPathQuerySockoptSupport(
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_RECV_COALESCING;
}
}

//
// TODO: This "TTL_FEATURE check" code works, and mirrors the approach for Kernel mode.
// However, it is considered a "hack" and we should determine whether or not
// the current release story fits this current workaround.
// Some USO/URO bug blocks TTL feature support on Windows Server 2022.
//
HMODULE NtDllHandle = LoadLibraryA("ntdll.dll");
if (NtDllHandle) {
FuncRtlGetVersion VersionFunc = (FuncRtlGetVersion)GetProcAddress(NtDllHandle, "RtlGetVersion");
if (VersionFunc) {
RTL_OSVERSIONINFOW VersionInfo = {0};
VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
if ((*VersionFunc)(&VersionInfo) == 0) {
//
// Some USO/URO bug blocks TTL feature support on Windows Server 2022.
//
if (VersionInfo.dwBuildNumber != 20348) {
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TTL;
}
}
}
FreeLibrary(NtDllHandle);
if (CxPlatform.dwBuildNumber != 20348) {
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TTL;
}

Datapath->Features |= CXPLAT_DATAPATH_FEATURE_TCP;
Expand Down Expand Up @@ -844,22 +823,11 @@ DataPathInitialize(
// Check for port reservation support.
//
#ifndef QUIC_UWP_BUILD
HMODULE NtDllHandle = LoadLibraryA("ntdll.dll");
if (NtDllHandle) {
FuncRtlGetVersion VersionFunc = (FuncRtlGetVersion)GetProcAddress(NtDllHandle, "RtlGetVersion");
if (VersionFunc) {
RTL_OSVERSIONINFOW VersionInfo = {0};
VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
if ((*VersionFunc)(&VersionInfo) == 0) {
//
// Only RS5 and newer can use the port reservation feature safely.
//
if (VersionInfo.dwBuildNumber >= 17763) {
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_PORT_RESERVATIONS;
}
}
}
FreeLibrary(NtDllHandle);
//
// Only RS5 and newer can use the port reservation feature safely.
//
if (CxPlatform.dwBuildNumber >= 17763) {
Datapath->Features |= CXPLAT_DATAPATH_FEATURE_PORT_RESERVATIONS;
}
#endif

Expand Down
12 changes: 11 additions & 1 deletion src/platform/platform_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ typedef struct CX_PLATFORM {
//
BCRYPT_ALG_HANDLE RngAlgorithm;

//
// Current Windows build number
//
DWORD dwBuildNumber;

#ifdef DEBUG
//
// 1/Denominator of allocations to fail.
Expand Down Expand Up @@ -305,6 +310,11 @@ typedef struct CX_PLATFORM {
//
HANDLE Heap;

//
// Current Windows build number
//
DWORD dwBuildNumber;

#ifdef DEBUG
//
// 1/Denominator of allocations to fail.
Expand Down Expand Up @@ -747,7 +757,7 @@ CxPlatCryptUninitialize(

//
// Platform Worker APIs
//
//

BOOLEAN
CxPlatWorkerPoolLazyStart(
Expand Down
11 changes: 11 additions & 0 deletions src/platform/platform_winkernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ CxPlatInitialize(
CxPlatProcessorCount =
(uint32_t)KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);

RTL_OSVERSIONINFOW osInfo;
RtlZeroMemory(&osInfo, sizeof(osInfo));
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
NTSTATUS status = RtlGetVersion(&osInfo);
if (NT_SUCCESS(status)) {
DWORD BuildNumber = osInfo.dwBuildNumber;
CxPlatform.dwBuildNumber = BuildNumber;
} else {
CXPLAT_DBG_ASSERT(FALSE); // TODO: Is the assert here enough or is there an appropriate QUIC_STATUS we return?
}

QUIC_STATUS Status =
BCryptOpenAlgorithmProvider(
&CxPlatform.RngAlgorithm,
Expand Down
22 changes: 22 additions & 0 deletions src/platform/platform_winuser.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ TIMECAPS CxPlatTimerCapabilities;
#endif // TIMERR_NOERROR
QUIC_TRACE_RUNDOWN_CALLBACK* QuicTraceRundownCallback;

//
// To determine the OS version, we are going to use RtlGetVersion API
// since GetVersion call can be shimmed on Win8.1+.
//
typedef LONG (WINAPI *FuncRtlGetVersion)(RTL_OSVERSIONINFOW *);

_IRQL_requires_max_(PASSIVE_LEVEL)
void
CxPlatSystemLoad(
Expand Down Expand Up @@ -242,6 +248,22 @@ CxPlatInitialize(
goto Error;
}

BOOLEAN SuccessfullySetVersion = FALSE;
HMODULE NtDllHandle = LoadLibraryA("ntdll.dll");
if (NtDllHandle) {
FuncRtlGetVersion VersionFunc = (FuncRtlGetVersion)GetProcAddress(NtDllHandle, "RtlGetVersion");
if (VersionFunc) {
RTL_OSVERSIONINFOW VersionInfo = {0};
VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
if ((*VersionFunc)(&VersionInfo) == 0) {
CxPlatform.dwBuildNumber = VersionInfo.dwBuildNumber;
SuccessfullySetVersion = TRUE;
}
}
FreeLibrary(NtDllHandle);
}
CXPLAT_DBG_ASSERT(SuccessfullySetVersion); // TODO: Is the assert here enough or is there an appropriate QUIC_STATUS we return?

if (QUIC_FAILED(Status = CxPlatProcessorInfoInit())) {
QuicTraceEvent(
LibraryError,
Expand Down

0 comments on commit 0d9dd69

Please sign in to comment.