Fix static Socket.ConnectAsync for DnsEndPoint containing IPv6-mapped address string...
authorAnton Firszov <Anton.Firszov@microsoft.com>
Fri, 23 Jul 2021 15:37:13 +0000 (17:37 +0200)
committerGitHub <noreply@github.com>
Fri, 23 Jul 2021 15:37:13 +0000 (17:37 +0200)
Fixes #56099

src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/DnsEndPointTest.cs

index 699a447..1035c27 100644 (file)
@@ -710,6 +710,11 @@ namespace System.Net.Sockets
                             if (address.AddressFamily == AddressFamily.InterNetworkV6)
                             {
                                 attemptSocket = tempSocketIPv6 ??= (Socket.OSSupportsIPv6 ? new Socket(AddressFamily.InterNetworkV6, socketType, protocolType) : null);
+                                if (attemptSocket is not null && address.IsIPv4MappedToIPv6)
+                                {
+                                    // We need a DualMode socket to connect to an IPv6-mapped IPv4 address.
+                                    attemptSocket.DualMode = true;
+                                }
                             }
                             else if (address.AddressFamily == AddressFamily.InterNetwork)
                             {
index be8cdea..1e362a0 100644 (file)
@@ -363,6 +363,30 @@ namespace System.Net.Sockets.Tests
             }
         }
 
+        [Fact]
+        public void Socket_StaticConnectAsync_IPv6MappedIPv4_Success()
+        {
+            using SocketTestServer server = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback, out int port);
+
+            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
+            args.RemoteEndPoint = new DnsEndPoint("[::FFFF:127.0.0.1]", port);
+            args.Completed += OnConnectAsyncCompleted;
+
+            ManualResetEvent complete = new ManualResetEvent(false);
+            args.UserToken = complete;
+
+            if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, args))
+            {
+                Assert.True(complete.WaitOne(TestSettings.PassingTestTimeout), "Timed out while waiting for connection");
+            }
+
+            Assert.Equal(SocketError.Success, args.SocketError);
+            Assert.Null(args.ConnectByNameError);
+            Assert.NotNull(args.ConnectSocket);
+            Assert.True(args.ConnectSocket.Connected);
+            args.ConnectSocket.Dispose();
+        }
+
         [OuterLoop]
         [Fact]
         public void Socket_StaticConnectAsync_HostNotFound()