diff --git a/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs b/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs
index 8315b8ce990ae2..0f4090dd756d92 100644
--- a/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs
+++ b/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs
@@ -94,8 +94,8 @@ public static bool TryConnect(this Socket socket, EndPoint remoteEndpoint, int m
}
///
- /// A utility to create and bind a socket while blocking it's port for both IPv4 and IPv6
- /// by also creating and binding a "shadow" socket of the opposite address family.
+ /// A utility to create and bind a socket while blocking its port for both IPv4 and IPv6
+ /// by also creating and binding a "shadow" socket.
///
internal class PortBlocker : IDisposable
{
@@ -106,7 +106,7 @@ internal class PortBlocker : IDisposable
public int Port;
- public PortBlocker(Func socketFactory)
+ public PortBlocker(Func socketFactory, IPAddress? shadowAddress = null)
{
bool success = false;
for (int i = 0; i < MaxAttempts; i++)
@@ -118,15 +118,14 @@ public PortBlocker(Func socketFactory)
throw new Exception($"{nameof(socketFactory)} is expected create and bind the socket.");
}
- IPAddress shadowAddress = MainSocket.AddressFamily == AddressFamily.InterNetwork ?
- IPAddress.IPv6Loopback :
- IPAddress.Loopback;
+ IPAddress address = shadowAddress ??
+ (MainSocket.AddressFamily == AddressFamily.InterNetwork ? IPAddress.IPv6Loopback : IPAddress.Loopback);
int port = ((IPEndPoint)MainSocket.LocalEndPoint).Port;
- IPEndPoint shadowEndPoint = new IPEndPoint(shadowAddress, port);
+ IPEndPoint shadowEndPoint = new IPEndPoint(address, port);
try
{
- _shadowSocket = new Socket(shadowAddress.AddressFamily, MainSocket.SocketType, MainSocket.ProtocolType);
+ _shadowSocket = new Socket(address.AddressFamily, MainSocket.SocketType, MainSocket.ProtocolType);
success = TryBindWithoutReuseAddress(_shadowSocket, shadowEndPoint, out _);
if (success)
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs
index e6bc9031b9c7e4..57f180f8eccd56 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs
@@ -797,13 +797,28 @@ private async Task Accept_Helper(IPAddress listenOn, IPAddress connectTo)
private async Task Accept_Helper_Failing(IPAddress listenOn, IPAddress connectTo)
{
- using Socket serverSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
- int port = serverSocket.BindToAnonymousPort(listenOn);
+ using PortBlocker portBlocker = new PortBlocker(() =>
+ {
+ Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ socket.BindToAnonymousPort(listenOn);
+ return socket;
+ }, connectTo);
+
+ Socket serverSocket = portBlocker.MainSocket;
serverSocket.Listen(1);
- _ = AcceptAsync(serverSocket);
using Socket client = new Socket(connectTo.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
- await Assert.ThrowsAsync(() => client.ConnectAsync(connectTo, port));
+ Assert.False(client.TryConnect(new IPEndPoint(connectTo, portBlocker.Port), TestSettings.FailingTestTimeout));
+
+ IPAddress validConnectTo = listenOn.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback;
+ using Socket validClient = new Socket(validConnectTo.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+ await validClient.ConnectAsync(validConnectTo, portBlocker.Port).WaitAsync(TestSettings.PassingTestTimeout);
+
+ using Socket accepted = await AcceptAsync(serverSocket).WaitAsync(TestSettings.PassingTestTimeout);
+ var clientEndPoint = (IPEndPoint)validClient.LocalEndPoint;
+ var acceptedRemoteEndPoint = (IPEndPoint)accepted.RemoteEndPoint;
+ Assert.Equal(clientEndPoint.Port, acceptedRemoteEndPoint.Port);
+ Assert.Equal(clientEndPoint.Address.MapToIPv6(), acceptedRemoteEndPoint.Address.MapToIPv6());
}
protected static void AssertDualModeEnabled(Socket socket, IPAddress listenOn)