diff --git a/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs b/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs
index b316d8e6e271f5..1e252f0d6d6dbb 100644
--- a/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs
+++ b/src/libraries/Common/tests/System/Net/Sockets/SocketTestExtensions.cs
@@ -42,8 +42,16 @@ public static (Socket client, Socket server) CreateConnectedSocketPair(bool ipv6
{
IPAddress serverAddress = ipv6 ? IPAddress.IPv6Loopback : IPAddress.Loopback;
- using Socket listener = new Socket(serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
- listener.Bind(new IPEndPoint(serverAddress, 0));
+ // PortBlocker creates a temporary socket of the opposite AddressFamily in the background, so parallel tests won't attempt
+ // to create their listener sockets on the same port, regardless of address family.
+ // This should prevent 'listener' from accepting DualMode connections of unrelated tests.
+ using PortBlocker portBlocker = new PortBlocker(() =>
+ {
+ Socket l = new Socket(serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+ l.BindToAnonymousPort(serverAddress);
+ return l;
+ });
+ Socket listener = portBlocker.MainSocket; // PortBlocker shall dispose this
listener.Listen(1);
IPEndPoint connectTo = (IPEndPoint)listener.LocalEndPoint;
@@ -84,4 +92,121 @@ public static bool TryConnect(this Socket socket, EndPoint remoteEndpoint, int m
return false;
}
}
+
+ ///
+ /// 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.
+ ///
+ internal class PortBlocker : IDisposable
+ {
+ private const int MaxAttempts = 16;
+ private Socket _shadowSocket;
+ public Socket MainSocket { get; }
+
+ public PortBlocker(Func socketFactory)
+ {
+ bool success = false;
+ for (int i = 0; i < MaxAttempts; i++)
+ {
+ MainSocket = socketFactory();
+ if (MainSocket.LocalEndPoint is not IPEndPoint)
+ {
+ MainSocket.Dispose();
+ throw new Exception($"{nameof(socketFactory)} is expected create and bind the socket.");
+ }
+
+ IPAddress shadowAddress = MainSocket.AddressFamily == AddressFamily.InterNetwork ?
+ IPAddress.IPv6Loopback :
+ IPAddress.Loopback;
+ int port = ((IPEndPoint)MainSocket.LocalEndPoint).Port;
+ IPEndPoint shadowEndPoint = new IPEndPoint(shadowAddress, port);
+
+ try
+ {
+ _shadowSocket = new Socket(shadowAddress.AddressFamily, MainSocket.SocketType, MainSocket.ProtocolType);
+ success = TryBindWithoutReuseAddress(_shadowSocket, shadowEndPoint, out _);
+
+ if (success) break;
+ }
+ catch (SocketException)
+ {
+ MainSocket.Dispose();
+ _shadowSocket?.Dispose();
+ }
+ }
+
+ if (!success)
+ {
+ throw new Exception($"Failed to create the 'shadow' (port blocker) socket in {MaxAttempts} attempts.");
+ }
+ }
+
+ public void Dispose()
+ {
+ MainSocket.Dispose();
+ _shadowSocket.Dispose();
+ }
+
+ // Socket.Bind() auto-enables SO_REUSEADDR on Unix to allow Bind() during TIME_WAIT to emulate Windows behavior, see SystemNative_Bind() in 'pal_networking.c'.
+ // To prevent other sockets from succesfully binding to the same port port, we need to avoid this logic when binding the shadow socket.
+ // This method is doing a custom P/Invoke to bind() on Unix to achieve that.
+ private static unsafe bool TryBindWithoutReuseAddress(Socket socket, IPEndPoint endPoint, out int port)
+ {
+ if (PlatformDetection.IsWindows)
+ {
+ try
+ {
+ socket.Bind(endPoint);
+ }
+ catch (SocketException)
+ {
+ port = default;
+ return false;
+ }
+
+ port = ((IPEndPoint)socket.LocalEndPoint).Port;
+ return true;
+ }
+
+ SocketAddress addr = endPoint.Serialize();
+ byte[] data = new byte[addr.Size];
+ for (int i = 0; i < data.Length; i++)
+ {
+ data[i] = addr[i];
+ }
+
+ fixed (byte* dataPtr = data)
+ {
+ int result = bind(socket.SafeHandle, (nint)dataPtr, (uint)data.Length);
+ if (result != 0)
+ {
+ port = default;
+ return false;
+ }
+ uint sockLen = (uint)data.Length;
+ result = getsockname(socket.SafeHandle, (nint)dataPtr, (IntPtr)(&sockLen));
+ if (result != 0)
+ {
+ port = default;
+ return false;
+ }
+
+ addr = new SocketAddress(endPoint.AddressFamily, (int)sockLen);
+ }
+
+ for (int i = 0; i < data.Length; i++)
+ {
+ addr[i] = data[i];
+ }
+
+ port = ((IPEndPoint)endPoint.Create(addr)).Port;
+ return true;
+
+ [Runtime.InteropServices.DllImport("libc", SetLastError = true)]
+ static extern int bind(SafeSocketHandle socket, IntPtr socketAddress, uint addrLen);
+
+ [Runtime.InteropServices.DllImport("libc", SetLastError = true)]
+ static extern int getsockname(SafeSocketHandle socket, IntPtr socketAddress, IntPtr addrLenPtr);
+ }
+ }
}
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs
index 8141ae29e04216..a85ababc594126 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs
@@ -195,6 +195,28 @@ await RetryHelper.ExecuteAsync(async () =>
}
}, maxAttempts: 10, retryWhen: e => e is XunitException);
}
+
+ [OuterLoop("Connection failure takes long on Windows.")]
+ [Fact]
+ public async Task Connect_WithoutListener_ThrowSocketExceptionWithAppropriateInfo()
+ {
+ using PortBlocker portBlocker = new PortBlocker(() =>
+ {
+ Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ socket.BindToAnonymousPort(IPAddress.Loopback);
+ return socket;
+ });
+ Socket a = portBlocker.MainSocket;
+ using Socket b = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+
+ SocketException ex = await Assert.ThrowsAsync(() => ConnectAsync(b, a.LocalEndPoint));
+ Assert.Contains(Marshal.GetPInvokeErrorMessage(ex.NativeErrorCode), ex.Message);
+
+ if (UsesSync)
+ {
+ Assert.Contains(a.LocalEndPoint.ToString(), ex.Message);
+ }
+ }
}
public sealed class ConnectSync : Connect
@@ -215,29 +237,6 @@ public ConnectApm(ITestOutputHelper output) : base(output) {}
public sealed class ConnectTask : Connect
{
public ConnectTask(ITestOutputHelper output) : base(output) {}
-
- [OuterLoop]
- [Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/79820", TestPlatforms.Linux | TestPlatforms.Android)]
- public static void Connect_ThrowSocketException_Success()
- {
- using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
- {
- int anonymousPort = socket.BindToAnonymousPort(IPAddress.Loopback);
- IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, anonymousPort);
- Assert.ThrowsAsync(() => socket.ConnectAsync(ep));
- try
- {
- socket.Connect(ep);
- Assert.Fail("Socket Connect should throw SocketException in this case.");
- }
- catch (SocketException ex)
- {
- Assert.Contains(Marshal.GetPInvokeErrorMessage(ex.NativeErrorCode), ex.Message);
- Assert.Contains(ep.ToString(), ex.Message);
- }
- }
- }
}
public sealed class ConnectEap : Connect
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs
index 91ff1ce5d96e54..0a5f3adf604012 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Net.Test.Common;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -144,6 +145,7 @@ private void DualModeConnect_IPAddressToHost_Helper(IPAddress connectTo, IPAddre
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
socket.Connect(connectTo, port);
Assert.True(socket.Connected);
}
@@ -235,6 +237,7 @@ private void DualModeConnect_IPEndPointToHost_Helper(IPAddress connectTo, IPAddr
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
socket.Connect(new IPEndPoint(connectTo, port));
Assert.True(socket.Connected);
}
@@ -269,6 +272,7 @@ public void Socket_ConnectV4IPAddressListToV4Host_Throws()
using (SocketServer server = new SocketServer(_log, IPAddress.Loopback, false, out int port))
{
+ server.Start();
AssertExtensions.Throws("addresses", () =>
{
socket.Connect(new IPAddress[] { IPAddress.Loopback }, port);
@@ -278,11 +282,31 @@ public void Socket_ConnectV4IPAddressListToV4Host_Throws()
}
[Theory]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
[MemberData(nameof(DualMode_IPAddresses_ListenOn_DualMode_Throws_Data))]
public void DualModeConnect_IPAddressListToHost_Throws(IPAddress[] connectTo, IPAddress listenOn, bool dualModeServer)
{
- Assert.ThrowsAny(() => DualModeConnect_IPAddressListToHost_Success(connectTo, listenOn, dualModeServer));
+ using Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ SocketServer server = null;
+ int port = 0;
+
+ // PortBlocker creates a temporary socket of the opposite AddressFamily in the background, so parallel tests won't attempt
+ // to create their listener sockets on the same port.
+ // This should prevent 'server' from accepting DualMode connections of unrelated tests.
+ using PortBlocker blocker = new PortBlocker(() =>
+ {
+ server = new SocketServer(_log, listenOn, dualModeServer, out port);
+ return server.Socket;
+ });
+
+ using (server)
+ {
+ server.Start();
+ Assert.ThrowsAny(() =>
+ {
+ socket.Connect(connectTo, port);
+ });
+ Assert.False(socket.Connected);
+ }
}
[Theory]
@@ -292,6 +316,7 @@ public void DualModeConnect_IPAddressListToHost_Success(IPAddress[] connectTo, I
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
socket.Connect(connectTo, port);
Assert.True(socket.Connected);
}
@@ -309,6 +334,7 @@ public void DualModeConnect_LoopbackDnsToHost_Helper(IPAddress listenOn, bool du
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
socket.Connect("localhost", port);
Assert.True(socket.Connected);
}
@@ -326,6 +352,7 @@ public void DualModeConnect_DnsEndPointToHost_Helper(IPAddress listenOn, bool du
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
socket.Connect(new DnsEndPoint("localhost", port, AddressFamily.Unspecified));
Assert.True(socket.Connected);
}
@@ -374,6 +401,7 @@ private async Task DualModeBeginConnect_IPAddressToHost_Helper(IPAddress connect
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, connectTo, port, null);
Assert.True(socket.Connected);
}
@@ -426,6 +454,7 @@ private async Task DualModeBeginConnect_IPEndPointToHost_Helper(IPAddress connec
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, new IPEndPoint(connectTo, port), null);
Assert.True(socket.Connected);
}
@@ -444,6 +473,7 @@ public async Task DualModeBeginConnect_IPAddressListToHost_Helper(IPAddress[] co
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, connectTo, port, null);
Assert.True(socket.Connected);
}
@@ -457,6 +487,7 @@ public async Task DualModeBeginConnect_LoopbackDnsToHost_Helper(IPAddress listen
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, "localhost", port, null);
Assert.True(socket.Connected);
}
@@ -470,6 +501,7 @@ public async Task DualModeBeginConnect_DnsEndPointToHost_Helper(IPAddress listen
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, new DnsEndPoint("localhost", port), null);
Assert.True(socket.Connected);
}
@@ -535,6 +567,7 @@ private void DualModeConnectAsync_IPEndPointToHost_Helper(IPAddress connectTo, I
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
ManualResetEvent waitHandle = new ManualResetEvent(false);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += new EventHandler(AsyncCompleted);
@@ -575,6 +608,7 @@ public void DualModeConnectAsync_DnsEndPointToHost_Helper(IPAddress listenOn, bo
using (Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp))
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
ManualResetEvent waitHandle = new ManualResetEvent(false);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += new EventHandler(AsyncCompleted);
@@ -601,6 +635,7 @@ public void DualModeConnectAsync_Static_DnsEndPointToHost_Helper(IPAddress liste
{
using (SocketServer server = new SocketServer(_log, listenOn, dualModeServer, out int port))
{
+ server.Start();
ManualResetEvent waitHandle = new ManualResetEvent(false);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += new EventHandler(AsyncCompleted);
@@ -692,1051 +727,363 @@ public void Socket_EnableDualModeAfterV4Bind_Throws()
}
}
- [Trait("IPv4", "true")]
- [Trait("IPv6", "true")]
- public class DualModeAccept : DualModeBase
+ public abstract class DualModeAcceptBase : SocketTestHelperBase where T : SocketHelperBase, new()
{
- [Fact]
- public void AcceptV4BoundToSpecificV4_Success()
+ public DualModeAcceptBase(ITestOutputHelper output) : base(output)
{
- Accept_Helper(IPAddress.Loopback, IPAddress.Loopback);
}
[Fact]
- public void AcceptV4BoundToAnyV4_Success()
- {
- Accept_Helper(IPAddress.Any, IPAddress.Loopback);
- }
+ public Task AcceptV4BoundToSpecificV4_Success() => Accept_Helper(IPAddress.Loopback, IPAddress.Loopback);
[Fact]
- public void AcceptV6BoundToSpecificV6_Success()
- {
- Accept_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
- }
+ public Task AcceptV4BoundToAnyV4_Success() => Accept_Helper(IPAddress.Any, IPAddress.Loopback);
[Fact]
- public void AcceptV6BoundToAnyV6_Success()
- {
- Accept_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
- }
+ public Task AcceptV6BoundToSpecificV6_Success() => Accept_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
[Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // https://github.com/dotnet/runtime/issues/16265
- public void AcceptV6BoundToSpecificV4_CantConnect()
- {
- Assert.Throws(() =>
- {
- Accept_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback);
- });
- }
+ public Task AcceptV6BoundToAnyV6_Success() => Accept_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
[Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // https://github.com/dotnet/runtime/issues/16265
- public void AcceptV4BoundToSpecificV6_CantConnect()
- {
- Assert.Throws(() =>
- {
- Accept_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback);
- });
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // https://github.com/dotnet/runtime/issues/16265
- public void AcceptV6BoundToAnyV4_CantConnect()
- {
- Assert.Throws(() =>
- {
- Accept_Helper(IPAddress.Any, IPAddress.IPv6Loopback);
- });
- }
-
- [Fact]
- public void AcceptV4BoundToAnyV6_Success()
- {
- Accept_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
- }
-
- private void Accept_Helper(IPAddress listenOn, IPAddress connectTo)
- {
- using (Socket serverSocket = new Socket(SocketType.Stream, ProtocolType.Tcp))
- {
- int port = serverSocket.BindToAnonymousPort(listenOn);
- serverSocket.Listen(1);
- SocketClient client = new SocketClient(_log, serverSocket, connectTo, port);
- Socket clientSocket = serverSocket.Accept();
- Assert.True(clientSocket.Connected);
- AssertDualModeEnabled(clientSocket, listenOn);
- Assert.Equal(AddressFamily.InterNetworkV6, clientSocket.AddressFamily);
- }
- }
- }
-
- [Trait("IPv4", "true")]
- [Trait("IPv6", "true")]
- public class DualModeBeginAccept : DualModeBase
- {
- [Fact]
- public void BeginAcceptV4BoundToSpecificV4_Success()
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.Loopback, IPAddress.Loopback);
- }
-
- [Fact]
- public void BeginAcceptV4BoundToAnyV4_Success()
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.Any, IPAddress.Loopback);
- }
-
- [Fact]
- public void BeginAcceptV6BoundToSpecificV6_Success()
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
- }
+ public Task AcceptV4BoundToAnyV6_Success() => Accept_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
[Fact]
- public void BeginAcceptV6BoundToAnyV6_Success()
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
- }
+ public Task AcceptV6BoundToSpecificV4_CantConnect() => Accept_Helper_Failing(IPAddress.Loopback, IPAddress.IPv6Loopback);
[Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void BeginAcceptV6BoundToSpecificV4_CantConnect()
- {
- Assert.Throws(() =>
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback);
- });
- }
+ public Task AcceptV4BoundToSpecificV6_CantConnect() => Accept_Helper_Failing(IPAddress.IPv6Loopback, IPAddress.Loopback);
[Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void BeginAcceptV4BoundToSpecificV6_CantConnect()
- {
- Assert.Throws(() =>
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback);
- });
- }
+ public Task AcceptV6BoundToAnyV4_CantConnect() => Accept_Helper_Failing(IPAddress.Any, IPAddress.IPv6Loopback);
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void BeginAcceptV6BoundToAnyV4_CantConnect()
+ private async Task Accept_Helper(IPAddress listenOn, IPAddress connectTo)
{
- Assert.Throws(() =>
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.Any, IPAddress.IPv6Loopback);
- });
- }
+ using Socket serverSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
- [Fact]
- public void BeginAcceptV4BoundToAnyV6_Success()
- {
- DualModeConnect_BeginAccept_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
- }
+ int port = serverSocket.BindToAnonymousPort(listenOn);
+ serverSocket.Listen(1);
- private void DualModeConnect_BeginAccept_Helper(IPAddress listenOn, IPAddress connectTo)
- {
- using (Socket serverSocket = new Socket(SocketType.Stream, ProtocolType.Tcp))
+ using Socket client = new Socket(connectTo.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+ Task connectTask = client.ConnectAsync(connectTo, port);
+ Socket clientSocket = await AcceptAsync(serverSocket);
+ await connectTask;
+ Assert.True(clientSocket.Connected);
+ AssertDualModeEnabled(clientSocket, listenOn);
+ Assert.Equal(AddressFamily.InterNetworkV6, clientSocket.AddressFamily);
+ if (connectTo == IPAddress.Loopback)
{
- int port = serverSocket.BindToAnonymousPort(listenOn);
- serverSocket.Listen(1);
- IAsyncResult async = serverSocket.BeginAccept(null, null);
- SocketClient client = new SocketClient(_log, serverSocket, connectTo, port);
-
- Assert.True(
- client.WaitHandle.WaitOne(TestSettings.PassingTestTimeout),
- "Timed out while waiting for connection");
- Assert.True(
- async.AsyncWaitHandle.WaitOne(TestSettings.PassingTestTimeout),
- "Timed out while waiting to accept the client");
-
- // Due to the nondeterministic nature of calling dispose on a Socket that is doing
- // an EndAccept operation, we expect two types of exceptions to happen.
- Socket clientSocket;
- try
- {
- clientSocket = serverSocket.EndAccept(async);
- Assert.True(clientSocket.Connected);
- AssertDualModeEnabled(clientSocket, listenOn);
- Assert.Equal(AddressFamily.InterNetworkV6, clientSocket.AddressFamily);
- if (connectTo == IPAddress.Loopback)
- {
- Assert.Contains(((IPEndPoint)clientSocket.LocalEndPoint).Address, ValidIPv6Loopbacks);
- }
- else
- {
- Assert.Equal(connectTo.MapToIPv6(), ((IPEndPoint)clientSocket.LocalEndPoint).Address);
- }
- }
- catch (ObjectDisposedException) { }
- catch (SocketException) { }
-
- if (client.Error != SocketError.Success)
- {
- throw new SocketException((int)client.Error);
- }
+ Assert.Contains(((IPEndPoint)clientSocket.LocalEndPoint).Address, DualModeBase.ValidIPv6Loopbacks);
}
- }
- }
-
- [Trait("IPv4", "true")]
- [Trait("IPv6", "true")]
- public class DualModeAcceptAsync : DualModeBase
- {
- [Fact]
- public void AcceptAsyncV4BoundToSpecificV4_Success()
- {
- DualModeConnect_AcceptAsync_Helper(IPAddress.Loopback, IPAddress.Loopback);
- }
-
- [Fact]
- public void AcceptAsyncV4BoundToAnyV4_Success()
- {
- DualModeConnect_AcceptAsync_Helper(IPAddress.Any, IPAddress.Loopback);
- }
-
- [Fact]
- public void AcceptAsyncV6BoundToSpecificV6_Success()
- {
- DualModeConnect_AcceptAsync_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
- }
-
- [Fact]
- public void AcceptAsyncV6BoundToAnyV6_Success()
- {
- DualModeConnect_AcceptAsync_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void AcceptAsyncV6BoundToSpecificV4_CantConnect()
- {
- Assert.Throws(() =>
- {
- DualModeConnect_AcceptAsync_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback);
- });
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void AcceptAsyncV4BoundToSpecificV6_CantConnect()
- {
- Assert.Throws(() =>
+ else
{
- DualModeConnect_AcceptAsync_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback);
- });
+ Assert.Equal(connectTo.MapToIPv6(), ((IPEndPoint)clientSocket.LocalEndPoint).Address);
+ }
}
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void AcceptAsyncV6BoundToAnyV4_CantConnect()
+ private async Task Accept_Helper_Failing(IPAddress listenOn, IPAddress connectTo)
{
- Assert.Throws(() =>
- {
- DualModeConnect_AcceptAsync_Helper(IPAddress.Any, IPAddress.IPv6Loopback);
- });
- }
+ using Socket serverSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ int port = serverSocket.BindToAnonymousPort(listenOn);
+ serverSocket.Listen(1);
+ _ = AcceptAsync(serverSocket);
- [Fact]
- public void AcceptAsyncV4BoundToAnyV6_Success()
- {
- DualModeConnect_AcceptAsync_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
+ using Socket client = new Socket(connectTo.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+ await Assert.ThrowsAsync(() => client.ConnectAsync(connectTo, port));
}
- private void DualModeConnect_AcceptAsync_Helper(IPAddress listenOn, IPAddress connectTo)
- {
- using (Socket serverSocket = new Socket(SocketType.Stream, ProtocolType.Tcp))
- {
- int port = serverSocket.BindToAnonymousPort(listenOn);
- serverSocket.Listen(1);
-
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
- args.Completed += AsyncCompleted;
- ManualResetEvent waitHandle = new ManualResetEvent(false);
- args.UserToken = waitHandle;
- args.SocketError = SocketError.SocketError;
-
- _log.WriteLine(args.GetHashCode() + " SocketAsyncEventArgs with manual event " + waitHandle.GetHashCode());
- if (!serverSocket.AcceptAsync(args))
- {
- throw new SocketException((int)args.SocketError);
- }
-
- SocketClient client = new SocketClient(_log, serverSocket, connectTo, port);
-
- var waitHandles = new WaitHandle[2];
- waitHandles[0] = waitHandle;
- waitHandles[1] = client.WaitHandle;
-
- int completedHandle = WaitHandle.WaitAny(waitHandles, TestSettings.PassingTestTimeout);
-
- if (completedHandle == WaitHandle.WaitTimeout)
- {
- throw new TimeoutException("Timed out while waiting for either of client and server connections...");
- }
-
- if (completedHandle == 1) // Client finished
- {
- if (client.Error != SocketError.Success)
- {
- // Client SocketException
- throw new SocketException((int)client.Error);
- }
-
- if (!waitHandle.WaitOne(5000)) // Now wait for the server.
- {
- throw new TimeoutException("Timed out while waiting for the server accept...");
- }
- }
-
- _log.WriteLine(args.SocketError.ToString());
-
-
- if (args.SocketError != SocketError.Success)
- {
- throw new SocketException((int)args.SocketError);
- }
-
- Socket clientSocket = args.AcceptSocket;
- Assert.NotNull(clientSocket);
- Assert.True(clientSocket.Connected);
- AssertDualModeEnabled(clientSocket, listenOn);
- Assert.Equal(AddressFamily.InterNetworkV6, clientSocket.AddressFamily);
- if (connectTo == IPAddress.Loopback)
- {
- Assert.Contains(((IPEndPoint)clientSocket.LocalEndPoint).Address, ValidIPv6Loopbacks);
- }
- else
- {
- Assert.Equal(connectTo.MapToIPv6(), ((IPEndPoint)clientSocket.LocalEndPoint).Address);
- }
- clientSocket.Dispose();
- }
- }
- }
-
- [OuterLoop]
- [Trait("IPv4", "true")]
- [Trait("IPv6", "true")]
- public class DualModeConnectionlessSendTo : DualModeBase
- {
- #region SendTo Sync IPEndPoint
-
- [Fact]
- public void Socket_SendToV4IPEndPointToV4Host_Throws()
+ protected static void AssertDualModeEnabled(Socket socket, IPAddress listenOn)
{
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
+ if (OperatingSystem.IsWindows())
{
- socket.DualMode = false;
- Assert.Throws(() =>
- {
- socket.SendTo(new byte[1], new IPEndPoint(IPAddress.Loopback, UnusedPort));
- });
+ Assert.True(socket.DualMode);
}
- }
-
- [Fact] // Base case
- // "The parameter remoteEP must not be of type DnsEndPoint."
- public void Socket_SendToDnsEndPoint_Throws()
- {
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
+ else if (OperatingSystem.IsFreeBSD())
{
- AssertExtensions.Throws("remoteEP", () =>
- {
- socket.SendTo(new byte[1], new DnsEndPoint("localhost", UnusedPort));
- });
+ // This is not valid check on FreeBSD.
+ // Accepted socket is never DualMode and cannot be changed.
}
- }
-
- [Fact]
- public void SendToV4IPEndPointToV4Host_Success()
- {
- DualModeSendTo_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.Loopback, false);
- }
-
- [Fact]
- public void SendToV6IPEndPointToV6Host_Success()
- {
- DualModeSendTo_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback, false);
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void SendToV4IPEndPointToV6Host_NotReceived()
- {
- Assert.Throws(() =>
- {
- DualModeSendTo_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false, expectedToTimeout: true);
- });
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void SendToV6IPEndPointToV4Host_NotReceived()
- {
- Assert.Throws(() =>
- {
- DualModeSendTo_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false, expectedToTimeout: true);
- });
- }
-
- [Fact]
- public void SendToV4IPEndPointToDualHost_Success()
- {
- DualModeSendTo_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Any, true);
- }
-
- [Fact]
- public void SendToV6IPEndPointToDualHost_Success()
- {
- DualModeSendTo_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Any, true);
- }
-
- private void DualModeSendTo_IPEndPointToHost_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer, bool expectedToTimeout = false)
- {
- using (Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp))
- using (SocketUdpServer server = new SocketUdpServer(_log, listenOn, dualModeServer, out int port))
+ else
{
- int sent = client.SendTo(new byte[1], new IPEndPoint(connectTo, port));
- Assert.Equal(1, sent);
-
- bool success = server.WaitHandle.WaitOne(expectedToTimeout ? TestSettings.FailingTestTimeout : TestSettings.PassingTestTimeout); // Make sure the bytes were received
- if (!success)
- {
- throw new TimeoutException();
- }
+ Assert.True((listenOn != IPAddress.IPv6Any && !listenOn.IsIPv4MappedToIPv6) || socket.DualMode);
}
}
-
- #endregion SendTo Sync
}
- [OuterLoop]
[Trait("IPv4", "true")]
[Trait("IPv6", "true")]
- public class DualModeConnectionlessBeginSendTo : DualModeBase
+ public class DualModeAcceptSync : DualModeAcceptBase
{
- #region SendTo Begin/End
-
- [Fact]
- public void Socket_BeginSendToV4IPEndPointToV4Host_Throws()
- {
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- socket.DualMode = false;
-
- Assert.Throws(() =>
- {
- // [ActiveIssue("https://github.com/dotnet/runtime/issues/47905")]
- // TODO: When fixing the issue above, revert this test to check that the exception is being thrown in BeginSendTo
- // without the need to call EndSendTo.
- IAsyncResult result = socket.BeginSendTo(new byte[1], 0, 1, SocketFlags.None, new IPEndPoint(IPAddress.Loopback, UnusedPort), null, null);
- socket.EndSendTo(result);
- });
- }
- }
-
- [Fact] // Base case
- // "The parameter remoteEP must not be of type DnsEndPoint."
- public void Socket_BeginSendToDnsEndPoint_Throws()
- {
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- AssertExtensions.Throws("remoteEP", () =>
- {
- socket.BeginSendTo(new byte[1], 0, 1, SocketFlags.None, new DnsEndPoint("localhost", UnusedPort), null, null);
- });
- }
- }
-
- [Fact]
- public void BeginSendToV4IPEndPointToV4Host_Success()
- {
- DualModeBeginSendTo_EndPointToHost_Helper(IPAddress.Loopback, IPAddress.Loopback, false);
- }
-
- [Fact]
- public void BeginSendToV6IPEndPointToV6Host_Success()
- {
- DualModeBeginSendTo_EndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback, false);
- }
-
- [Fact]
- public void BeginSendToV4IPEndPointToV6Host_NotReceived()
- {
- Assert.Throws(() =>
- {
- DualModeBeginSendTo_EndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false, expectedToTimeout: true);
- });
- }
-
- [Fact]
- public void BeginSendToV6IPEndPointToV4Host_NotReceived()
- {
- Assert.Throws(() =>
- {
- DualModeBeginSendTo_EndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false, expectedToTimeout: true);
- });
- }
-
- [Fact]
- public void BeginSendToV4IPEndPointToDualHost_Success()
- {
- DualModeBeginSendTo_EndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Any, true);
- }
-
- [Fact]
- public void BeginSendToV6IPEndPointToDualHost_Success()
- {
- DualModeBeginSendTo_EndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Any, true);
- }
-
- private void DualModeBeginSendTo_EndPointToHost_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer, bool expectedToTimeout = false)
- {
- using (Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp))
- using (SocketUdpServer server = new SocketUdpServer(_log, listenOn, dualModeServer, out int port))
- {
- IAsyncResult async = client.BeginSendTo(new byte[1], 0, 1, SocketFlags.None, new IPEndPoint(connectTo, port), null, null);
-
- int sent = client.EndSendTo(async);
- Assert.Equal(1, sent);
-
- bool success = server.WaitHandle.WaitOne(expectedToTimeout ? TestSettings.FailingTestTimeout : TestSettings.PassingTestTimeout); // Make sure the bytes were received
- if (!success)
- {
- throw new TimeoutException();
- }
- }
- }
-
- #endregion SendTo Begin/End
+ public DualModeAcceptSync(ITestOutputHelper output) : base(output) { }
}
- [OuterLoop]
[Trait("IPv4", "true")]
[Trait("IPv6", "true")]
- public class DualModeConnectionlessSendToAsync : DualModeBase
+ public class DualModeAcceptApm : DualModeAcceptBase
{
- #region SendTo Async/Event
-
- [Fact]
- public void Socket_SendToAsyncV4IPEndPointToV4Host_Throws()
- {
- using (Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp))
- {
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
- args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, UnusedPort);
- args.SetBuffer(new byte[1], 0, 1);
- bool async = socket.SendToAsync(args);
- Assert.False(async);
-
- if (OperatingSystem.IsWindows())
- {
- Assert.Equal(SocketError.Fault, args.SocketError);
- }
- else if (OperatingSystem.IsLinux())
- {
- // NOTE: on Linux, this API returns ENETUNREACH instead of EFAULT: this platform
- // checks the family of the provided socket address before checking its size
- // (as long as the socket address is large enough to store an address family).
- Assert.Equal(SocketError.NetworkUnreachable, args.SocketError);
- }
- else
- {
- // NOTE: on other Unix platforms, this API returns EINVAL instead of EFAULT.
- Assert.Equal(SocketError.InvalidArgument, args.SocketError);
- }
- }
- }
-
- [Fact] // Base case
- // "The parameter remoteEP must not be of type DnsEndPoint."
- public void Socket_SendToAsyncDnsEndPoint_Throws()
- {
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
- args.RemoteEndPoint = new DnsEndPoint("localhost", UnusedPort);
- args.SetBuffer(new byte[1], 0, 1);
- AssertExtensions.Throws("remoteEP", () =>
- {
- socket.SendToAsync(args);
- });
- }
- }
-
- [Fact]
- public void SendToAsyncV4IPEndPointToV4Host_Success()
- {
- DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.Loopback, false);
- }
-
- [Fact]
- public void SendToAsyncV6IPEndPointToV6Host_Success()
- {
- DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback, false);
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void SendToAsyncV4IPEndPointToV6Host_NotReceived()
- {
- Assert.Throws(() =>
- {
- DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false, expectedToTimeout: true);
- });
- }
-
- [Fact]
- [PlatformSpecific(TestPlatforms.Windows)] // Binds to a specific port on 'connectTo' which on Unix may already be in use
- public void SendToAsyncV6IPEndPointToV4Host_NotReceived()
- {
- Assert.Throws(() =>
- {
- DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false, expectedToTimeout: true);
- });
- }
-
- [Fact]
- public void SendToAsyncV4IPEndPointToDualHost_Success()
- {
- DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Any, true);
- }
-
- [Fact]
- public void SendToAsyncV6IPEndPointToDualHost_Success()
- {
- DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Any, true);
- }
-
- private void DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer, bool expectedToTimeout = false)
- {
- using (Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp))
- using (SocketUdpServer server = new SocketUdpServer(_log, listenOn, dualModeServer, out int port))
- {
- using (ManualResetEvent waitHandle = new ManualResetEvent(false))
- {
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
- args.RemoteEndPoint = new IPEndPoint(connectTo, port);
- args.SetBuffer(new byte[1], 0, 1);
- args.UserToken = waitHandle;
- args.Completed += AsyncCompleted;
-
- bool async = client.SendToAsync(args);
- if (async)
- {
- Assert.True(waitHandle.WaitOne(TestSettings.PassingTestTimeout), "Timeout while waiting for connection");
- }
-
- Assert.Equal(1, args.BytesTransferred);
- if (args.SocketError != SocketError.Success)
- {
- throw new SocketException((int)args.SocketError);
- }
- }
-
- bool success = server.WaitHandle.WaitOne(expectedToTimeout ? TestSettings.FailingTestTimeout : TestSettings.PassingTestTimeout); // Make sure the bytes were received
- if (!success)
- {
- throw new TimeoutException();
- }
- }
- }
-
- #endregion SendTo Async/Event
+ public DualModeAcceptApm(ITestOutputHelper output) : base(output) { }
}
- [OuterLoop]
[Trait("IPv4", "true")]
[Trait("IPv6", "true")]
- public class DualModeConnectionlessReceiveFrom : DualModeBase
+ public class DualModeAcceptEap : DualModeAcceptBase
{
- #region ReceiveFrom Sync
-
- [Fact] // Base case
- public void Socket_ReceiveFromV4IPEndPointFromV4Client_Throws()
- {
- // "The supplied EndPoint of AddressFamily InterNetwork is not valid for this Socket, use InterNetworkV6 instead."
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- socket.DualMode = false;
-
- EndPoint receivedFrom = new IPEndPoint(IPAddress.Loopback, UnusedPort);
- AssertExtensions.Throws("remoteEP", () =>
- {
- int received = socket.ReceiveFrom(new byte[1], ref receivedFrom);
- });
- }
- }
-
- [Fact] // Base case
- public void Socket_ReceiveFromDnsEndPoint_Throws()
- {
- // "The parameter remoteEP must not be of type DnsEndPoint."
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- int port = socket.BindToAnonymousPort(IPAddress.IPv6Loopback);
- EndPoint receivedFrom = new DnsEndPoint("localhost", port, AddressFamily.InterNetworkV6);
- AssertExtensions.Throws("remoteEP", () =>
- {
- int received = socket.ReceiveFrom(new byte[1], ref receivedFrom);
- });
- }
- }
-
- [Fact]
- public void ReceiveFromV4BoundToSpecificV4_Success()
- {
- ReceiveFrom_Helper(IPAddress.Loopback, IPAddress.Loopback);
- }
-
- [Fact]
- public void ReceiveFromV4BoundToAnyV4_Success()
- {
- ReceiveFrom_Helper(IPAddress.Any, IPAddress.Loopback);
- }
-
- [Fact]
- public void ReceiveFromV6BoundToSpecificV6_Success()
- {
- ReceiveFrom_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
- }
-
- [Fact]
- public void ReceiveFromV6BoundToAnyV6_Success()
- {
- ReceiveFrom_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
- }
-
- [Fact]
- // Binds to a specific port on 'connectTo' which on Unix may already be in use
- // Also ReceiveFrom not supported on OSX
- [PlatformSpecific(TestPlatforms.Windows)]
- public void ReceiveFromV6BoundToSpecificV4_NotReceived()
- {
- Assert.Throws(() =>
- {
- ReceiveFrom_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback);
- });
- }
-
- [Fact]
- // Binds to a specific port on 'connectTo' which on Unix may already be in use
- // Also expected behavior is different on OSX and Linux (ArgumentException instead of SocketException)
- [PlatformSpecific(TestPlatforms.Windows)]
- public void ReceiveFromV4BoundToSpecificV6_NotReceived()
- {
- Assert.Throws(() =>
- {
- ReceiveFrom_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback);
- });
- }
-
- [Fact]
- // Binds to a specific port on 'connectTo' which on Unix may already be in use
- // Also ReceiveFrom not supported on OSX
- [PlatformSpecific(TestPlatforms.Windows)]
- public void ReceiveFromV6BoundToAnyV4_NotReceived()
- {
- Assert.Throws(() =>
- {
- ReceiveFrom_Helper(IPAddress.Any, IPAddress.IPv6Loopback);
- });
- }
-
- [Fact]
- public void ReceiveFromV4BoundToAnyV6_Success()
- {
- ReceiveFrom_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
- }
-
- #endregion ReceiveFrom Sync
+ public DualModeAcceptEap(ITestOutputHelper output) : base(output) { }
}
- [OuterLoop]
[Trait("IPv4", "true")]
- [Trait("IPv6", "true")]
- public class DualModeConnectionlessBeginReceiveFrom : DualModeBase
- {
- #region ReceiveFrom Begin/End
-
- [Fact] // Base case
- // "The supplied EndPoint of AddressFamily InterNetwork is not valid for this Socket, use InterNetworkV6 instead."
- public void Socket_BeginReceiveFromV4IPEndPointFromV4Client_Throws()
- {
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- socket.DualMode = false;
-
- EndPoint receivedFrom = new IPEndPoint(IPAddress.Loopback, UnusedPort);
- AssertExtensions.Throws("remoteEP", () =>
- {
- socket.BeginReceiveFrom(new byte[1], 0, 1, SocketFlags.None, ref receivedFrom, null, null);
- });
- }
- }
+ [Trait("IPv6", "true")]
+ public class DualModeAcceptTask : DualModeAcceptBase
+ {
+ public DualModeAcceptTask(ITestOutputHelper output) : base(output) { }
+ }
- [Fact] // Base case
- // "The parameter remoteEP must not be of type DnsEndPoint."
- public void Socket_BeginReceiveFromDnsEndPoint_Throws()
+ public abstract class DualModeConnectionlessSendToBase : SocketTestHelperBase where T : SocketHelperBase, new()
+ {
+ protected DualModeConnectionlessSendToBase(ITestOutputHelper output) : base(output)
{
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- int port = socket.BindToAnonymousPort(IPAddress.IPv6Loopback);
- EndPoint receivedFrom = new DnsEndPoint("localhost", port, AddressFamily.InterNetworkV6);
-
- AssertExtensions.Throws("remoteEP", () =>
- {
- socket.BeginReceiveFrom(new byte[1], 0, 1, SocketFlags.None, ref receivedFrom, null, null);
- });
- }
}
[Fact]
- public void BeginReceiveFromV4BoundToSpecificV4_Success()
+ public async Task Socket_SendToV4IPEndPointToV4Host_Throws()
{
- BeginReceiveFrom_Helper(IPAddress.Loopback, IPAddress.Loopback);
+ using Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
+ socket.DualMode = false;
+ await Assert.ThrowsAsync(
+ () => SendToAsync(socket, new byte[1], new IPEndPoint(IPAddress.Loopback, DualModeBase.UnusedPort)));
}
- [Fact]
- [SkipOnPlatform(TestPlatforms.OSX | TestPlatforms.MacCatalyst | TestPlatforms.iOS | TestPlatforms.tvOS, "BeginReceiveFrom not supported on Apple platforms")]
- public void BeginReceiveFromV4BoundToAnyV4_Success()
+ [Fact] // Base case
+ // "The parameter remoteEP must not be of type DnsEndPoint."
+ public async Task Socket_SendToDnsEndPoint_Throws()
{
- BeginReceiveFrom_Helper(IPAddress.Any, IPAddress.Loopback);
+ using Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
+
+ await AssertExtensions.ThrowsAsync("remoteEP",
+ () => SendToAsync(socket, new byte[1], new DnsEndPoint("localhost", DualModeBase.UnusedPort)));
}
[Fact]
- public void BeginReceiveFromV6BoundToSpecificV6_Success()
- {
- BeginReceiveFrom_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
- }
+ public Task SendToV4IPEndPointToV4Host_Success() => DualModeSendTo_IPEndPointToHost_Success_Helper(IPAddress.Loopback, IPAddress.Loopback, false);
[Fact]
- public void BeginReceiveFromV6BoundToAnyV6_Success()
- {
- BeginReceiveFrom_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
- }
+ public Task SendToV6IPEndPointToV6Host_Success() => DualModeSendTo_IPEndPointToHost_Success_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback, false);
[Fact]
- // Binds to a specific port on 'connectTo' which on Unix may already be in use
- // Also BeginReceiveFrom not supported on OSX
- [PlatformSpecific(TestPlatforms.Windows)]
- public void BeginReceiveFromV6BoundToSpecificV4_NotReceived()
- {
- Assert.Throws(() =>
- {
- BeginReceiveFrom_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, expectedToTimeout: true);
- });
- }
+ public Task SendToV4IPEndPointToDualHost_Success() => DualModeSendTo_IPEndPointToHost_Success_Helper(IPAddress.Loopback, IPAddress.IPv6Any, true);
[Fact]
- // Binds to a specific port on 'connectTo' which on Unix may already be in use
- // Also expected behavior is different on OSX and Linux (ArgumentException instead of TimeoutException)
- [PlatformSpecific(TestPlatforms.Windows)]
- public void BeginReceiveFromV4BoundToSpecificV6_NotReceived()
- {
- Assert.Throws(() =>
- {
- BeginReceiveFrom_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, expectedToTimeout: true);
- });
- }
+ public Task SendToV6IPEndPointToDualHost_Success() => DualModeSendTo_IPEndPointToHost_Success_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Any, true);
[Fact]
- // Binds to a specific port on 'connectTo' which on Unix may already be in use
- // Also BeginReceiveFrom not supported on OSX
- [PlatformSpecific(TestPlatforms.Windows)]
- public void BeginReceiveFromV6BoundToAnyV4_NotReceived()
- {
- Assert.Throws(() =>
- {
- BeginReceiveFrom_Helper(IPAddress.Any, IPAddress.IPv6Loopback, expectedToTimeout: true);
- });
- }
+ public Task SendToV4IPEndPointToV6Host_NotReceived() => DualModeSendTo_IPEndPointToHost_Failing_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false);
[Fact]
- public void BeginReceiveFromV4BoundToAnyV6_Success()
- {
- BeginReceiveFrom_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
- }
+ public Task SendToV6IPEndPointToV4Host_NotReceived() => DualModeSendTo_IPEndPointToHost_Failing_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false);
- private void BeginReceiveFrom_Helper(IPAddress listenOn, IPAddress connectTo, bool expectedToTimeout = false)
+ private async Task DualModeSendTo_IPEndPointToHost_Success_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer)
{
- using (Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- serverSocket.ReceiveTimeout = 500;
- int port = serverSocket.BindToAnonymousPort(listenOn);
-
- EndPoint receivedFrom = new IPEndPoint(connectTo, port);
- IAsyncResult async = serverSocket.BeginReceiveFrom(new byte[1], 0, 1, SocketFlags.None, ref receivedFrom, null, null);
-
- // Behavior difference from Desktop: receivedFrom will _not_ change during the synchronous phase.
+ using Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp);
+ using Socket server = dualModeServer ?
+ new Socket(SocketType.Dgram, ProtocolType.Udp) :
+ new Socket(listenOn.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
+ int port = server.BindToAnonymousPort(listenOn);
- // IPEndPoint remoteEndPoint = receivedFrom as IPEndPoint;
- // Assert.Equal(AddressFamily.InterNetworkV6, remoteEndPoint.AddressFamily);
- // Assert.Equal(connectTo.MapToIPv6(), remoteEndPoint.Address);
+ Task receiveTask = server.ReceiveAsync(new byte[1]);
+ int sent = await SendToAsync(client, new byte[1], new IPEndPoint(connectTo, port)).WaitAsync(TestSettings.PassingTestTimeout);
+ Assert.Equal(1, sent);
- SocketUdpClient client = new SocketUdpClient(_log, serverSocket, connectTo, port);
- bool success = async.AsyncWaitHandle.WaitOne(expectedToTimeout ? TestSettings.FailingTestTimeout : TestSettings.PassingTestTimeout);
- if (!success)
- {
- throw new TimeoutException();
- }
+ int received = await receiveTask.WaitAsync(TestSettings.PassingTestTimeout);
+ Assert.Equal(1, received);
+ }
- receivedFrom = new IPEndPoint(connectTo, port);
- int received = serverSocket.EndReceiveFrom(async, ref receivedFrom);
+ private async Task DualModeSendTo_IPEndPointToHost_Failing_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer)
+ {
+ using Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp);
+ using Socket server = dualModeServer ?
+ new Socket(SocketType.Dgram, ProtocolType.Udp) :
+ new Socket(listenOn.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
+ int port = server.BindToAnonymousPort(listenOn);
- Assert.Equal(1, received);
- Assert.Equal(typeof(IPEndPoint), receivedFrom.GetType());
+ _ = SendToAsync(client, new byte[1], new IPEndPoint(connectTo, port)).WaitAsync(TestSettings.PassingTestTimeout);
+ await Assert.ThrowsAsync(() => server.ReceiveAsync(new byte[1]).WaitAsync(TestSettings.FailingTestTimeout));
+ }
+ }
- IPEndPoint remoteEndPoint = receivedFrom as IPEndPoint;
- Assert.Equal(AddressFamily.InterNetworkV6, remoteEndPoint.AddressFamily);
- Assert.Equal(connectTo.MapToIPv6(), remoteEndPoint.Address);
- }
+ [Trait("IPv4", "true")]
+ [Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessSendToSync : DualModeConnectionlessSendToBase
+ {
+ public DualModeConnectionlessSendToSync(ITestOutputHelper output) : base(output)
+ {
}
+ }
- #endregion ReceiveFrom Begin/End
+ [Trait("IPv4", "true")]
+ [Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessSendToApm : DualModeConnectionlessSendToBase
+ {
+ public DualModeConnectionlessSendToApm(ITestOutputHelper output) : base(output)
+ {
+ }
}
- [OuterLoop]
[Trait("IPv4", "true")]
[Trait("IPv6", "true")]
- public class DualModeConnectionlessReceiveFromAsync : DualModeBase
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessSendToEap : DualModeConnectionlessSendToBase
{
- #region ReceiveFrom Async/Event
+ public DualModeConnectionlessSendToEap(ITestOutputHelper output) : base(output)
+ {
+ }
+ }
- [Fact] // Base case
- // "The supplied EndPoint of AddressFamily InterNetwork is not valid for this Socket, use InterNetworkV6 instead."
- public void Socket_ReceiveFromAsyncV4IPEndPointFromV4Client_Throws()
+ [Trait("IPv4", "true")]
+ [Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessSendToTask : DualModeConnectionlessSendToBase
+ {
+ public DualModeConnectionlessSendToTask(ITestOutputHelper output) : base(output)
{
- using (Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp))
- {
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
- args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, UnusedPort);
- args.SetBuffer(new byte[1], 0, 1);
+ }
+ }
- AssertExtensions.Throws("e", () =>
- {
- socket.ReceiveFromAsync(args);
- });
- }
+ public abstract class DualModeConnectionlessReceiveFromBase : SocketTestHelperBase where T : SocketHelperBase, new()
+ {
+ protected DualModeConnectionlessReceiveFromBase(ITestOutputHelper output) : base(output)
+ {
}
[Fact] // Base case
- // "The parameter remoteEP must not be of type DnsEndPoint."
- public void Socket_ReceiveFromAsyncDnsEndPoint_Throws()
+ public async Task Socket_ReceiveFromV4IPEndPointFromV4Client_Throws()
{
- using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- int port = socket.BindToAnonymousPort(IPAddress.IPv6Loopback);
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
- args.RemoteEndPoint = new DnsEndPoint("localhost", port, AddressFamily.InterNetworkV6);
- args.SetBuffer(new byte[1], 0, 1);
+ // "The supplied EndPoint of AddressFamily InterNetwork is not valid for this Socket, use InterNetworkV6 instead."
+ using Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
+ socket.DualMode = false;
- AssertExtensions.Throws("remoteEP", () =>
- {
- socket.ReceiveFromAsync(args);
- });
- }
+ EndPoint receivedFrom = new IPEndPoint(IPAddress.Loopback, DualModeBase.UnusedPort);
+ await Assert.ThrowsAsync(() => ReceiveFromAsync(socket, new byte[1], receivedFrom));
}
- [Fact]
- public void ReceiveFromAsyncV4BoundToSpecificV4_Success()
+ [Fact] // Base case
+ public async Task Socket_ReceiveFromDnsEndPoint_Throws()
{
- ReceiveFromAsync_Helper(IPAddress.Loopback, IPAddress.Loopback);
+ // "The parameter remoteEP must not be of type DnsEndPoint."
+ using Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp);
+
+ int port = socket.BindToAnonymousPort(IPAddress.IPv6Loopback);
+ EndPoint receivedFrom = new DnsEndPoint("localhost", port, AddressFamily.InterNetworkV6);
+ await AssertExtensions.ThrowsAsync("remoteEP", () => ReceiveFromAsync(socket, new byte[1], receivedFrom));
}
[Fact]
- public void ReceiveFromAsyncV4BoundToAnyV4_Success()
- {
- ReceiveFromAsync_Helper(IPAddress.Any, IPAddress.Loopback);
- }
+ public Task ReceiveFromV4BoundToSpecificV4_Success() => ReceiveFrom_Success_Helper(IPAddress.Loopback, IPAddress.Loopback);
[Fact]
- public void ReceiveFromAsyncV6BoundToSpecificV6_Success()
- {
- ReceiveFromAsync_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
- }
+ public Task ReceiveFromV4BoundToAnyV4_Success() => ReceiveFrom_Success_Helper(IPAddress.Any, IPAddress.Loopback);
[Fact]
- public void ReceiveFromAsyncV6BoundToAnyV6_Success()
- {
- ReceiveFromAsync_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
- }
+ public Task ReceiveFromV6BoundToSpecificV6_Success() => ReceiveFrom_Success_Helper(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback);
[Fact]
- public void ReceiveFromAsyncV6BoundToSpecificV4_NotReceived()
- {
- Assert.Throws(() =>
- {
- ReceiveFromAsync_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, expectedToTimeout: true);
- });
- }
+ public Task ReceiveFromV6BoundToAnyV6_Success() => ReceiveFrom_Success_Helper(IPAddress.IPv6Any, IPAddress.IPv6Loopback);
[Fact]
- public void ReceiveFromAsyncV4BoundToSpecificV6_NotReceived()
- {
- Assert.Throws(() =>
- {
- ReceiveFromAsync_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, expectedToTimeout: true);
- });
- }
+ public Task ReceiveFromV4BoundToAnyV6_Success() => ReceiveFrom_Success_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
[Fact]
- public void ReceiveFromAsyncV6BoundToAnyV4_NotReceived()
- {
- Assert.Throws(() =>
- {
- ReceiveFromAsync_Helper(IPAddress.Any, IPAddress.IPv6Loopback, expectedToTimeout: true);
- });
- }
+ // Binds to a specific port on 'connectTo' which on Unix may already be in use
+ // Also ReceiveFrom not supported on OSX
+ [PlatformSpecific(TestPlatforms.Windows)]
+ public Task ReceiveFromV6BoundToSpecificV4_NotReceived() => ReceiveFrom_Failure_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback);
+
+ [Fact]
+ // Binds to a specific port on 'connectTo' which on Unix may already be in use
+ // Also expected behavior is different on OSX and Linux (ArgumentException instead of SocketException)
+ [PlatformSpecific(TestPlatforms.Windows)]
+ public Task ReceiveFromV4BoundToSpecificV6_NotReceived() => ReceiveFrom_Failure_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback);
[Fact]
- public void ReceiveFromAsyncV4BoundToAnyV6_Success()
+ // Binds to a specific port on 'connectTo' which on Unix may already be in use
+ // Also ReceiveFrom not supported on OSX
+ [PlatformSpecific(TestPlatforms.Windows)]
+ public Task ReceiveFromV6BoundToAnyV4_NotReceived() => ReceiveFrom_Failure_Helper(IPAddress.Any, IPAddress.IPv6Loopback);
+
+ protected async Task ReceiveFrom_Success_Helper(IPAddress listenOn, IPAddress connectTo)
{
- ReceiveFromAsync_Helper(IPAddress.IPv6Any, IPAddress.Loopback);
+ using Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
+ int port = serverSocket.BindToAnonymousPort(listenOn);
+
+ Socket client = new Socket(connectTo.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
+ Task sendTask = client.SendToAsync(new byte[1], new IPEndPoint(connectTo, port))
+ .WaitAsync(TestSettings.PassingTestTimeout);
+
+ var result = await ReceiveFromAsync(serverSocket, new byte[1], new IPEndPoint(connectTo, port))
+ .WaitAsync(TestSettings.PassingTestTimeout);
+
+ Assert.Equal(1, result.ReceivedBytes);
+ IPEndPoint remoteEndPoint = Assert.IsType(result.RemoteEndPoint);
+ Assert.Equal(AddressFamily.InterNetworkV6, remoteEndPoint.AddressFamily);
+ Assert.Equal(connectTo.MapToIPv6(), remoteEndPoint.Address);
}
- private void ReceiveFromAsync_Helper(IPAddress listenOn, IPAddress connectTo, bool expectedToTimeout = false)
+ protected async Task ReceiveFrom_Failure_Helper(IPAddress listenOn, IPAddress connectTo)
{
- using (Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp))
- {
- int port = serverSocket.BindToAnonymousPort(listenOn);
-
- ManualResetEvent waitHandle = new ManualResetEvent(false);
+ using Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);
+ int port = serverSocket.BindToAnonymousPort(listenOn);
- SocketAsyncEventArgs args = new SocketAsyncEventArgs();
- args.RemoteEndPoint = new IPEndPoint(listenOn, port);
- args.SetBuffer(new byte[1], 0, 1);
- args.UserToken = waitHandle;
- args.Completed += AsyncCompleted;
+ Socket client = new Socket(connectTo.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
+ _ = client.SendToAsync(new byte[1], new IPEndPoint(connectTo, port)).WaitAsync(TestSettings.PassingTestTimeout);
+ await Assert.ThrowsAsync(() => ReceiveFromAsync(serverSocket, new byte[1], new IPEndPoint(connectTo, port))
+ .WaitAsync(TestSettings.FailingTestTimeout));
+ }
+ }
- bool async = serverSocket.ReceiveFromAsync(args);
- SocketUdpClient client = new SocketUdpClient(_log, serverSocket, connectTo, port);
- if (async && !waitHandle.WaitOne(expectedToTimeout ? TestSettings.FailingTestTimeout : TestSettings.PassingTestTimeout))
- {
- throw new TimeoutException();
- }
+ [Trait("IPv4", "true")]
+ [Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessReceiveFromSync : DualModeConnectionlessReceiveFromBase
+ {
+ public DualModeConnectionlessReceiveFromSync(ITestOutputHelper output) : base(output)
+ {
+ }
+ }
- if (args.SocketError != SocketError.Success)
- {
- throw new SocketException((int)args.SocketError);
- }
+ [Trait("IPv4", "true")]
+ [Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessReceiveFromApm : DualModeConnectionlessReceiveFromBase
+ {
+ public DualModeConnectionlessReceiveFromApm(ITestOutputHelper output) : base(output)
+ {
+ }
+ }
- Assert.Equal(1, args.BytesTransferred);
- Assert.Equal(typeof(IPEndPoint), args.RemoteEndPoint.GetType());
- IPEndPoint remoteEndPoint = args.RemoteEndPoint as IPEndPoint;
- Assert.Equal(AddressFamily.InterNetworkV6, remoteEndPoint.AddressFamily);
- Assert.Equal(connectTo.MapToIPv6(), remoteEndPoint.Address);
- }
+ [Trait("IPv4", "true")]
+ [Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessReceiveFromEap : DualModeConnectionlessReceiveFromBase
+ {
+ public DualModeConnectionlessReceiveFromEap(ITestOutputHelper output) : base(output)
+ {
}
+ }
- #endregion ReceiveFrom Async/Event
+ [Trait("IPv4", "true")]
+ [Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
+ public class DualModeConnectionlessReceiveFromTask : DualModeConnectionlessReceiveFromBase
+ {
+ public DualModeConnectionlessReceiveFromTask(ITestOutputHelper output) : base(output)
+ {
+ }
}
- [OuterLoop]
[Trait("IPv4", "true")]
[Trait("IPv6", "true")]
+ [Collection(nameof(DisableParallelization))]
public class DualModeConnectionlessReceiveMessageFrom : DualModeBase
{
[Fact]
@@ -2356,12 +1703,12 @@ public void BeginReceiveMessageFrom_NotSupported()
public class DualModeBase
{
// Ports 8 and 8887 are unassigned as per https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
- protected const int UnusedPort = 8;
+ internal const int UnusedPort = 8;
protected const int UnusedBindablePort = 8887;
protected readonly ITestOutputHelper _log;
- protected static IPAddress[] ValidIPv6Loopbacks = new IPAddress[] {
+ internal static IPAddress[] ValidIPv6Loopbacks = new IPAddress[] {
new IPAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1 }, 0), // ::127.0.0.1
IPAddress.Loopback.MapToIPv6(), // ::ffff:127.0.0.1
IPAddress.IPv6Loopback // ::1
@@ -2442,10 +1789,11 @@ protected static void AssertDualModeEnabled(Socket socket, IPAddress listenOn)
protected class SocketServer : IDisposable
{
private readonly ITestOutputHelper _output;
- private Socket _server;
private Socket _acceptedSocket;
private EventWaitHandle _waitHandle = new AutoResetEvent(false);
+ public Socket Socket { get; }
+
public EventWaitHandle WaitHandle
{
get { return _waitHandle; }
@@ -2457,24 +1805,27 @@ public SocketServer(ITestOutputHelper output, IPAddress address, bool dualMode,
if (dualMode)
{
- _server = new Socket(SocketType.Stream, ProtocolType.Tcp);
+ Socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
}
else
{
- _server = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+ Socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
- port = _server.BindToAnonymousPort(address);
- _server.Listen(1);
+ port = Socket.BindToAnonymousPort(address);
+ Socket.Listen(1);
+ }
- IPAddress remoteAddress = address.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any;
+ public void Start()
+ {
+ IPAddress remoteAddress = Socket.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any;
EndPoint remote = new IPEndPoint(remoteAddress, 0);
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.RemoteEndPoint = remote;
e.Completed += new EventHandler(Accepted);
e.UserToken = _waitHandle;
- _server.AcceptAsync(e);
+ Socket.AcceptAsync(e);
}
private void Accepted(object sender, SocketAsyncEventArgs e)
@@ -2493,7 +1844,7 @@ public void Dispose()
{
try
{
- _server.Dispose();
+ Socket.Dispose();
if (_acceptedSocket != null)
_acceptedSocket.Dispose();
}
@@ -2501,77 +1852,6 @@ public void Dispose()
}
}
- protected class SocketClient
- {
- private IPAddress _connectTo;
- private Socket _serverSocket;
- private int _port;
- private readonly ITestOutputHelper _output;
-
- private EventWaitHandle _waitHandle = new AutoResetEvent(false);
- public EventWaitHandle WaitHandle
- {
- get { return _waitHandle; }
- }
-
- public SocketError Error
- {
- get;
- private set;
- }
-
- public SocketClient(ITestOutputHelper output, Socket serverSocket, IPAddress connectTo, int port)
- {
- _output = output;
- _connectTo = connectTo;
- _serverSocket = serverSocket;
- _port = port;
- Error = SocketError.Success;
-
- Task.Run(() => ConnectClient(null));
- }
-
- private void ConnectClient(object state)
- {
- try
- {
- Socket socket = new Socket(_connectTo.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-
- SocketAsyncEventArgs e = new SocketAsyncEventArgs();
- e.Completed += new EventHandler(Connected);
- e.RemoteEndPoint = new IPEndPoint(_connectTo, _port);
- e.UserToken = _waitHandle;
-
- if (!socket.ConnectAsync(e))
- {
- Connected(socket, e);
- }
- }
- catch (SocketException ex)
- {
- Error = ex.SocketErrorCode;
- Thread.Sleep(TestSettings.FailingTestTimeout); // Give the other end a chance to call Accept().
- _serverSocket.Dispose(); // Cancels the test
- _waitHandle.Set();
- }
- }
- private void Connected(object sender, SocketAsyncEventArgs e)
- {
- EventWaitHandle handle = (EventWaitHandle)e.UserToken;
- _output.WriteLine(
- "Connected: " + e.GetHashCode() + " SocketAsyncEventArgs with manual event " +
- handle.GetHashCode() + " error: " + e.SocketError);
-
- Error = e.SocketError;
- if (Error != SocketError.Success)
- {
- Thread.Sleep(TestSettings.FailingTestTimeout); // Give the other end a chance to call Accept().
- _serverSocket.Dispose(); // Cancels the test
- }
- handle.Set();
- }
- }
-
protected class SocketUdpServer : IDisposable
{
private readonly ITestOutputHelper _output;
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs
index b94fe8cdeb0c4f..e096d536fa4b96 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive/SendReceive.cs
@@ -892,14 +892,14 @@ public async Task ReceiveAsync_ConcurrentDispose_SucceedsOrThrowsAppropriateExce
{
b.SignalAndWait();
client.Dispose();
- }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).WaitAsync(TestSettings.PassingTestTimeout);
Task send = Task.Factory.StartNew(() =>
{
SendAsync(server, new ArraySegment(new byte[1])).GetAwaiter().GetResult();
b.SignalAndWait();
ReceiveAsync(client, new ArraySegment(new byte[1])).GetAwaiter().GetResult();
- }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
+ }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).WaitAsync(TestSettings.PassingTestTimeout);
await dispose;
Exception error = await Record.ExceptionAsync(() => send);