Set SO_UPDATE_ACCEPT_CONTEXT on sockets accepted via AcceptEx in PortRelay (#40505)

* Set SO_UPDATE_ACCEPT_CONTEXT on sockets accepted via AcceptEx --------- Co-authored-by: Xin Wang (from Dev Box) <xiwang4@microsoft.com>

wangxin12 committed Jun 3, 2026 at 09:04 UTC 4f48477dd6e34ea4c3dc6041d06ebc434f2d0d96
4 files changed +23 -5
src/windows/common/socket.cpp
+10 -5
@@ -17,6 +17,15 @@ Abstract:
17 #include "socket.hpp"
18 #pragma hdrstop
19
20 +void wsl::windows::common::socket::SetAcceptContext(_In_ SOCKET AcceptedSocket, _In_ SOCKET ListenSocket, _In_ const std::source_location& Location)
21 +{
22 + // Set the accept context to mark the socket as connected.
23 + THROW_LAST_ERROR_IF_MSG(
24 + setsockopt(AcceptedSocket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, reinterpret_cast<const char*>(&ListenSocket), sizeof(ListenSocket)) == SOCKET_ERROR,
25 + "From: %hs",
26 + std::format("{}", Location).c_str());
27 +}
28 +
29 bool wsl::windows::common::socket::CancellableAccept(
30 _In_ SOCKET ListenSocket, _In_ SOCKET Socket, _In_ DWORD Timeout, _In_opt_ HANDLE ExitHandle, _In_ const std::source_location& Location)
31 {
@@ -38,11 +47,7 @@ bool wsl::windows::common::socket::CancellableAccept(
47 return false; // Accept was cancelled by the exit event.
48 }
49
41 - // Set the accept context to mark the socket as connected.
42 - THROW_LAST_ERROR_IF_MSG(
43 - setsockopt(Socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, reinterpret_cast<char*>(&ListenSocket), sizeof(ListenSocket)) == SOCKET_ERROR,
44 - "From: %hs",
45 - std::format("{}", Location).c_str());
50 + SetAcceptContext(Socket, ListenSocket, Location);
51
52 return true;
53 }
src/windows/common/socket.hpp
+3
@@ -18,6 +18,9 @@ Abstract:
18
19 namespace wsl::windows::common::socket {
20
21 +// Sets SO_UPDATE_ACCEPT_CONTEXT on a socket accepted via AcceptEx to mark it as connected.
22 +void SetAcceptContext(_In_ SOCKET AcceptedSocket, _In_ SOCKET ListenSocket, _In_ const std::source_location& Location = std::source_location::current());
23 +
24 bool CancellableAccept(
25 _In_ SOCKET ListenSocket,
26 _In_ SOCKET Socket,
src/windows/wslcsession/PortRelayHandle.cpp
+3
@@ -83,6 +83,9 @@ void PortRelayAcceptHandle::Collect()
83 THROW_IF_WIN32_BOOL_FALSE(WSAGetOverlappedResult(ListenSocket.get(), &Overlapped, &bytesReceived, false, &flagsReturned));
84 }
85
86 + // Set the accept context to mark the socket as connected.
87 + socket::SetAcceptContext(AcceptedSocket.get(), ListenSocket.get());
88 +
89 // Launch a relay for this accepted connection
90 LaunchRelay(std::move(AcceptedSocket));
91
src/windows/wslrelay/localhost.cpp
+7
@@ -401,6 +401,7 @@ struct PortRelay
401 wsl::windows::common::relay::SocketRelay(WindowsSocket, channel.Socket(), message.BufferSize);
402 }
403
404 + // Completes the overlapped AcceptEx initiated by ScheduleAccept, and sets accept context on the accepted socket.
405 void CompleteAccept()
406 {
407 Pending = false;
@@ -411,8 +412,12 @@ struct PortRelay
412 {
413 THROW_WIN32(WSAGetLastError());
414 }
415 +
416 + // Set the accept context to mark the socket as connected.
417 + wsl::windows::common::socket::SetAcceptContext(PendingSocket.get(), ListenSocket.get());
418 }
419
420 + // If the accept completes immediately, accept context will be set on the accepted socket.
421 bool ScheduleAccept()
422 {
423 WI_VERIFY(!Pending);
@@ -429,6 +434,8 @@ struct PortRelay
434 return false;
435 }
436
437 + // Set the accept context to mark the socket as connected.
438 + wsl::windows::common::socket::SetAcceptContext(PendingSocket.get(), ListenSocket.get());
439 return true;
440 }
441 };