make sure TcpClient is properly initialized when using name in ctor (#47058)
authorTomas Weinfurt <tweinfurt@yahoo.com>
Tue, 9 Feb 2021 00:27:43 +0000 (16:27 -0800)
committerGitHub <noreply@github.com>
Tue, 9 Feb 2021 00:27:43 +0000 (16:27 -0800)
* make sure TcpClient is properly initialized when using name in ctor

* add client.Dispose

* feedback from review

* feedback from review

* feedback from review

src/libraries/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/TcpClientTest.cs

index 0149040..06723ad 100644 (file)
@@ -74,6 +74,8 @@ namespace System.Net.Sockets
                 throw new ArgumentOutOfRangeException(nameof(port));
             }
 
+            _family = AddressFamily.Unknown;
+
             try
             {
                 Connect(hostname, port);
@@ -171,6 +173,11 @@ namespace System.Net.Sockets
                             if ((address.AddressFamily == AddressFamily.InterNetwork && Socket.OSSupportsIPv4) || Socket.OSSupportsIPv6)
                             {
                                 var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+                                if (address.IsIPv4MappedToIPv6)
+                                {
+                                    socket.DualMode = true;
+                                }
+
                                 // Use of Interlocked.Exchanged ensures _clientSocket is written before Disposed is read.
                                 Interlocked.Exchange(ref _clientSocket!, socket);
                                 if (Disposed)
index 458e7f7..3223a64 100644 (file)
@@ -493,6 +493,34 @@ namespace System.Net.Sockets.Tests
             }
         }
 
+        [Theory]
+        [InlineData(false, "::ffff:127.0.0.1")]
+        [InlineData(false, "127.0.0.1")]
+        [InlineData(false, "localhost")]
+        [InlineData(true, "::1")]
+        public void CtorConnect_Success(bool useIPv6, string connectString)
+        {
+            if (!Socket.OSSupportsIPv6)
+            {
+                return;
+            }
+
+            IPAddress serverAddress = useIPv6 ? IPAddress.IPv6Loopback : IPAddress.Loopback;
+
+            using (var server = new Socket(serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
+            {
+                // Set up a server socket to which to connect
+                server.Bind(new IPEndPoint(serverAddress, 0));
+                server.Listen(1);
+                var endpoint = (IPEndPoint)server.LocalEndPoint;
+
+                using (TcpClient client = new TcpClient(connectString, endpoint.Port))
+                {
+                    Assert.True(client.Connected);
+                }
+            }
+        }
+
         private sealed class DerivedTcpClient : TcpClient
         {
             public new bool Active