Пример #1
0
        public Task ProcessWebSocketRequestAsync(
            WebSocket webSocket,
            Option <EndPoint> localEndPoint,
            EndPoint remoteEndPoint,
            string correlationId,
            X509Certificate2 clientCert,
            IList <X509Certificate2> clientCertChain)
        {
            var identityProvider = new DeviceIdentityProvider(this.authenticator, this.clientCredentialsFactory, this.clientCertAuthAllowed);

            identityProvider.RegisterConnectionCertificate(clientCert, clientCertChain);
            return(this.ProcessWebSocketRequestAsyncInternal(identityProvider, webSocket, localEndPoint, remoteEndPoint, correlationId));
        }
Пример #2
0
        bool RemoteCertificateValidationCallback(DeviceIdentityProvider identityProvider, X509Certificate certificate, X509Chain chain)
        {
            if (this.clientCertAuthAllowed && certificate != null)
            {
                IList <X509Certificate2> certChain = chain?.ChainElements?
                                                     .Cast <X509ChainElement>()
                                                     .Select(element => element.Certificate)
                                                     .ToList()
                                                     ?? new List <X509Certificate2>();
                identityProvider.RegisterConnectionCertificate(new X509Certificate2(certificate), certChain);
            }

            return(true);
        }
Пример #3
0
        public async Task ProcessWebSocketRequestAsync(WebSocket webSocket,
                                                       Option <EndPoint> localEndPoint,
                                                       EndPoint remoteEndPoint,
                                                       string correlationId,
                                                       Option <X509Certificate2> clientCert,
                                                       Option <IList <X509Certificate2> > clientCertChain)
        {
            try
            {
                DeviceIdentityProvider identityProvider = new DeviceIdentityProvider(this.authenticator, this.clientCredentialsFactory, true);
                var serverChannel = new ServerWebSocketChannel(
                    webSocket,
                    remoteEndPoint
                    );

                clientCert.Map(cert =>
                {
                    return(identityProvider.RemoteCertificateValidationCallback(cert, clientCertChain.Expect(() => new ArgumentException("Certificate chain was found to be null"))));
                });

                serverChannel
                .Option(ChannelOption.Allocator, this.byteBufferAllocator)
                .Option(ChannelOption.AutoRead, this.autoRead)
                .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
                .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
                .Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, this.mqttDecoderMaxMessageSize),
                    new MqttAdapter(
                        this.settings,
                        this.sessionProviderFactory(),
                        identityProvider,
                        null,
                        this.messagingBridgeFactoryFunc));

                await this.workerGroup.GetNext().RegisterAsync(serverChannel);

                Events.Established(correlationId);

                await serverChannel.WebSocketClosed.Task;  // This will wait until the websocket is closed
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                Events.Exception(correlationId, ex);
                throw;
            }
        }
Пример #4
0
        public async Task ProcessWebSocketRequestAsyncInternal(
            DeviceIdentityProvider identityProvider,
            WebSocket webSocket,
            Option <EndPoint> localEndPoint,
            EndPoint remoteEndPoint,
            string correlationId)
        {
            try
            {
                var serverChannel = new ServerWebSocketChannel(webSocket, remoteEndPoint);

                serverChannel
                .Option(ChannelOption.Allocator, this.byteBufferAllocator)
                .Option(ChannelOption.AutoRead, this.autoRead)
                .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
                .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
                .Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, this.mqttDecoderMaxMessageSize),
                    new MqttAdapter(
                        this.settings,
                        this.sessionProviderFactory(),
                        identityProvider,
                        null,
                        this.messagingBridgeFactoryFunc));

                await this.workerGroup.GetNext().RegisterAsync(serverChannel);

                Events.Established(correlationId);

                await serverChannel.WebSocketClosed.Task; // This will wait until the websocket is closed
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                Events.Exception(correlationId, ex);
                throw;
            }
        }
Пример #5
0
        public Task ProcessWebSocketRequestAsync(WebSocket webSocket, Option <EndPoint> localEndPoint, EndPoint remoteEndPoint, string correlationId)
        {
            var identityProvider = new DeviceIdentityProvider(this.authenticator, this.usernameParser, this.clientCredentialsFactory, this.metadataStore, this.clientCertAuthAllowed);

            return(this.ProcessWebSocketRequestAsyncInternal(identityProvider, webSocket, localEndPoint, remoteEndPoint, correlationId));
        }
Пример #6
0
        ServerBootstrap SetupServerBootstrap()
        {
            int maxInboundMessageSize = this.settingsProvider.GetIntegerSetting("MaxInboundMessageSize", DefaultMaxInboundMessageSize);
            int threadCount           = this.settingsProvider.GetIntegerSetting("ThreadCount", DefaultThreadCount);
            int listenBacklogSize     = this.settingsProvider.GetIntegerSetting("ListenBacklogSize", DefaultListenBacklogSize);
            int parentEventLoopCount  = this.settingsProvider.GetIntegerSetting("EventLoopCount", DefaultParentEventLoopCount);
            var settings = new Settings(this.settingsProvider);

            MessagingBridgeFactoryFunc bridgeFactory = this.mqttConnectionProvider.Connect;

            var bootstrap = new ServerBootstrap();
            // multithreaded event loop that handles the incoming connection
            IEventLoopGroup parentEventLoopGroup = new MultithreadEventLoopGroup(parentEventLoopCount);

            // multithreaded event loop (worker) that handles the traffic of the accepted connections
            this.eventLoopGroup = new MultithreadEventLoopGroup(threadCount);

            bootstrap.Group(parentEventLoopGroup, this.eventLoopGroup)
            .Option(ChannelOption.SoBacklog, listenBacklogSize)
            // Allow listening socket to force bind to port if previous socket is still in TIME_WAIT
            // Fixes "address is already in use" errors
            .Option(ChannelOption.SoReuseaddr, true)
            .ChildOption(ChannelOption.Allocator, this.byteBufferAllocator)
            .ChildOption(ChannelOption.AutoRead, AutoRead)
            // channel that accepts incoming connections
            .Channel <TcpServerSocketChannel>()
            // Channel initializer, it is handler that is purposed to help configure a new channel
            .ChildHandler(
                new ActionChannelInitializer <ISocketChannel>(
                    channel =>
            {
                var identityProvider = new DeviceIdentityProvider(this.authenticator, this.clientCredentialsFactory, this.clientCertAuthAllowed);
                // configure the channel pipeline of the new Channel by adding handlers
                TlsSettings serverSettings = new ServerTlsSettings(
                    certificate: this.tlsCertificate,
                    negotiateClientCertificate: this.clientCertAuthAllowed
                    );

                channel.Pipeline.AddLast(
                    new TlsHandler(
                        stream =>
                        new SslStream(
                            stream,
                            true,
                            (sender, remoteCertificate, remoteChain, sslPolicyErrors) => this.RemoteCertificateValidationCallback(identityProvider, remoteCertificate, remoteChain)),
                        serverSettings));

                channel.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, maxInboundMessageSize),
                    new MqttAdapter(
                        settings,
                        this.sessionProvider,
                        identityProvider,
                        null,
                        bridgeFactory));
            }));

            var mqttWebSocketListener = new MqttWebSocketListener(
                settings,
                bridgeFactory,
                this.authenticator,
                this.clientCredentialsFactory,
                () => this.sessionProvider,
                new MultithreadEventLoopGroup(Environment.ProcessorCount),
                this.byteBufferAllocator,
                AutoRead,
                maxInboundMessageSize,
                this.clientCertAuthAllowed);

            this.webSocketListenerRegistry.TryRegister(mqttWebSocketListener);

            return(bootstrap);
        }