protected override void InitChannel(IChannel channel) { var pipeline = channel.Pipeline; if (_cert is object) { var tlsSettings = new ClientTlsSettings(_targetHost) { ApplicationProtocols = new List <SslApplicationProtocol>(new[] { SslApplicationProtocol.Http2, SslApplicationProtocol.Http11 }) }.AllowAnyServerCertificate(); pipeline.AddLast("tls", new TlsHandler(tlsSettings)); } var build = Http2FrameCodecBuilder.ForClient(); build.InitialSettings = Http2Settings.DefaultSettings(); // this is the default, but shows it can be changed. Http2FrameCodec http2FrameCodec = build.Build(); pipeline.AddLast(http2FrameCodec); pipeline.AddLast(new Http2MultiplexHandler(new SimpleChannelInboundHandler0())); }
public async void MqttServerAndClient() { var testPromise = new TaskCompletionSource(); var tlsCertificate = new X509Certificate2("dotnetty.com.pfx", "password"); Func <Task> closeServerFunc = await this.StartServerAsync(true, ch => { ch.Pipeline.AddLast("server logger", new LoggingHandler("SERVER")); ch.Pipeline.AddLast("server tls", TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast("server logger2", new LoggingHandler("SER***")); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(true, 256 * 1024), new TestScenarioRunner(this.GetMqttServerScenario, testPromise)); }, testPromise); var group = new MultithreadEventLoopGroup(); Bootstrap b = new Bootstrap() .Group(group) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); var clientTlsSettings = new ClientTlsSettings(targetHost); ch.Pipeline.AddLast("client logger", new LoggingHandler("CLIENT")); ch.Pipeline.AddLast("client tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), clientTlsSettings)); ch.Pipeline.AddLast("client logger2", new LoggingHandler("CLI***")); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(false, 256 * 1024), new TestScenarioRunner(this.GetMqttClientScenario, testPromise)); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); await Task.WhenAny(testPromise.Task, Task.Delay(TimeSpan.FromSeconds(30))); Assert.True(testPromise.Task.IsCompleted); } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }
public async void EchoServerAndClient() { var testPromise = new TaskCompletionSource(); var tlsCertificate = new X509Certificate2("dotnetty.com.pfx", "password"); Func<Task> closeServerFunc = await this.StartServerAsync(true, ch => { ch.Pipeline.AddLast("server logger", new LoggingHandler("SERVER")); ch.Pipeline.AddLast("server tls", TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast("server logger2", new LoggingHandler("SER***")); ch.Pipeline.AddLast("server prepender", new LengthFieldPrepender(2)); ch.Pipeline.AddLast("server decoder", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(new EchoChannelHandler()); }, testPromise); var group = new MultithreadEventLoopGroup(); Bootstrap b = new Bootstrap() .Group(group) .Channel<TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer<ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); var clientTlsSettings = new ClientTlsSettings(targetHost); ch.Pipeline.AddLast("client logger", new LoggingHandler("CLIENT")); ch.Pipeline.AddLast("client tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), clientTlsSettings)); ch.Pipeline.AddLast("client logger2", new LoggingHandler("CLI***")); ch.Pipeline.AddLast("client prepender", new LengthFieldPrepender(2)); ch.Pipeline.AddLast("client decoder", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(new TestScenarioRunner(this.GetEchoClientScenario, testPromise)); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); await Task.WhenAny(testPromise.Task, Task.Delay(TimeSpan.FromSeconds(30))); Assert.True(testPromise.Task.IsCompleted, "timed out"); testPromise.Task.Wait(); } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }
private Task <RegistrationOperationStatus> ProvisionOverTcpUsingSymmetricKeyAsync( ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken) { Debug.Assert(message.Security is SecurityProviderSymmetricKey); cancellationToken.ThrowIfCancellationRequested(); var tlsSettings = new ClientTlsSettings( message.GlobalDeviceEndpoint); return(ProvisionOverTcpCommonAsync(message, tlsSettings, cancellationToken)); }
/// <summary> /// Configure the pipeline for TLS NPN negotiation to HTTP/2. /// </summary> /// <param name="ch"></param> void ConfigureSsl(IChannel ch) { var pipeline = ch.Pipeline; var tlsSettings = new ClientTlsSettings(_targetHost) { ApplicationProtocols = new List <SslApplicationProtocol>(new[] { SslApplicationProtocol.Http2, SslApplicationProtocol.Http11 }) }.AllowAnyServerCertificate(); pipeline.AddLast("tls", new TlsHandler(tlsSettings)); // We must wait for the handshake to finish and the protocol to be negotiated before configuring // the HTTP/2 components of the pipeline. pipeline.AddLast(new ClientApplicationProtocolNegotiationHandler(this)); }
private Task <RegistrationOperationStatus> ProvisionOverTcpUsingX509CertificateAsync( ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken) { Debug.Assert(message.Security is SecurityProviderX509); cancellationToken.ThrowIfCancellationRequested(); X509Certificate2 clientCertificate = ((SecurityProviderX509)message.Security).GetAuthenticationCertificate(); var tlsSettings = new ClientTlsSettings( message.GlobalDeviceEndpoint, new List <X509Certificate> { clientCertificate }); return(ProvisionOverTcpCommonAsync(message, tlsSettings, cancellationToken)); }
private async Task <RegistrationOperationStatus> ProvisionOverTcpCommonAsync( ProvisioningTransportRegisterMessage message, ClientTlsSettings tlsSettings, CancellationToken cancellationToken) { var tcs = new TaskCompletionSource <RegistrationOperationStatus>(); Func <Stream, SslStream> streamFactory = stream => new SslStream(stream, true, RemoteCertificateValidationCallback); Bootstrap bootstrap = new Bootstrap() .Group(s_eventLoopGroup) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { ch.Pipeline.AddLast( new ReadTimeoutHandler(ReadTimeoutSeconds), new TlsHandler(streamFactory, tlsSettings), MqttEncoder.Instance, new MqttDecoder(isServer: false, maxMessageSize: MaxMessageSize), new LoggingHandler(LogLevel.DEBUG), new ProvisioningChannelHandlerAdapter(message, tcs, cancellationToken)); })); if (Logging.IsEnabled) { Logging.Associate(bootstrap, this); } IPAddress[] addresses = await Dns.GetHostAddressesAsync(message.GlobalDeviceEndpoint).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Info(this, $"DNS resolved {addresses.Length} addresses."); } IChannel channel = null; Exception lastException = null; foreach (IPAddress address in addresses) { cancellationToken.ThrowIfCancellationRequested(); try { if (Logging.IsEnabled) { Logging.Info(this, $"Connecting to {address.ToString()}."); } channel = await bootstrap.ConnectAsync(address, Port).ConfigureAwait(false); break; } catch (AggregateException ae) { ae.Handle((ex) => { if (ex is ConnectException) // We will handle DotNetty.Transport.Channels.ConnectException { lastException = ex; if (Logging.IsEnabled) { Logging.Info( this, $"ConnectException trying to connect to {address.ToString()}: {ex.ToString()}"); } return(true); } return(false); // Let anything else stop the application. }); } } if (channel == null) { string errorMessage = "Cannot connect to Provisioning Service."; if (Logging.IsEnabled) { Logging.Error(this, errorMessage); } ExceptionDispatchInfo.Capture(lastException).Throw(); } return(await tcs.Task.ConfigureAwait(false)); }
public async Task EchoServerAndClient() { var testPromise = new DefaultPromise(); var tlsCertificate = TestResourceHelper.GetTestCertificate(); Func <Task> closeServerFunc = await this.StartServerAsync(true, ch => { ch.Pipeline.AddLast("server logger", new LoggingHandler("SERVER")); ch.Pipeline.AddLast("server tls", TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast("server logger2", new LoggingHandler("SER***")); ch.Pipeline.AddLast("server prepender", new LengthFieldPrepender2(2)); ch.Pipeline.AddLast("server decoder", new LengthFieldBasedFrameDecoder2(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(new EchoChannelHandler()); }, testPromise); var group = new MultithreadEventLoopGroup(); var readListener = new ReadListeningHandler(DefaultTimeout); Bootstrap b = new Bootstrap() .Group(group) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); var clientTlsSettings = new ClientTlsSettings(targetHost); ch.Pipeline.AddLast("client logger", new LoggingHandler("CLIENT")); ch.Pipeline.AddLast("client tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), clientTlsSettings)); ch.Pipeline.AddLast("client logger2", new LoggingHandler("CLI***")); ch.Pipeline.AddLast("client prepender", new LengthFieldPrepender2(2)); ch.Pipeline.AddLast("client decoder", new LengthFieldBasedFrameDecoder2(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(readListener); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); string[] messages = { "message 1", string.Join(",", Enumerable.Range(1, 300)) }; foreach (string message in messages) { await clientChannel.WriteAndFlushAsync(Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(message))).WithTimeout(DefaultTimeout); var responseMessage = Assert.IsAssignableFrom <IByteBuffer>(await readListener.ReceiveAsync()); Assert.Equal(message, responseMessage.ToString(Encoding.UTF8)); } testPromise.TryComplete(); await testPromise.Task.WithTimeout(TimeSpan.FromMinutes(5)); } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Wait(TimeSpan.FromSeconds(10)); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }
public async Task MqttServerAndClient() { var testPromise = new DefaultPromise(); var tlsCertificate = TestResourceHelper.GetTestCertificate(); var serverReadListener = new ReadListeningHandler(); IChannel serverChannel = null; Func <Task> closeServerFunc = await this.StartServerAsync(true, ch => { serverChannel = ch; ch.Pipeline.AddLast("server logger", new LoggingHandler("SERVER")); ch.Pipeline.AddLast("server tls", TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast("server logger2", new LoggingHandler("SER***")); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(true, 256 * 1024), serverReadListener); }, testPromise); var group = new MultithreadEventLoopGroup(); var clientReadListener = new ReadListeningHandler(); Bootstrap b = new Bootstrap() .Group(group) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); var clientTlsSettings = new ClientTlsSettings(targetHost); ch.Pipeline.AddLast("client logger", new LoggingHandler("CLIENT")); ch.Pipeline.AddLast("client tls", new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), clientTlsSettings)); ch.Pipeline.AddLast("client logger2", new LoggingHandler("CLI***")); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(false, 256 * 1024), clientReadListener); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); await Task.WhenAll(this.RunMqttClientScenarioAsync(clientChannel, clientReadListener), this.RunMqttServerScenarioAsync(serverChannel, serverReadListener)) .WithTimeout(TimeSpan.FromMinutes(5)); testPromise.TryComplete(); await testPromise.Task; } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(5)).Wait(TimeSpan.FromSeconds(10)); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }
private async Task <RegistrationOperationStatus> ProvisionOverTcpUsingX509CertificateAsync( ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken) { Debug.Assert(message.Security is SecurityProviderX509); cancellationToken.ThrowIfCancellationRequested(); X509Certificate2 clientCertificate = ((SecurityProviderX509)message.Security).GetAuthenticationCertificate(); var tlsSettings = new ClientTlsSettings( message.GlobalDeviceEndpoint, new List <X509Certificate> { clientCertificate }); var tcs = new TaskCompletionSource <RegistrationOperationStatus>(); Bootstrap bootstrap = new Bootstrap() .Group(s_eventLoopGroup) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { ch.Pipeline.AddLast( new ReadTimeoutHandler(ReadTimeoutSeconds), new TlsHandler(tlsSettings), //TODO: Ensure SystemDefault is used. MqttEncoder.Instance, new MqttDecoder(isServer: false, maxMessageSize: MaxMessageSize), new ProvisioningChannelHandlerAdapter(message, tcs, cancellationToken)); })); if (Logging.IsEnabled) { Logging.Associate(bootstrap, this); } IPAddress[] addresses = await Dns.GetHostAddressesAsync(message.GlobalDeviceEndpoint); if (Logging.IsEnabled) { Logging.Info(this, $"DNS resolved {addresses.Length} addresses."); } IChannel channel = null; Exception lastException = null; foreach (IPAddress address in addresses) { cancellationToken.ThrowIfCancellationRequested(); try { if (Logging.IsEnabled) { Logging.Info(this, $"Connecting to {address.ToString()}."); } channel = await bootstrap.ConnectAsync(address, this.Port); break; } catch (AggregateException ae) { ae.Handle((ex) => { if (ex is ConnectException) // We will handle DotNetty.Transport.Channels.ConnectException { lastException = ex; if (Logging.IsEnabled) { Logging.Info( this, $"ConnectException trying to connect to {address.ToString()}: {ex.ToString()}"); } return(true); } return(false); // Let anything else stop the application. }); } } if (channel == null) { string errorMessage = "Cannot connect to Provisioning Service."; if (Logging.IsEnabled) { Logging.Error(this, errorMessage); } ExceptionDispatchInfo.Capture(lastException).Throw(); } return(await tcs.Task); }
private Func <IPAddress[], int, Task <IChannel> > CreateChannelFactory(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings, ProductInfo productInfo) { return(async(addresses, port) => { IChannel channel = null; Func <Stream, SslStream> streamFactory = stream => new SslStream(stream, true, settings.RemoteCertificateValidationCallback); var certs = settings.ClientCertificate == null ? new List <X509Certificate>(0) : new List <X509Certificate> { settings.ClientCertificate }; SslProtocols protocols = TlsVersions.Instance.Preferred; #if NET451 // Requires hardcoding in NET451 otherwise yields error: // Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException: Transient network error occurred, please retry. // DotNetty.Transport.Channels.ClosedChannelException: I/O error occurred. if (settings.GetTransportType() == TransportType.Mqtt_Tcp_Only && protocols == SslProtocols.None) { protocols = TlsVersions.Instance.MinimumTlsVersions; } #endif var clientTlsSettings = new ClientTlsSettings( protocols, settings.CertificateRevocationCheck, certs, iotHubConnectionString.HostName); Bootstrap bootstrap = new Bootstrap() .Group(s_eventLoopGroup.Value) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { var tlsHandler = new TlsHandler(streamFactory, clientTlsSettings); ch.Pipeline .AddLast( tlsHandler, MqttEncoder.Instance, new MqttDecoder(false, MaxMessageSize), new LoggingHandler(LogLevel.DEBUG), this.mqttIotHubAdapterFactory.Create(this, iotHubConnectionString, settings, productInfo)); })); foreach (IPAddress address in addresses) { try { if (Logging.IsEnabled) { Logging.Info(this, $"Connecting to {address.ToString()}", nameof(CreateChannelFactory)); } channel = await bootstrap.ConnectAsync(address, port).ConfigureAwait(true); break; } catch (AggregateException ae) { ae.Handle((ex) => { if (ex is ConnectException) // We will handle DotNetty.Transport.Channels.ConnectException { if (Logging.IsEnabled) { Logging.Error(this, $"ConnectException trying to connect to {address.ToString()}: {ex.ToString()}", nameof(CreateChannelFactory)); } return true; } return false; // Let anything else stop the application. }); } catch (ConnectException ex) { //same as above, we will handle DotNetty.Transport.Channels.ConnectException if (Logging.IsEnabled) { Logging.Error(this, $"ConnectException trying to connect to {address.ToString()}: {ex.ToString()}", nameof(CreateChannelFactory)); } } } if (channel == null) { throw new IotHubCommunicationException("MQTT channel open failed."); } return channel; }); }