Skip to content

Commit 30d770d

Browse files
authored
Auto-enable SO_REUSE_UNICASTPORT for ConnectEx (#54903)
Fixes #48219.
1 parent c7ffa32 commit 30d770d

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Windows.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,34 @@ partial void WildcardBindForConnectIfNecessary(AddressFamily addressFamily)
235235

236236
if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, csep.IPEndPoint);
237237

238+
if (_socketType == SocketType.Stream && _protocolType == ProtocolType.Tcp)
239+
{
240+
EnableReuseUnicastPort();
241+
}
242+
238243
DoBind(csep.IPEndPoint, csep.SocketAddress);
239244
}
240245

246+
private void EnableReuseUnicastPort()
247+
{
248+
// By enabling SO_REUSE_UNICASTPORT, we defer actual port allocation until the ConnectEx call,
249+
// so it can bind to ports from the Windows auto-reuse port range, if configured by an admin.
250+
// The socket option is supported on Windows 10+, we are ignoring the SocketError in case setsockopt fails.
251+
int optionValue = 1;
252+
SocketError error = Interop.Winsock.setsockopt(
253+
_handle,
254+
SocketOptionLevel.Socket,
255+
SocketOptionName.ReuseUnicastPort,
256+
ref optionValue,
257+
sizeof(int));
258+
259+
if (NetEventSource.Log.IsEnabled() && error != SocketError.Success)
260+
{
261+
error = SocketPal.GetLastSocketError();
262+
NetEventSource.Info($"Enabling SO_REUSE_UNICASTPORT failed with error code: {error}");
263+
}
264+
}
265+
241266
internal unsafe bool ConnectEx(SafeSocketHandle socketHandle,
242267
IntPtr socketAddress,
243268
int socketAddressSize,

0 commit comments

Comments
 (0)