From b7ab29473b5a6902b6aba6cc0acda5d7cfca1cd9 Mon Sep 17 00:00:00 2001 From: JanEggers Date: Sun, 7 Oct 2018 12:10:26 +0200 Subject: [PATCH 1/3] added ability to specify tls protocol version --- Source/MQTTnet/Implementations/MqttTcpServerListener.cs | 9 +++++++-- Source/MQTTnet/Server/MqttServerOptionsBuilder.cs | 7 +++++++ Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs | 7 ++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs index e3522979..e72c831d 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs @@ -20,8 +20,8 @@ namespace MQTTnet.Implementations private readonly CancellationToken _cancellationToken; private readonly AddressFamily _addressFamily; private readonly MqttServerTcpEndpointBaseOptions _options; + private readonly MqttServerTlsTcpEndpointOptions _tlsOptions; private readonly X509Certificate2 _tlsCertificate; - private Socket _socket; public MqttTcpServerListener( @@ -36,6 +36,11 @@ namespace MQTTnet.Implementations _tlsCertificate = tlsCertificate; _cancellationToken = cancellationToken; _logger = logger.CreateChildLogger(nameof(MqttTcpServerListener)); + + if (_options is MqttServerTlsTcpEndpointOptions tlsOptions) + { + _tlsOptions = tlsOptions; + } } public event EventHandler ClientAccepted; @@ -75,7 +80,7 @@ namespace MQTTnet.Implementations if (_tlsCertificate != null) { sslStream = new SslStream(new NetworkStream(clientSocket), false); - await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, SslProtocols.Tls12, false).ConfigureAwait(false); + await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, _tlsOptions.SslProtocol, false).ConfigureAwait(false); } _logger.Verbose("Client '{0}' accepted by TCP listener '{1}, {2}'.", diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs index f54f379f..45400620 100644 --- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs +++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs @@ -1,5 +1,6 @@ using System; using System.Net; +using System.Security.Authentication; namespace MQTTnet.Server { @@ -80,6 +81,12 @@ namespace MQTTnet.Server return this; } + public MqttServerOptionsBuilder WithEncryptionSslProtocol(SslProtocols value) + { + _options.TlsEndpointOptions.SslProtocol = value; + return this; + } + public MqttServerOptionsBuilder WithoutEncryptedEndpoint() { _options.TlsEndpointOptions.IsEnabled = false; diff --git a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs index 76d6c862..88d2f86d 100644 --- a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs @@ -1,4 +1,6 @@ -namespace MQTTnet.Server +using System.Security.Authentication; + +namespace MQTTnet.Server { public class MqttServerTlsTcpEndpointOptions : MqttServerTcpEndpointBaseOptions { @@ -8,5 +10,8 @@ } public byte[] Certificate { get; set; } + + + public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; } } From 583b32f17ae70e009dd95d702c24ee53b7749987 Mon Sep 17 00:00:00 2001 From: JanEggers Date: Sun, 7 Oct 2018 13:24:07 +0200 Subject: [PATCH 2/3] updated release notes --- Build/MQTTnet.nuspec | 1 + 1 file changed, 1 insertion(+) diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index fbcd355a..82536191 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -11,6 +11,7 @@ false MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker). * [Client] Fixed a deadlock when an exception is fired while connecting (thanks to @malibVB). + * [Server] Added ability to specify tls protocol version Copyright Christian Kratky 2016-2018 MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin From 73d33e2200b69a6867d6a83db9aed69ca385ecc9 Mon Sep 17 00:00:00 2001 From: JanEggers Date: Sun, 7 Oct 2018 14:40:57 +0200 Subject: [PATCH 3/3] fixed #421 --- Build/MQTTnet.AspNetCore.nuspec | 3 +- .../MqttConnectionContext.cs | 3 +- .../MQTTnet.AspNetCore.Tests.csproj | 8 ++--- .../Mockups/ConnectionContextMockup.cs | 22 ++++++++++++++ .../Mockups/DuplexPipeMockup.cs | 16 ++++++++++ .../MqttConnectionContextTest.cs | 29 +++++++++++++++++++ .../MQTTnet.Core.Tests.csproj | 2 +- 7 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 Tests/MQTTnet.AspNetCore.Tests/Mockups/ConnectionContextMockup.cs create mode 100644 Tests/MQTTnet.AspNetCore.Tests/Mockups/DuplexPipeMockup.cs create mode 100644 Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs diff --git a/Build/MQTTnet.AspNetCore.nuspec b/Build/MQTTnet.AspNetCore.nuspec index cb1718f3..8809fac6 100644 --- a/Build/MQTTnet.AspNetCore.nuspec +++ b/Build/MQTTnet.AspNetCore.nuspec @@ -10,7 +10,8 @@ https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png false This is a support library to integrate MQTTnet into AspNetCore. - * For more release notes please check the MQTTnet release notes. + * For more release notes please check the MQTTnet release notes. + * [Server] fixed cpu spike in case a client disconnectes (issue 421) Copyright Christian Kratky 2016-2018 MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin diff --git a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs index 8a8469de..361eb6a1 100644 --- a/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs +++ b/Source/MQTTnet.AspnetCore/MqttConnectionContext.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Connections; using MQTTnet.Adapter; using MQTTnet.AspNetCore.Client.Tcp; +using MQTTnet.Exceptions; using MQTTnet.Packets; using MQTTnet.Serializer; using System; @@ -83,7 +84,7 @@ namespace MQTTnet.AspNetCore } else if (readResult.IsCompleted) { - break; + throw new MqttCommunicationException("Connection Aborted"); } } finally diff --git a/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj b/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj index 77dfff97..f45b4fb5 100644 --- a/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj +++ b/Tests/MQTTnet.AspNetCore.Tests/MQTTnet.AspNetCore.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.1 @@ -7,9 +7,9 @@ - - - + + + diff --git a/Tests/MQTTnet.AspNetCore.Tests/Mockups/ConnectionContextMockup.cs b/Tests/MQTTnet.AspNetCore.Tests/Mockups/ConnectionContextMockup.cs new file mode 100644 index 00000000..296959ef --- /dev/null +++ b/Tests/MQTTnet.AspNetCore.Tests/Mockups/ConnectionContextMockup.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.IO.Pipelines; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Http.Features; + +namespace MQTTnet.AspNetCore.Tests.Mockups +{ + public class ConnectionContextMockup : ConnectionContext + { + public override string ConnectionId { get; set; } + + public override IFeatureCollection Features { get; } + + public override IDictionary Items { get; set; } + public override IDuplexPipe Transport { get; set; } + + public ConnectionContextMockup() + { + //Transport = new DefaultConnectionContext + } + } +} diff --git a/Tests/MQTTnet.AspNetCore.Tests/Mockups/DuplexPipeMockup.cs b/Tests/MQTTnet.AspNetCore.Tests/Mockups/DuplexPipeMockup.cs new file mode 100644 index 00000000..1774f180 --- /dev/null +++ b/Tests/MQTTnet.AspNetCore.Tests/Mockups/DuplexPipeMockup.cs @@ -0,0 +1,16 @@ +using System.IO.Pipelines; + +namespace MQTTnet.AspNetCore.Tests.Mockups +{ + public class DuplexPipeMockup : IDuplexPipe + { + PipeReader IDuplexPipe.Input => Receive.Reader; + + PipeWriter IDuplexPipe.Output => Send.Writer; + + + public Pipe Receive { get; set; } = new Pipe(); + + public Pipe Send { get; set; } = new Pipe(); + } +} diff --git a/Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs b/Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs new file mode 100644 index 00000000..7498015e --- /dev/null +++ b/Tests/MQTTnet.AspNetCore.Tests/MqttConnectionContextTest.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Connections; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using MQTTnet.AspNetCore.Tests.Mockups; +using MQTTnet.Exceptions; +using MQTTnet.Serializer; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace MQTTnet.AspNetCore.Tests +{ + [TestClass] + public class MqttConnectionContextTest + { + [TestMethod] + public async Task TestReceivePacketAsyncThrowsWhenReaderCompleted() + { + var serializer = new MqttPacketSerializer {}; + var pipe = new DuplexPipeMockup(); + var connection = new DefaultConnectionContext(); + connection.Transport = pipe; + var ctx = new MqttConnectionContext(serializer, connection); + + pipe.Receive.Writer.Complete(); + + await Assert.ThrowsExceptionAsync(() => ctx.ReceivePacketAsync(TimeSpan.FromSeconds(1), CancellationToken.None)); + } + } +} diff --git a/Tests/MQTTnet.Core.Tests/MQTTnet.Core.Tests.csproj b/Tests/MQTTnet.Core.Tests/MQTTnet.Core.Tests.csproj index 40697e94..ff820b29 100644 --- a/Tests/MQTTnet.Core.Tests/MQTTnet.Core.Tests.csproj +++ b/Tests/MQTTnet.Core.Tests/MQTTnet.Core.Tests.csproj @@ -9,7 +9,7 @@ - +