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
};