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)