diff --git a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs index edc12fcff897..1698209be2c8 100644 --- a/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs @@ -6,6 +6,8 @@ using System.Net; using System.Net.Security; using System.Net.Sockets; +using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -25,7 +27,6 @@ internal class SNITCPHandle : SNIHandle private readonly TaskFactory _writeTaskFactory; private Stream _stream; - private TcpClient _tcpClient; private SslStream _sslStream; private SslOverTdsStream _sslOverTdsStream; private SNIAsyncCallback _receiveCallback; @@ -56,12 +57,6 @@ public override void Dispose() _sslStream.Dispose(); _sslStream = null; } - - if (_tcpClient != null) - { - _tcpClient.Dispose(); - _tcpClient = null; - } } } @@ -103,8 +98,6 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba try { - _tcpClient = new TcpClient(); - TimeSpan ts; // In case the Timeout is Infinite, we will receive the max value of Int64 as the tick count @@ -116,7 +109,7 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba ts = ts.Ticks < 0 ? TimeSpan.FromTicks(0) : ts; } - Task connectTask; + Task connectTask; if (parallel) { Task serverAddrTask = Dns.GetHostAddressesAsync(serverName); @@ -130,11 +123,11 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba return; } - connectTask = _tcpClient.ConnectAsync(serverAddresses, port); + connectTask = ConnectAsync(serverAddresses, port); } else { - connectTask = _tcpClient.ConnectAsync(serverName, port); + connectTask = ConnectAsync(serverName, port); } if (!(isInfiniteTimeOut ? connectTask.Wait(-1) : connectTask.Wait(ts))) @@ -143,9 +136,9 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba return; } - _tcpClient.NoDelay = true; - _tcpStream = _tcpClient.GetStream(); - _socket = _tcpClient.Client; + _socket = connectTask.Result; + _socket.NoDelay = true; + _tcpStream = new NetworkStream(_socket, true); _sslOverTdsStream = new SslOverTdsStream(_tcpStream); _sslStream = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); @@ -165,6 +158,70 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba _status = TdsEnums.SNI_SUCCESS; } + private static async Task ConnectAsync(string serverName, int port) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + await socket.ConnectAsync(serverName, port).ConfigureAwait(false); + return socket; + } + + // On unix we can't use the instance Socket methods that take multiple endpoints + + IPAddress[] addresses = await Dns.GetHostAddressesAsync(serverName).ConfigureAwait(false); + return await ConnectAsync(addresses, port).ConfigureAwait(false); + } + + private static async Task ConnectAsync(IPAddress[] serverAddresses, int port) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + await socket.ConnectAsync(serverAddresses, port).ConfigureAwait(false); + return socket; + } + + // On unix we can't use the instance Socket methods that take multiple endpoints + + if (serverAddresses == null) + { + throw new ArgumentNullException("serverAddresses"); + } + if (serverAddresses.Length == 0) + { + throw new ArgumentOutOfRangeException("serverAddresses"); + } + + // Try each address in turn, and return the socket opened for the first one that works. + ExceptionDispatchInfo lastException = null; + foreach (IPAddress address in serverAddresses) + { + var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + try + { + await socket.ConnectAsync(address, port).ConfigureAwait(false); + return socket; + } + catch (Exception exc) + { + socket.Dispose(); + lastException = ExceptionDispatchInfo.Capture(exc); + } + } + + // Propagate the last failure that occurrred + if (lastException != null) + { + lastException.Throw(); + } + + // Should never get here. Either there will have been no addresses and we'll have thrown + // at the beginning, or one of the addresses will have worked and we'll have returned, or + // at least one of the addresses will failed, in which case we will have propagated that. + throw new ArgumentException(); + } + /// /// Enable SSL /// @@ -276,11 +333,11 @@ public override uint Receive(out SNIPacket packet, int timeoutInMilliseconds) { if (timeoutInMilliseconds > 0) { - _tcpClient.ReceiveTimeout = timeoutInMilliseconds; + _socket.ReceiveTimeout = timeoutInMilliseconds; } else if (timeoutInMilliseconds == -1) { // SqlCient internally represents infinite timeout by -1, and for TcpClient this is translated to a timeout of 0 - _tcpClient.ReceiveTimeout = 0; + _socket.ReceiveTimeout = 0; } else { @@ -320,7 +377,7 @@ public override uint Receive(out SNIPacket packet, int timeoutInMilliseconds) } finally { - _tcpClient.ReceiveTimeout = 0; + _socket.ReceiveTimeout = 0; } } } diff --git a/src/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 2c520290ca5e..e52dba0504cb 100644 --- a/src/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -142,9 +142,8 @@ private Task ClientAsyncSslHelper(SslProtocols clientSslProtocols, SslProtocols Assert.True(((IAsyncResult)async).AsyncWaitHandle.WaitOne(TestConfiguration.PassingTestTimeoutMilliseconds), "Timed Out"); async.GetAwaiter().GetResult(); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + server.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); } diff --git a/src/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs b/src/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs index a0462a54c5f8..99d72b89c589 100644 --- a/src/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs @@ -45,9 +45,8 @@ public async Task ClientDefaultEncryption_ServerRequireEncryption_ConnectWithEnc using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverRequireEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); } @@ -66,9 +65,8 @@ public async Task ClientDefaultEncryption_ServerAllowNoEncryption_ConnectWithEnc using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); } diff --git a/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs b/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs index 41ef597996e6..a24d0358ff2c 100644 --- a/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs +++ b/src/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs @@ -96,8 +96,7 @@ private void OnAuthenticate(Task result, ClientState state) try { result.GetAwaiter().GetResult(); - _log.WriteLine("Server({0}) authenticated to client({1}) with encryption cipher: {2} {3}-bit strength", - state.TcpClient.Client.LocalEndPoint, state.TcpClient.Client.RemoteEndPoint, + _log.WriteLine("Server authenticated to client with encryption cipher: {0} {1}-bit strength", sslStream.CipherAlgorithm, sslStream.CipherStrength); // Start listening for data from the client connection. @@ -106,15 +105,13 @@ private void OnAuthenticate(Task result, ClientState state) catch (AuthenticationException authEx) { _log.WriteLine( - "Server({0}) disconnecting from client({1}) during authentication. No shared SSL/TLS algorithm. ({2})", - state.TcpClient.Client.LocalEndPoint, - state.TcpClient.Client.RemoteEndPoint, + "Server disconnecting from client during authentication. No shared SSL/TLS algorithm. ({0})", authEx); } catch (Exception ex) { - _log.WriteLine("Server({0}) disconnecting from client({1}) during authentication. Exception: {2}", - state.TcpClient.Client.LocalEndPoint, state.TcpClient.Client.RemoteEndPoint, ex.Message); + _log.WriteLine("Server disconnecting from client during authentication. Exception: {0}", + ex.Message); } finally { diff --git a/src/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs b/src/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs index d0a4b1b5ddde..917641f68306 100644 --- a/src/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs @@ -44,9 +44,8 @@ public async Task ServerAllowNoEncryption_ClientRequireEncryption_ConnectWithEnc using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); Assert.NotEqual(CipherAlgorithmType.Null, sslStream.CipherAlgorithm); Assert.True(sslStream.CipherStrength > 0); } @@ -65,9 +64,8 @@ public async Task ServerAllowNoEncryption_ClientAllowNoEncryption_ConnectWithEnc using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); Assert.NotEqual(CipherAlgorithmType.Null, sslStream.CipherAlgorithm); Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); } @@ -87,9 +85,8 @@ public async Task ServerAllowNoEncryption_ClientNoEncryption_ConnectWithNoEncryp using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); CipherAlgorithmType expected = CipherAlgorithmType.Null; Assert.Equal(expected, sslStream.CipherAlgorithm); diff --git a/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 05cfdbbd8068..b423600e270d 100644 --- a/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -171,9 +171,8 @@ private static IEnumerable ProtocolMismatchData() } _log.WriteLine( - "Server({0}) authenticated client({1}) with encryption cipher: {2} {3}-bit strength", - serverConnection.Client.LocalEndPoint, - serverConnection.Client.RemoteEndPoint, + "Server({0}) authenticated with encryption cipher: {1} {2}-bit strength", + serverEndPoint, sslServerStream.CipherAlgorithm, sslServerStream.CipherStrength); diff --git a/src/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs b/src/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs index b9a379c00593..f5ae12fddab1 100644 --- a/src/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs @@ -63,9 +63,8 @@ public async Task ServerNoEncryption_ClientAllowNoEncryption_ConnectWithNoEncryp { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); CipherAlgorithmType expected = CipherAlgorithmType.Null; Assert.Equal(expected, sslStream.CipherAlgorithm); @@ -87,9 +86,8 @@ public async Task ServerNoEncryption_ClientNoEncryption_ConnectWithNoEncryption( using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); CipherAlgorithmType expected = CipherAlgorithmType.Null; Assert.Equal(expected, sslStream.CipherAlgorithm); diff --git a/src/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs b/src/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs index e42b65f206ec..0114e9b1f5ee 100644 --- a/src/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs +++ b/src/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs @@ -44,9 +44,8 @@ public async Task ServerRequireEncryption_ClientRequireEncryption_ConnectWithEnc using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverRequireEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); } @@ -65,9 +64,8 @@ public async Task ServerRequireEncryption_ClientAllowNoEncryption_ConnectWithEnc using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) { await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); - _log.WriteLine("Client({0}) authenticated to server({1}) with encryption cipher: {2} {3}-bit strength", - client.Client.LocalEndPoint, client.Client.RemoteEndPoint, - sslStream.CipherAlgorithm, sslStream.CipherStrength); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", + serverRequireEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); } diff --git a/src/System.Net.Sockets.Legacy/tests/FunctionalTests/AgnosticListenerTest.cs b/src/System.Net.Sockets.Legacy/tests/FunctionalTests/AgnosticListenerTest.cs index bc9d95b841d6..fb554d82df7b 100644 --- a/src/System.Net.Sockets.Legacy/tests/FunctionalTests/AgnosticListenerTest.cs +++ b/src/System.Net.Sockets.Legacy/tests/FunctionalTests/AgnosticListenerTest.cs @@ -73,8 +73,6 @@ public void ConnectWithV4AndV6_Success() v6Client.ConnectAsync(IPAddress.IPv6Loopback, port).GetAwaiter().GetResult(); TcpClient acceptedV6Client = listener.EndAcceptTcpClient(asyncResult); - Assert.Equal(AddressFamily.InterNetworkV6, acceptedV6Client.Client.RemoteEndPoint.AddressFamily); - Assert.Equal(AddressFamily.InterNetworkV6, v6Client.Client.RemoteEndPoint.AddressFamily); asyncResult = listener.BeginAcceptTcpClient(null, null); @@ -82,8 +80,6 @@ public void ConnectWithV4AndV6_Success() v4Client.ConnectAsync(IPAddress.Loopback, port).GetAwaiter().GetResult(); TcpClient acceptedV4Client = listener.EndAcceptTcpClient(asyncResult); - Assert.Equal(AddressFamily.InterNetworkV6, acceptedV4Client.Client.RemoteEndPoint.AddressFamily); - Assert.Equal(AddressFamily.InterNetwork, v4Client.Client.RemoteEndPoint.AddressFamily); v6Client.Dispose(); acceptedV6Client.Dispose(); diff --git a/src/System.Net.Sockets.Legacy/tests/FunctionalTests/UdpClientTest.cs b/src/System.Net.Sockets.Legacy/tests/FunctionalTests/UdpClientTest.cs index 934f28a8ef59..507c240ca5cb 100644 --- a/src/System.Net.Sockets.Legacy/tests/FunctionalTests/UdpClientTest.cs +++ b/src/System.Net.Sockets.Legacy/tests/FunctionalTests/UdpClientTest.cs @@ -55,14 +55,6 @@ public void BeginSend_AsyncOperationCompletes_Success() Assert.True(_waitHandle.WaitOne(Configuration.PassingTestTimeout), "Timed out while waiting for connection"); } - [ActiveIssue(4968)] - [Fact] - public void UdpClient_ConnectAsync_Success() - { - var c = new UdpClient(); - c.Client.ConnectAsync("114.114.114.114", 53).Wait(); - } - private void AsyncCompleted(IAsyncResult ar) { UdpClient udpService = (UdpClient)ar.AsyncState; diff --git a/src/System.Net.Sockets/ref/System.Net.Sockets.cs b/src/System.Net.Sockets/ref/System.Net.Sockets.cs index 04cfb222b7d2..519e8662ea00 100644 --- a/src/System.Net.Sockets/ref/System.Net.Sockets.cs +++ b/src/System.Net.Sockets/ref/System.Net.Sockets.cs @@ -417,7 +417,6 @@ public partial class TcpClient : System.IDisposable public TcpClient(System.Net.Sockets.AddressFamily family) { } protected bool Active { get { return default(bool); } set { } } public int Available { get { return default(int); } } - public System.Net.Sockets.Socket Client { get { return default(System.Net.Sockets.Socket); } set { } } public bool Connected { get { return default(bool); } } public bool ExclusiveAddressUse { get { return default(bool); } set { } } public System.Net.Sockets.LingerOption LingerState { get { return default(System.Net.Sockets.LingerOption); } set { } } @@ -458,7 +457,6 @@ public partial class UdpClient : System.IDisposable public UdpClient(System.Net.Sockets.AddressFamily family) { } protected bool Active { get { return default(bool); } set { } } public int Available { get { return default(int); } } - public System.Net.Sockets.Socket Client { get { return default(System.Net.Sockets.Socket); } set { } } public bool DontFragment { get { return default(bool); } set { } } public bool EnableBroadcast { get { return default(bool); } set { } } public bool ExclusiveAddressUse { get { return default(bool); } set { } } diff --git a/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Unix.cs b/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Unix.cs index e4afe8bb2037..23e33035d613 100644 --- a/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Unix.cs +++ b/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Unix.cs @@ -51,7 +51,8 @@ private void InitializeClientSocket() // Nop. We want to lazily-allocate the socket. } - private Socket ClientCore + [DebuggerBrowsable(DebuggerBrowsableState.Never)] // TODO: Remove once https://github.com/dotnet/corefx/issues/5868 is addressed. + private Socket Client { get { @@ -73,19 +74,6 @@ private Socket ClientCore ExitClientLock(); } } - set - { - EnterClientLock(); - try - { - _clientSocket = value; - ClearInitializedValues(); - } - finally - { - ExitClientLock(); - } - } } private void ApplyInitializedOptionsToSocket(Socket socket) @@ -134,25 +122,6 @@ private void ApplyInitializedOptionsToSocket(Socket socket) } } - private void ClearInitializedValues() - { - ShadowOptions so = _shadowOptions; - if (so == null) - { - return; - } - - // Clear the initialized fields for all of our shadow properties. - so._exclusiveAddressUseInitialized = - so._receiveBufferSizeInitialized = - so._sendBufferSizeInitialized = - so._receiveTimeoutInitialized = - so._sendTimeoutInitialized = - so._lingerStateInitialized = - so._noDelayInitialized = - false; - } - private int AvailableCore { get @@ -249,9 +218,9 @@ private async Task ConnectAsyncCorePrivate(IPAddress[] addresses, int port) ExceptionDispatchInfo lastException = null; foreach (IPAddress address in addresses) { + Socket s = CreateSocket(); try { - Socket s = CreateSocket(); ApplyInitializedOptionsToSocket(s); await s.ConnectAsync(address, port).ConfigureAwait(false); @@ -262,6 +231,7 @@ private async Task ConnectAsyncCorePrivate(IPAddress[] addresses, int port) } catch (Exception exc) { + s.Dispose(); lastException = ExceptionDispatchInfo.Capture(exc); } } diff --git a/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Windows.cs b/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Windows.cs index f731959ffa41..154e3a269009 100644 --- a/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Windows.cs +++ b/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.Windows.cs @@ -10,21 +10,10 @@ partial class TcpClient { private void InitializeClientSocket() { - Client = CreateSocket(); + _clientSocket = CreateSocket(); } - // Used by the class to provide the underlying network socket. - private Socket ClientCore - { - get - { - return _clientSocket; - } - set - { - _clientSocket = value; - } - } + private Socket Client { get { return _clientSocket; } } private int AvailableCore { get { return _clientSocket.Available; } } diff --git a/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs b/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs index 6b8c6ebb1657..fae1cd3adddf 100644 --- a/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs +++ b/src/System.Net.Sockets/src/System/Net/Sockets/TCPClient.cs @@ -63,14 +63,6 @@ internal TcpClient(Socket acceptedSocket) } } - // Used by the class to provide the underlying network socket. - [DebuggerBrowsable(DebuggerBrowsableState.Never)] // TODO: Remove once https://github.com/dotnet/corefx/issues/5868 is addressed. - public Socket Client - { - get { return ClientCore; } - set { ClientCore = value; } - } - // Used by the class to indicate that a connection has been made. protected bool Active { @@ -151,14 +143,14 @@ public NetworkStream GetStream() { throw new ObjectDisposedException(this.GetType().FullName); } - if (!Client.Connected) + if (!Connected) { throw new InvalidOperationException(SR.net_notconnected); } if (_dataStream == null) { - _dataStream = new NetworkStream(Client, true); + _dataStream = new NetworkStream(_clientSocket, true); } if (NetEventSource.Log.IsEnabled()) diff --git a/src/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs b/src/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs index 58aeb7be2814..22c7ac49b46f 100644 --- a/src/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs +++ b/src/System.Net.Sockets/src/System/Net/Sockets/UDPClient.cs @@ -79,7 +79,7 @@ public UdpClient(int port, AddressFamily family) CreateClientSocket(); - Client.Bind(localEP); + _clientSocket.Bind(localEP); } // Creates a new instance of the UdpClient class that communicates on the @@ -98,20 +98,7 @@ public UdpClient(IPEndPoint localEP) CreateClientSocket(); - Client.Bind(localEP); - } - - // Used by the class to provide the underlying network socket. - public Socket Client - { - get - { - return _clientSocket; - } - set - { - _clientSocket = value; - } + _clientSocket.Bind(localEP); } // Used by the class to indicate that a connection to a remote host has been made. @@ -207,7 +194,7 @@ private void FreeResources() return; } - Socket chkClientSocket = Client; + Socket chkClientSocket = _clientSocket; if (chkClientSocket != null) { // If the NetworkStream wasn't retrieved, the Socket might @@ -215,7 +202,7 @@ private void FreeResources() // of the Bind() call and free the bound IPEndPoint. chkClientSocket.InternalShutdown(SocketShutdown.Both); chkClientSocket.Dispose(); - Client = null; + _clientSocket = null; } _cleanedUp = true; } @@ -247,12 +234,12 @@ private void CheckForBroadcast(IPAddress ipAddress) // and in that case we set SocketOptionName.Broadcast on the socket to allow its use. // if the user really wants complete control over Broadcast addresses he needs to // inherit from UdpClient and gain control over the Socket and do whatever is appropriate. - if (Client != null && !_isBroadcast && IsBroadcast(ipAddress)) + if (_clientSocket != null && !_isBroadcast && IsBroadcast(ipAddress)) { // We need to set the Broadcast socket option. // Note that once we set the option on the Socket we never reset it. _isBroadcast = true; - Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); + _clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); } } @@ -294,12 +281,12 @@ internal IAsyncResult BeginSend(byte[] datagram, int bytes, IPEndPoint endPoint, if (endPoint == null) { - return Client.BeginSend(datagram, 0, bytes, SocketFlags.None, requestCallback, state); + return _clientSocket.BeginSend(datagram, 0, bytes, SocketFlags.None, requestCallback, state); } CheckForBroadcast(endPoint.Address); - return Client.BeginSendTo(datagram, 0, bytes, SocketFlags.None, endPoint, requestCallback, state); + return _clientSocket.BeginSendTo(datagram, 0, bytes, SocketFlags.None, endPoint, requestCallback, state); } internal IAsyncResult BeginSend(byte[] datagram, int bytes, string hostname, int port, AsyncCallback requestCallback, object state) @@ -346,11 +333,11 @@ internal int EndSend(IAsyncResult asyncResult) if (_active) { - return Client.EndSend(asyncResult); + return _clientSocket.EndSend(asyncResult); } else { - return Client.EndSendTo(asyncResult); + return _clientSocket.EndSendTo(asyncResult); } } @@ -375,7 +362,7 @@ internal IAsyncResult BeginReceive(AsyncCallback requestCallback, object state) tempRemoteEP = IPEndPointStatics.IPv6Any; } - return Client.BeginReceiveFrom(_buffer, 0, MaxUDPSize, SocketFlags.None, ref tempRemoteEP, requestCallback, state); + return _clientSocket.BeginReceiveFrom(_buffer, 0, MaxUDPSize, SocketFlags.None, ref tempRemoteEP, requestCallback, state); } internal byte[] EndReceive(IAsyncResult asyncResult, ref IPEndPoint remoteEP) @@ -395,7 +382,7 @@ internal byte[] EndReceive(IAsyncResult asyncResult, ref IPEndPoint remoteEP) tempRemoteEP = IPEndPointStatics.IPv6Any; } - int received = Client.EndReceiveFrom(asyncResult, ref tempRemoteEP); + int received = _clientSocket.EndReceiveFrom(asyncResult, ref tempRemoteEP); remoteEP = (IPEndPoint)tempRemoteEP; // Because we don't return the actual length, we need to ensure the returned buffer @@ -435,7 +422,7 @@ public void JoinMulticastGroup(IPAddress multicastAddr) { MulticastOption mcOpt = new MulticastOption(multicastAddr); - Client.SetSocketOption( + _clientSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.AddMembership, mcOpt); @@ -444,7 +431,7 @@ public void JoinMulticastGroup(IPAddress multicastAddr) { IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr); - Client.SetSocketOption( + _clientSocket.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mcOpt); @@ -466,7 +453,7 @@ public void JoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress) MulticastOption mcOpt = new MulticastOption(multicastAddr, localAddress); - Client.SetSocketOption( + _clientSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.AddMembership, mcOpt); @@ -500,7 +487,7 @@ public void JoinMulticastGroup(int ifindex, IPAddress multicastAddr) IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr, ifindex); - Client.SetSocketOption( + _clientSocket.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.AddMembership, mcOpt); @@ -527,7 +514,7 @@ public void JoinMulticastGroup(IPAddress multicastAddr, int timeToLive) JoinMulticastGroup(multicastAddr); // Set Time To Live (TTL). - Client.SetSocketOption( + _clientSocket.SetSocketOption( (_family == AddressFamily.InterNetwork) ? SocketOptionLevel.IP : SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive, timeToLive); @@ -557,7 +544,7 @@ public void DropMulticastGroup(IPAddress multicastAddr) { MulticastOption mcOpt = new MulticastOption(multicastAddr); - Client.SetSocketOption( + _clientSocket.SetSocketOption( SocketOptionLevel.IP, SocketOptionName.DropMembership, mcOpt); @@ -566,7 +553,7 @@ public void DropMulticastGroup(IPAddress multicastAddr) { IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr); - Client.SetSocketOption( + _clientSocket.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mcOpt); @@ -601,7 +588,7 @@ public void DropMulticastGroup(IPAddress multicastAddr, int ifindex) IPv6MulticastOption mcOpt = new IPv6MulticastOption(multicastAddr, ifindex); - Client.SetSocketOption( + _clientSocket.SetSocketOption( SocketOptionLevel.IPv6, SocketOptionName.DropMembership, mcOpt); @@ -667,7 +654,7 @@ private void CreateClientSocket() // Common initialization code. // // IPv6 Changes: Use the AddressFamily of this class rather than hardcode. - Client = new Socket(_family, SocketType.Dgram, ProtocolType.Udp); + _clientSocket = new Socket(_family, SocketType.Dgram, ProtocolType.Udp); } } } diff --git a/src/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs b/src/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs index ad8a198d6fa4..b782ce83e2d0 100644 --- a/src/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs +++ b/src/System.Net.Sockets/tests/FunctionalTests/ArgumentValidationTests.cs @@ -758,27 +758,5 @@ public void Socket_ConnectAsync_MultipleAddresses_NotSupported() Assert.Throws(() => { s.ConnectAsync(new[] { IPAddress.Loopback }, 12345); }); } } - - [Fact] - [PlatformSpecific(PlatformID.AnyUnix)] - public void TcpClient_ConnectAsync_StringHost_NotSupportedAfterClientAccess() - { - using (TcpClient client = new TcpClient()) - { - var tmp = client.Client; - Assert.Throws(() => { client.ConnectAsync("localhost", 12345); }); - } - } - - [Fact] - [PlatformSpecific(PlatformID.AnyUnix)] - public void TcpClient_ConnectAsync_MultipleAddresses_NotSupportedAfterClientAccess() - { - using (TcpClient client = new TcpClient()) - { - var tmp = client.Client; - Assert.Throws(() => { client.ConnectAsync(new[] { IPAddress.Loopback }, 12345); }); - } - } } } diff --git a/src/System.Net.Sockets/tests/FunctionalTests/SendReceive.cs b/src/System.Net.Sockets/tests/FunctionalTests/SendReceive.cs index 7bb6b0dba6a0..562eafd195a7 100644 --- a/src/System.Net.Sockets/tests/FunctionalTests/SendReceive.cs +++ b/src/System.Net.Sockets/tests/FunctionalTests/SendReceive.cs @@ -126,77 +126,6 @@ private static void SendToRecvFromAsync_Datagram_UDP(IPAddress leftAddress, IPAd } } - private static void SendToRecvFromAsync_UdpClient_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress) - { - const int DatagramSize = 256; - const int DatagramsToSend = 256; - const int AckTimeout = 1000; - const int TestTimeout = 30000; - - var left = new UdpClient(new IPEndPoint(leftAddress, 0)); - var right = new UdpClient(new IPEndPoint(rightAddress, 0)); - - var leftEndpoint = (IPEndPoint)left.Client.LocalEndPoint; - var rightEndpoint = (IPEndPoint)right.Client.LocalEndPoint; - - var receiverAck = new ManualResetEventSlim(); - var senderAck = new ManualResetEventSlim(); - - var receivedChecksums = new uint?[DatagramsToSend]; - int receivedDatagrams = 0; - - Task receiverTask = Task.Run(async () => - { - for (; receivedDatagrams < DatagramsToSend; receivedDatagrams++) - { - UdpReceiveResult result = await left.ReceiveAsync(); - - receiverAck.Set(); - Assert.True(senderAck.Wait(AckTimeout)); - senderAck.Reset(); - - Assert.Equal(DatagramSize, result.Buffer.Length); - Assert.Equal(rightEndpoint, result.RemoteEndPoint); - - int datagramId = (int)result.Buffer[0]; - Assert.Null(receivedChecksums[datagramId]); - - receivedChecksums[datagramId] = Fletcher32.Checksum(result.Buffer, 0, result.Buffer.Length); - } - }); - - var sentChecksums = new uint[DatagramsToSend]; - int sentDatagrams = 0; - - Task senderTask = Task.Run(async () => - { - var random = new Random(); - var sendBuffer = new byte[DatagramSize]; - - for (; sentDatagrams < DatagramsToSend; sentDatagrams++) - { - random.NextBytes(sendBuffer); - sendBuffer[0] = (byte)sentDatagrams; - - int sent = await right.SendAsync(sendBuffer, DatagramSize, leftEndpoint); - - Assert.True(receiverAck.Wait(AckTimeout)); - receiverAck.Reset(); - senderAck.Set(); - - Assert.Equal(DatagramSize, sent); - sentChecksums[sentDatagrams] = Fletcher32.Checksum(sendBuffer, 0, sent); - } - }); - - Assert.True(Task.WaitAll(new[] { receiverTask, senderTask }, TestTimeout)); - for (int i = 0; i < DatagramsToSend; i++) - { - Assert.NotNull(receivedChecksums[i]); - Assert.Equal(sentChecksums[i], (uint)receivedChecksums[i]); - } - } - private static void SendRecvAsync_Stream_TCP(IPAddress listenAt, bool useMultipleBuffers) { const int BytesToSend = 123456; @@ -464,20 +393,6 @@ public void SendToRecvFromAsync_Single_Datagram_UDP_IPv4() SendToRecvFromAsync_Datagram_UDP(IPAddress.Loopback, IPAddress.Loopback); } - [ActiveIssue(5411, PlatformID.Windows)] - [Fact] - public void SendToRecvFromAsync_UdpClient_Single_Datagram_UDP_IPv6() - { - SendToRecvFromAsync_UdpClient_Datagram_UDP(IPAddress.IPv6Loopback, IPAddress.IPv6Loopback); - } - - [ActiveIssue(5411, PlatformID.Windows)] - [Fact] - public void SendToRecvFromAsync_UdpClient_Single_Datagram_UDP_IPv4() - { - SendToRecvFromAsync_UdpClient_Datagram_UDP(IPAddress.Loopback, IPAddress.Loopback); - } - [Fact] public void SendRecvAsync_Multiple_Stream_TCP_IPv6() { diff --git a/src/System.Net.Sockets/tests/FunctionalTests/TcpClientTest.cs b/src/System.Net.Sockets/tests/FunctionalTests/TcpClientTest.cs index 4538f890d7d5..0e5ac62979dc 100644 --- a/src/System.Net.Sockets/tests/FunctionalTests/TcpClientTest.cs +++ b/src/System.Net.Sockets/tests/FunctionalTests/TcpClientTest.cs @@ -46,8 +46,6 @@ public async Task Connect_DnsEndPoint_Success(int mode) } Assert.True(client.Connected); - Assert.NotNull(client.Client); - Assert.Same(client.Client, client.Client); using (NetworkStream s = client.GetStream()) {