diff --git a/src/platform/datapath_epoll.c b/src/platform/datapath_epoll.c index a91b82c532..925880b36a 100644 --- a/src/platform/datapath_epoll.c +++ b/src/platform/datapath_epoll.c @@ -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 @@ -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; @@ -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; } @@ -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. // @@ -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( diff --git a/src/platform/datapath_kqueue.c b/src/platform/datapath_kqueue.c index e5a441ed3c..0bb64fa330 100644 --- a/src/platform/datapath_kqueue.c +++ b/src/platform/datapath_kqueue.c @@ -376,7 +376,7 @@ typedef struct CXPLAT_DATAPATH { CXPLAT_DATAPATH_PARTITION Partitions[]; } CXPLAT_DATAPATH; - + CXPLAT_EVENT_COMPLETION CxPlatSocketContextUninitializeEventComplete; CXPLAT_EVENT_COMPLETION CxPlatSocketContextIoEventComplete; @@ -567,9 +567,6 @@ CxPlatDataPathGetSupportedFeatures( _In_ CXPLAT_DATAPATH* Datapath ) { - // - // Intentionally not enabling Feature_TTL on MacOS for now. - // return Datapath->Features; } diff --git a/src/platform/datapath_raw.c b/src/platform/datapath_raw.c index f74785e7c6..57f342d91e 100644 --- a/src/platform/datapath_raw.c +++ b/src/platform/datapath_raw.c @@ -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; } diff --git a/src/platform/datapath_winkernel.c b/src/platform/datapath_winkernel.c index a2f7391153..57d7862ea3 100644 --- a/src/platform/datapath_winkernel.c +++ b/src/platform/datapath_winkernel.c @@ -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: diff --git a/src/platform/datapath_winuser.c b/src/platform/datapath_winuser.c index 2d935ab68f..946ceaf271 100644 --- a/src/platform/datapath_winuser.c +++ b/src/platform/datapath_winuser.c @@ -294,7 +294,7 @@ void SocketDelete( _In_ CXPLAT_SOCKET* Socket ); - + CXPLAT_EVENT_COMPLETION CxPlatIoRecvEventComplete; CXPLAT_EVENT_COMPLETION CxPlatIoRecvFailureEventComplete; CXPLAT_EVENT_COMPLETION CxPlatIoSendEventComplete; @@ -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 @@ -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; @@ -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 diff --git a/src/platform/platform_internal.h b/src/platform/platform_internal.h index d9e83583ee..4930ceb614 100644 --- a/src/platform/platform_internal.h +++ b/src/platform/platform_internal.h @@ -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. @@ -305,6 +310,11 @@ typedef struct CX_PLATFORM { // HANDLE Heap; + // + // Current Windows build number + // + DWORD dwBuildNumber; + #ifdef DEBUG // // 1/Denominator of allocations to fail. @@ -747,7 +757,7 @@ CxPlatCryptUninitialize( // // Platform Worker APIs -// +// BOOLEAN CxPlatWorkerPoolLazyStart( diff --git a/src/platform/platform_winkernel.c b/src/platform/platform_winkernel.c index 061c7b66fb..929e9ab149 100644 --- a/src/platform/platform_winkernel.c +++ b/src/platform/platform_winkernel.c @@ -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, diff --git a/src/platform/platform_winuser.c b/src/platform/platform_winuser.c index 11897048d2..2818a515c0 100644 --- a/src/platform/platform_winuser.c +++ b/src/platform/platform_winuser.c @@ -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( @@ -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,