private async Task AcceptClientConnectionsAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    var clientSocket = await PlatformAbstractionLayer.AcceptAsync(_socket).ConfigureAwait(false);

                    if (clientSocket == null)
                    {
                        continue;
                    }

                    Task.Run(() => TryHandleClientConnectionAsync(clientSocket), cancellationToken).Forget(_logger);
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception exception)
                {
                    if (exception is SocketException socketException)
                    {
                        if (socketException.SocketErrorCode == SocketError.ConnectionAborted ||
                            socketException.SocketErrorCode == SocketError.OperationAborted)
                        {
                            continue;
                        }
                    }

                    _logger.Error(exception, $"Error while accepting connection at TCP listener {_localEndPoint} TLS={_tlsCertificate != null}.");
                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
                }
            }
        }
示例#2
0
        public async Task ConnectAsync(CancellationToken cancellationToken)
        {
            Socket socket;

            if (_options.AddressFamily == AddressFamily.Unspecified)
            {
                socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
            }
            else
            {
                socket = new Socket(_options.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            }

            socket.ReceiveBufferSize = _options.BufferSize;
            socket.SendBufferSize    = _options.BufferSize;
            socket.NoDelay           = _options.NoDelay;

            if (_options.DualMode.HasValue)
            {
                // It is important to avoid setting the flag if no specific value is set by the user
                // because on IPv4 only networks the setter will always throw an exception. Regardless
                // of the actual value.
                socket.DualMode = _options.DualMode.Value;
            }

            // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430
            using (cancellationToken.Register(() => socket.Dispose()))
            {
                await PlatformAbstractionLayer.ConnectAsync(socket, _options.Server, _options.GetPort()).ConfigureAwait(false);
            }

            var networkStream = new NetworkStream(socket, true);

            if (_options.TlsOptions.UseTls)
            {
                var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback);
                _stream = sslStream;

                await sslStream.AuthenticateAsClientAsync(_options.Server, LoadCertificates(), _options.TlsOptions.SslProtocol, !_options.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false);
            }
            else
            {
                _stream = networkStream;
            }

            Endpoint = socket.RemoteEndPoint?.ToString();
        }