Exemple #1
0
        private async Task AcceptTlsEndpointConnectionsAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
#if NET452 || NET461
                    var clientSocket = await Task.Factory.FromAsync(_tlsEndpointSocket.BeginAccept, _tlsEndpointSocket.EndAccept, null).ConfigureAwait(false);
#else
                    var clientSocket = await _tlsEndpointSocket.AcceptAsync().ConfigureAwait(false);
#endif

                    var sslStream = new SslStream(new NetworkStream(clientSocket));
                    await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, SslProtocols.Tls12, false).ConfigureAwait(false);

                    var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(clientSocket, sslStream), new MqttPacketSerializer(), _logger);
                    ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter));
                }
                catch (Exception exception)
                {
                    _logger.Error <MqttServerAdapter>(exception, "Error while accepting connection at TLS endpoint.");

                    //excessive CPU consumed if in endless loop of socket errors
                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
                }
            }
        }
Exemple #2
0
        private async Task AcceptTlsEndpointConnectionsAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
#if NET452 || NET461
                    var clientSocket = await Task.Factory.FromAsync(_tlsEndpointSocket.BeginAccept, _tlsEndpointSocket.EndAccept, null).ConfigureAwait(false);
#else
                    var clientSocket = await _tlsEndpointSocket.AcceptAsync().ConfigureAwait(false);
#endif

                    var sslStream = new SslStream(new NetworkStream(clientSocket));
                    await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, SslProtocols.Tls12, false).ConfigureAwait(false);

                    var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(clientSocket, sslStream), new MqttPacketSerializer(), _logger);
                    ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter));
                }
                catch (ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                }
                catch (Exception exception)
                {
                    if (exception is SocketException s && s.SocketErrorCode == SocketError.OperationAborted)
                    {
                        return;
                    }

                    _logger.Error <MqttServerAdapter>(exception, "Error while accepting connection at TLS endpoint.");
                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
                }
            }
        }
        private async void OnConnectionReceivedAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
        {
            try
            {
                var clientHandler = ClientHandler;
                if (clientHandler != null)
                {
                    using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket, _options), new MqttPacketFormatterAdapter(), _logger))
                    {
                        await clientHandler(clientAdapter).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception exception)
            {
                if (exception is ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                    return;
                }

                _logger.Error(exception, "Error while handling client connection.");
            }
            finally
            {
                try
                {
                    args.Socket.Dispose();
                }
                catch (Exception exception)
                {
                    _logger.Error(exception, "Error while cleaning up client connection");
                }
            }
        }
        private void _serverSokcet_OnAccepted(object obj)
        {
            Task.Run(() =>
            {
                var ci = (ChannelInfo)obj;

                Stream stream = ci.Stream;

                string remoteEndPoint = ci.ID;

                X509Certificate2 clientCertificate = null;

                if (_tlsCertificate != null)
                {
                    SslStream sslStream = (SslStream)stream;

                    clientCertificate = sslStream.RemoteCertificate as X509Certificate2;

                    if (clientCertificate == null && sslStream.RemoteCertificate != null)
                    {
                        clientCertificate = new X509Certificate2(sslStream.RemoteCertificate.Export(X509ContentType.Cert));
                    }
                }

                var clientHandler = ClientHandler;

                if (clientHandler != null)
                {
                    using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(stream, remoteEndPoint, clientCertificate), new MqttPacketFormatterAdapter(new MqttPacketWriter()), _rootLogger))
                    {
                        clientHandler(clientAdapter).ConfigureAwait(false).GetAwaiter().GetResult();
                    }
                }
            });
        }
Exemple #5
0
        private async Task AcceptDefaultEndpointConnectionsAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    //todo: else branch can be used with min dependency NET46
#if NET452 || NET461
                    var clientSocket = await Task.Factory.FromAsync(_defaultEndpointSocket.BeginAccept, _defaultEndpointSocket.EndAccept, null).ConfigureAwait(false);
#else
                    var clientSocket = await _defaultEndpointSocket.AcceptAsync().ConfigureAwait(false);
#endif

                    var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(clientSocket, null), new MqttPacketSerializer(), _logger);
                    ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter));
                }
                catch (ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                }
                catch (Exception exception)
                {
                    if (exception is SocketException s && s.SocketErrorCode == SocketError.OperationAborted)
                    {
                        return;
                    }

                    _logger.Error <MqttServerAdapter>(exception, "Error while accepting connection at default endpoint.");
                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
                }
            }
        }
Exemple #6
0
        public void Setup()
        {
            var message = new MqttApplicationMessageBuilder()
                          .WithTopic("A")
                          .Build();

            _packet = message.ToPublishPacket();
            var serializer       = new MqttPacketSerializer();
            var serializedPacket = Join(serializer.Serialize(_packet));

            _iterations = 10000;

            _stream = new MemoryStream(_iterations * serializedPacket.Length);

            for (var i = 0; i < _iterations; i++)
            {
                _stream.Write(serializedPacket, 0, serializedPacket.Length);
            }

            _stream.Position = 0;

            var channel = new TestMqttChannel(_stream);

            _channelAdapter = new MqttChannelAdapter(channel, serializer, new MqttNetLogger().CreateChildLogger(nameof(MqttChannelAdapter)));
        }
Exemple #7
0
        TPacket Roundtrip <TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
            where TPacket : MqttBasePacket
        {
            var writer     = WriterFactory();
            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
            var buffer     = serializer.Encode(packet);

            var channel = new TestMqttChannel(buffer.ToArray());
            var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, writer), null, new MqttNetLogger());

            return((TPacket)adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult());

            //using (var headerStream = new MemoryStream(buffer1.ToArray()))
            //{



            //    //var fixedHeader = new byte[2];

            //    //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;

            //    //using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
            //    //{
            //    //    var reader = ReaderFactory(bodyStream.ToArray());
            //    //    return (T)serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
            //    //}
            //}
        }
Exemple #8
0
        public async Task RunWebSocketConnectionAsync(WebSocket webSocket, HttpContext httpContext)
        {
            if (webSocket == null)
            {
                throw new ArgumentNullException(nameof(webSocket));
            }

            var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}";

            var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false);

            var isSecureConnection = clientCertificate != null;

            clientCertificate?.Dispose();

            var clientHandler = ClientHandler;

            if (clientHandler != null)
            {
                var writer    = new SpanBasedMqttPacketWriter();
                var formatter = new MqttPacketFormatterAdapter(writer);
                var channel   = new MqttWebSocketChannel(webSocket, endpoint, isSecureConnection);
                using (var channelAdapter = new MqttChannelAdapter(channel, formatter, _logger.CreateChildLogger(nameof(MqttWebSocketServerAdapter))))
                {
                    await clientHandler(channelAdapter).ConfigureAwait(false);
                }
            }
        }
Exemple #9
0
        void DeserializeAndCompare(MqttPacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
        {
            var writer = WriterFactory();

            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
            var buffer1    = serializer.Encode(packet);

            using (var headerStream = new MemoryStream(buffer1.Join().ToArray()))
            {
                using (var channel = new TestMqttChannel(headerStream))
                {
                    using (var adapter = new MqttChannelAdapter(
                               channel,
                               new MqttPacketFormatterAdapter(protocolVersion, new MqttBufferWriter(4096, 65535)),
                               null,
                               new MqttNetEventLogger()))
                    {
                        var receivedPacket = adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();

                        var buffer2 = serializer.Encode(receivedPacket);

                        Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(buffer2.Join().ToArray()));
                    }
                }
            }
        }
Exemple #10
0
        MqttProtocolVersion DeserializeAndDetectVersion(MqttPacketFormatterAdapter packetFormatterAdapter, byte[] buffer)
        {
            var channel = new TestMqttChannel(buffer);
            var adapter = new MqttChannelAdapter(channel, packetFormatterAdapter, null, new MqttNetLogger());

            adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
            return(packetFormatterAdapter.ProtocolVersion);

            //using (var headerStream = new MemoryStream(buffer))
            //{



            //    //var fixedHeader = new byte[2];
            //    //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;

            //    //using (var bodyStream = new MemoryStream(buffer, (int)headerStream.Position, (int)header.RemainingLength))
            //    //{
            //    //    var reader = ReaderFactory(bodyStream.ToArray());
            //    //    var packet = new ReceivedMqttPacket(header.Flags, reader, 0);
            //    //    packetFormatterAdapter.DetectProtocolVersion(packet);
            //    //    return adapter.ProtocolVersion;
            //    //}
            //}
        }
Exemple #11
0
        void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
        {
            var writer = WriterFactory();

            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
            var buffer1    = serializer.Encode(packet);

            using (var headerStream = new MemoryStream(buffer1.ToArray()))
            {
                var channel        = new TestMqttChannel(headerStream);
                var adapter        = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, writer), null, new MqttNetLogger());
                var receivedPacket = adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();

                var buffer2 = serializer.Encode(receivedPacket);

                Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(buffer2.ToArray()));

                //adapter.ReceivePacketAsync(CancellationToken.None);
                //var fixedHeader = new byte[2];
                //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;

                //using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
                //{
                //    var reader = ReaderFactory(bodyStream.ToArray());
                //    var deserializedPacket = serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
                //    var buffer2 = serializer.Encode(deserializedPacket);

                //    Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
                //}
            }
        }
Exemple #12
0
        public void Setup()
        {
            _packet = new MqttPublishPacket
            {
                Topic = "A"
            };

            var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311);

            var serializedPacket = Join(serializer.Encode(_packet));

            _iterations = 10000;

            _stream = new MemoryStream(_iterations * serializedPacket.Length);

            for (var i = 0; i < _iterations; i++)
            {
                _stream.Write(serializedPacket, 0, serializedPacket.Length);
            }

            _stream.Position = 0;

            var channel = new TestMqttChannel(_stream);

            _channelAdapter = new MqttChannelAdapter(channel, serializer, new MqttNetLogger());
        }
        public async Task RunWebSocketConnectionAsync(WebSocket webSocket, HttpContext httpContext)
        {
            if (webSocket == null)
            {
                throw new ArgumentNullException(nameof(webSocket));
            }

            var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}";

            var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false);

            try
            {
                var isSecureConnection = clientCertificate != null;

                var clientHandler = ClientHandler;
                if (clientHandler != null)
                {
                    var formatter = new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535));
                    var channel   = new MqttWebSocketChannel(webSocket, endpoint, isSecureConnection, clientCertificate);

                    using (var channelAdapter = new MqttChannelAdapter(channel, formatter, null, _logger))
                    {
                        await clientHandler(channelAdapter).ConfigureAwait(false);
                    }
                }
            }
            finally
            {
                clientCertificate?.Dispose();
            }
        }
Exemple #14
0
        MqttProtocolVersion DeserializeAndDetectVersion(MqttPacketFormatterAdapter packetFormatterAdapter, byte[] buffer)
        {
            var channel = new TestMqttChannel(buffer);
            var adapter = new MqttChannelAdapter(channel, packetFormatterAdapter, null, new MqttNetEventLogger());

            adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
            return(packetFormatterAdapter.ProtocolVersion);
        }
        public MqttPacket Decode(MqttPacketBuffer buffer)
        {
            using (var channel = new MemoryMqttChannel(buffer.ToArray()))
            {
                var formatterAdapter = new MqttPacketFormatterAdapter(_protocolVersion, new MqttBufferWriter(4096, 65535));

                var adapter = new MqttChannelAdapter(channel, formatterAdapter, null, MqttNetNullLogger.Instance);
                return adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
            }
        }
Exemple #16
0
        public void Deserialize_10000_Messages()
        {
            var channel = new BenchmarkMqttChannel(_serializedPacket);
            var reader  = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535)), null, new MqttNetEventLogger());

            for (var i = 0; i < 10000; i++)
            {
                channel.Reset();

                var header = reader.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
            }
        }
Exemple #17
0
        TPacket Roundtrip <TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311, MqttBufferWriter bufferWriter = null) where TPacket : MqttPacket
        {
            var writer     = bufferWriter ?? WriterFactory();
            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
            var buffer     = serializer.Encode(packet);

            using (var channel = new TestMqttChannel(buffer.Join().ToArray()))
            {
                var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, new MqttBufferWriter(4096, 65535)), null, new MqttNetEventLogger());
                return((TPacket)adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult());
            }
        }
        async void OnConnectionReceivedAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
        {
            try
            {
                var clientHandler = ClientHandler;
                if (clientHandler != null)
                {
                    X509Certificate2 clientCertificate = null;

                    if (args.Socket.Control.ClientCertificate != null)
                    {
                        try
                        {
                            clientCertificate = new X509Certificate2(args.Socket.Control.ClientCertificate.GetCertificateBlob().ToArray());
                        }
                        catch (Exception exception)
                        {
                            _logger.Warning(exception, "Unable to convert UWP certificate to X509Certificate2.");
                        }
                    }

                    var bufferWriter           = new MqttBufferWriter(4096, 65535);
                    var packetFormatterAdapter = new MqttPacketFormatterAdapter(bufferWriter);
                    var tcpChannel             = new MqttTcpChannel(args.Socket, clientCertificate, _options);

                    using (var clientAdapter = new MqttChannelAdapter(tcpChannel, packetFormatterAdapter, null, _rootLogger))
                    {
                        await clientHandler(clientAdapter).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception exception)
            {
                if (exception is ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                    return;
                }

                _logger.Error(exception, "Error while handling client connection.");
            }
            finally
            {
                try
                {
                    args.Socket.Dispose();
                }
                catch (Exception exception)
                {
                    _logger.Error(exception, "Error while cleaning up client connection.");
                }
            }
        }
Exemple #19
0
 private void AcceptDefaultEndpointConnectionsAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
 {
     try
     {
         var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket), new MqttPacketSerializer(), _logger);
         ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter));
     }
     catch (Exception exception)
     {
         _logger.Error <MqttServerAdapter>(exception, "Error while accepting connection at default endpoint.");
     }
 }
Exemple #20
0
        public Task AcceptWebSocketAsync(WebSocket webSocket)
        {
            if (webSocket == null)
            {
                throw new ArgumentNullException(nameof(webSocket));
            }

            var channel       = new MqttWebSocketServerChannel(webSocket);
            var clientAdapter = new MqttChannelAdapter(channel, new MqttPacketSerializer(), new MqttNetLogger());

            var eventArgs = new MqttServerAdapterClientAcceptedEventArgs(clientAdapter);

            ClientAccepted?.Invoke(this, eventArgs);
            return(eventArgs.SessionTask);
        }
        private async Task AcceptClientConnectionsAsync()
        {
            while (!_cancellationToken.IsCancellationRequested)
            {
                try
                {
#if NET452 || NET461
                    var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null).ConfigureAwait(false);
#else
                    var clientSocket = await _socket.AcceptAsync().ConfigureAwait(false);
#endif
                    clientSocket.NoDelay = true;

                    SslStream sslStream = null;

                    if (_tlsCertificate != null)
                    {
                        sslStream = new SslStream(new NetworkStream(clientSocket), false);
                        await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, _tlsOptions.SslProtocol, false).ConfigureAwait(false);
                    }

                    _logger.Verbose("Client '{0}' accepted by TCP listener '{1}, {2}'.",
                                    clientSocket.RemoteEndPoint,
                                    _socket.LocalEndPoint,
                                    _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6");

                    var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(clientSocket, sslStream), new MqttPacketSerializer(), _logger);
                    ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter));
                }
                catch (ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                }
                catch (Exception exception)
                {
                    if (exception is SocketException s && s.SocketErrorCode == SocketError.OperationAborted)
                    {
                        return;
                    }

                    _logger.Error(exception, $"Error while accepting connection at TCP listener {_socket.LocalEndPoint} TLS={_tlsCertificate != null}.");
                    await Task.Delay(TimeSpan.FromSeconds(1), _cancellationToken).ConfigureAwait(false);
                }
            }
        }
Exemple #22
0
        public async Task RunWebSocketConnectionAsync(WebSocket webSocket, string endpoint)
        {
            if (webSocket == null)
            {
                throw new ArgumentNullException(nameof(webSocket));
            }

            var clientAdapter = new MqttChannelAdapter(new MqttWebSocketChannel(webSocket, endpoint), new MqttPacketSerializer(), new MqttNetLogger().CreateChildLogger(nameof(MqttWebSocketServerAdapter)));

            var eventArgs = new MqttServerAdapterClientAcceptedEventArgs(clientAdapter);

            ClientAccepted?.Invoke(this, eventArgs);

            if (eventArgs.SessionTask != null)
            {
                await eventArgs.SessionTask.ConfigureAwait(false);
            }
        }
Exemple #23
0
        private async Task AcceptDefaultEndpointConnectionsAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    //todo: else branch can be used with min dependency NET46
#if NET452 || NET461
                    var clientSocket = await Task.Factory.FromAsync(_defaultEndpointSocket.BeginAccept, _defaultEndpointSocket.EndAccept, null).ConfigureAwait(false);
#else
                    var clientSocket = await _defaultEndpointSocket.AcceptAsync().ConfigureAwait(false);
#endif
                    var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(clientSocket, null), new MqttPacketSerializer(), _logger);
                    ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter));
                }
                catch (Exception exception)
                {
                    _logger.Error <MqttServerAdapter>(exception, "Error while accepting connection at default endpoint.");

                    //excessive CPU consumed if in endless loop of socket errors
                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);
                }
            }
        }
        async Task TryHandleClientConnectionAsync(CrossPlatformSocket clientSocket)
        {
            Stream stream         = null;
            string remoteEndPoint = null;

            try
            {
                remoteEndPoint = clientSocket.RemoteEndPoint.ToString();

                _logger.Verbose("Client '{0}' accepted by TCP listener '{1}, {2}'.",
                                remoteEndPoint,
                                _localEndPoint,
                                _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6");

                clientSocket.NoDelay = _options.NoDelay;
                stream = clientSocket.GetStream();
                X509Certificate2 clientCertificate = null;

                if (_tlsCertificate != null)
                {
                    var sslStream = new SslStream(stream, false, _tlsOptions.RemoteCertificateValidationCallback);

                    await sslStream.AuthenticateAsServerAsync(
                        _tlsCertificate,
                        _tlsOptions.ClientCertificateRequired,
                        _tlsOptions.SslProtocol,
                        _tlsOptions.CheckCertificateRevocation).ConfigureAwait(false);

                    stream = sslStream;

                    clientCertificate = sslStream.RemoteCertificate as X509Certificate2;

                    if (clientCertificate == null && sslStream.RemoteCertificate != null)
                    {
                        clientCertificate = new X509Certificate2(sslStream.RemoteCertificate.Export(X509ContentType.Cert));
                    }
                }

                var clientHandler = ClientHandler;
                if (clientHandler != null)
                {
                    using (var clientAdapter = new MqttChannelAdapter(
                               new MqttTcpChannel(stream, remoteEndPoint, clientCertificate),
                               new MqttPacketFormatterAdapter(new MqttPacketWriter()),
                               null,
                               _rootLogger))
                    {
                        await clientHandler(clientAdapter).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception exception)
            {
                if (exception is ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                    return;
                }

                if (exception is SocketException socketException &&
                    socketException.SocketErrorCode == SocketError.OperationAborted)
                {
                    return;
                }

                _logger.Error(exception, "Error while handling client connection.");
            }
            finally
            {
                try
                {
                    stream?.Dispose();
                    clientSocket?.Dispose();
                }
                catch (Exception disposeException)
                {
                    _logger.Error(disposeException, "Error while cleaning up client connection");
                }
            }

            _logger.Verbose("Client '{0}' disconnected at TCP listener '{1}, {2}'.",
                            remoteEndPoint,
                            _localEndPoint,
                            _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6");
        }
Exemple #25
0
        private async Task TryHandleClientConnectionAsync(Socket clientSocket)
        {
            Stream stream         = null;
            string remoteEndPoint = null;

            try
            {
                remoteEndPoint = clientSocket.RemoteEndPoint.ToString();

                _logger.Verbose("Client '{0}' accepted by TCP listener '{1}, {2}'.",
                                remoteEndPoint,
                                _socket.LocalEndPoint,
                                _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6");

                clientSocket.NoDelay = _options.NoDelay;

                stream = new NetworkStream(clientSocket, true);

                if (_tlsCertificate != null)
                {
                    var sslStream = new SslStream(stream, false);
                    await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, _tlsOptions.SslProtocol, false).ConfigureAwait(false);

                    stream = sslStream;
                }

                var clientHandler = ClientHandler;
                if (clientHandler != null)
                {
                    using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(stream, remoteEndPoint), new MqttPacketFormatterAdapter(), _logger))
                    {
                        await clientHandler(clientAdapter).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception exception)
            {
                if (exception is ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                    return;
                }

                if (exception is SocketException socketException &&
                    socketException.SocketErrorCode == SocketError.OperationAborted)
                {
                    return;
                }

                _logger.Error(exception, "Error while handling client connection.");
            }
            finally
            {
                try
                {
                    stream?.Dispose();
                    clientSocket?.Dispose();

                    _logger.Verbose("Client '{0}' disconnected at TCP listener '{1}, {2}'.",
                                    remoteEndPoint,
                                    _socket.LocalEndPoint,
                                    _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6");
                }
                catch (Exception disposeException)
                {
                    _logger.Error(disposeException, "Error while cleaning up client connection");
                }
            }
        }
        private async Task TryHandleClientConnectionAsync(Socket clientSocket)
        {
            var socketIndex = Interlocked.Increment(ref latestSocketIndex);

            string    clientPrefix  = null;
            string    serverEndPont = null;
            SslStream sslStream     = null;
            var       stopwatch     = new Stopwatch();

            try
            {
                stopwatch.Start();

                clientPrefix  = $"Socket[{socketIndex}, {clientSocket.RemoteEndPoint}]";
                serverEndPont = string.Format("{0}, {1}, {2}",
                                              _socket.LocalEndPoint,
                                              _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6",
                                              _tlsCertificate == null ? "tcp" : "tls");

                _logger.Verbose($"{clientPrefix} > Accepted by TCP listener '{serverEndPont}'. Time:{stopwatch.Elapsed.TotalMilliseconds}ms");

                clientSocket.NoDelay = true;

                if (_tlsCertificate != null)
                {//如果不设置超时,AuthenticateAsServerAsync 可能会一直阻塞下去
                    clientSocket.ReceiveTimeout = (int)_communicationTimeout.TotalMilliseconds;
                    clientSocket.SendTimeout    = (int)_communicationTimeout.TotalMilliseconds;

                    var stream = new NetworkStream(clientSocket, true);
                    sslStream = new SslStream(stream, false);

                    var cancellationTokenDisposeSslStream = new CancellationTokenSource();
                    var taskDisposeSslStream = Task.Delay(_communicationTimeout, cancellationTokenDisposeSslStream.Token)
                                               .ContinueWith((task) =>
                    {
                        if (task.IsCanceled)
                        {
                            return;
                        }
                        if (cancellationTokenDisposeSslStream.IsCancellationRequested)
                        {
                            return;
                        }

                        //超时,则清理掉
                        Cleanup(clientSocket, sslStream);
                    });

                    await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, _tlsOptions.SslProtocol, false).ConfigureAwait(false);

                    cancellationTokenDisposeSslStream.Cancel();

                    _logger.Verbose($"{clientPrefix} > SslStream created. Time:{stopwatch.Elapsed.TotalMilliseconds}ms");
                }

                _logger.Verbose($"{clientPrefix} > Processed. Time:{stopwatch.Elapsed.TotalMilliseconds}ms");

                if (ClientAccepted != null)
                {
                    using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(clientSocket, sslStream), new MqttPacketSerializer(), _logger))
                    {
                        var args = new MqttServerAdapterClientAcceptedEventArgs(clientAdapter);
                        ClientAccepted.Invoke(this, args);
                        await args.SessionTask.ConfigureAwait(false);
                    }
                }
            }
            catch (ObjectDisposedException exception)
            {
                // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                _logger.Error(exception, $"{clientPrefix} > Error while handling client connection. Listener:'{serverEndPont}' Time:{stopwatch.Elapsed.TotalMilliseconds}ms Disposed");
            }
            catch (Exception exception)
            {
                Cleanup(clientSocket, sslStream);

                if (exception is SocketException s && s.SocketErrorCode == SocketError.OperationAborted)
                {
                    _logger.Error(exception, $"{clientPrefix} > Error while handling client connection. Listener:'{serverEndPont}' Time:{stopwatch.Elapsed.TotalMilliseconds}ms OperationAborted");
                    return;
                }
                if (exception is System.IO.IOException ioException)
                {
                    _logger.Error(exception, $"{clientPrefix} > Error while handling client connection. Listener:'{serverEndPont}' Time:{stopwatch.Elapsed.TotalMilliseconds}ms IOException");
                    return;
                }

                _logger.Error(exception, $"{clientPrefix} > Error while handling client connection. Listener:'{serverEndPont}' Time:{stopwatch.Elapsed.TotalMilliseconds}ms Unknown");
            }
            finally
            {
                try
                {
                    Cleanup(clientSocket, sslStream);

                    _logger.Verbose($"{clientPrefix} > Disconnected at TCP listener '{serverEndPont}'. Time:{stopwatch.Elapsed.TotalMilliseconds}ms");
                }
                catch (Exception disposeException)
                {
                    _logger.Error(disposeException, $"{clientPrefix} > Error while cleaning up client connection. Listener:'{serverEndPont}' Time:{stopwatch.Elapsed.TotalMilliseconds}ms");
                }

                stopwatch.Stop();
            }
        }
        async Task TryHandleClientConnectionAsync(CrossPlatformSocket clientSocket)
        {
            Stream stream         = null;
            string remoteEndPoint = null;

            try
            {
                remoteEndPoint = clientSocket.RemoteEndPoint.ToString();

                _logger.Verbose("Client '{0}' accepted by TCP listener '{1}, {2}'.",
                                remoteEndPoint,
                                _localEndPoint,
                                _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6");

                clientSocket.NoDelay = _options.NoDelay;
                stream = clientSocket.GetStream();
                X509Certificate2 clientCertificate = null;

                if (_tlsCertificate != null)
                {
                    var sslStream = new SslStream(stream, false, _tlsOptions.RemoteCertificateValidationCallback);

                    #if NETCOREAPP3_1 || NET5_0_OR_GREATER
                    await sslStream.AuthenticateAsServerAsync(
                        new SslServerAuthenticationOptions()
                    {
                        ServerCertificate              = _tlsCertificate,
                        ClientCertificateRequired      = _tlsOptions.ClientCertificateRequired,
                        EnabledSslProtocols            = _tlsOptions.SslProtocol,
                        CertificateRevocationCheckMode = _tlsOptions.CheckCertificateRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck,
                        EncryptionPolicy   = EncryptionPolicy.RequireEncryption,
                        CipherSuitesPolicy = _tlsOptions.CipherSuitesPolicy
                    }).ConfigureAwait(false);
                    #else
                    await sslStream.AuthenticateAsServerAsync(
                        _tlsCertificate,
                        _tlsOptions.ClientCertificateRequired,
                        _tlsOptions.SslProtocol,
                        _tlsOptions.CheckCertificateRevocation).ConfigureAwait(false);
                    #endif

                    stream = sslStream;

                    clientCertificate = sslStream.RemoteCertificate as X509Certificate2;

                    if (clientCertificate == null && sslStream.RemoteCertificate != null)
                    {
                        clientCertificate = new X509Certificate2(sslStream.RemoteCertificate.Export(X509ContentType.Cert));
                    }
                }

                var clientHandler = ClientHandler;
                if (clientHandler != null)
                {
                    var tcpChannel             = new MqttTcpChannel(stream, remoteEndPoint, clientCertificate);
                    var bufferWriter           = new MqttBufferWriter(_serverOptions.WriterBufferSize, _serverOptions.WriterBufferSizeMax);
                    var packetFormatterAdapter = new MqttPacketFormatterAdapter(bufferWriter);

                    using (var clientAdapter = new MqttChannelAdapter(tcpChannel, packetFormatterAdapter, null, _rootLogger))
                    {
                        await clientHandler(clientAdapter).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception exception)
            {
                if (exception is ObjectDisposedException)
                {
                    // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
                    return;
                }

                if (exception is SocketException socketException &&
                    socketException.SocketErrorCode == SocketError.OperationAborted)
                {
                    return;
                }

                _logger.Error(exception, "Error while handling client connection.");
            }
            finally
            {
                try
                {
                    stream?.Dispose();
                    clientSocket?.Dispose();
                }
                catch (Exception disposeException)
                {
                    _logger.Error(disposeException, "Error while cleaning up client connection");
                }
            }

            _logger.Verbose("Client '{0}' disconnected at TCP listener '{1}, {2}'.",
                            remoteEndPoint,
                            _localEndPoint,
                            _addressFamily == AddressFamily.InterNetwork ? "ipv4" : "ipv6");
        }