From a03bdc7616d61eb9217ff391c60b6ecd741b3a7f Mon Sep 17 00:00:00 2001 From: Craig Lutgen Date: Wed, 31 Jul 2019 13:04:03 -0500 Subject: [PATCH 01/19] Expose server certificate password and client certificate options to MqttServerOptionsBuilder --- .../Client/Options/MqttClientOptionsBuilder.cs | 7 +++++++ .../MQTTnet/Implementations/MqttTcpServerAdapter.cs | 2 +- Source/MQTTnet/Server/IMqttServerCredentials.cs | 6 ++++++ Source/MQTTnet/Server/MqttServerOptionsBuilder.cs | 13 +++++++++++-- .../Server/MqttServerTlsTcpEndpointOptions.cs | 2 ++ 5 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 Source/MQTTnet/Server/IMqttServerCredentials.cs diff --git a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs index a7aefd18..65a1ec99 100644 --- a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs +++ b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs @@ -139,6 +139,13 @@ namespace MQTTnet.Client.Options return this; } + public MqttClientOptionsBuilder WithCredentials(IMqttClientCredentials credentials) + { + _options.Credentials = credentials; + + return this; + } + public MqttClientOptionsBuilder WithExtendedAuthenticationExchangeHandler(IMqttExtendedAuthenticationExchangeHandler handler) { _options.ExtendedAuthenticationExchangeHandler = handler; diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs index 0e28ad00..8ef8c513 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs @@ -48,7 +48,7 @@ namespace MQTTnet.Implementations throw new ArgumentException("TLS certificate is not set."); } - var tlsCertificate = new X509Certificate2(options.TlsEndpointOptions.Certificate); + var tlsCertificate = new X509Certificate2(options.TlsEndpointOptions.Certificate, options.TlsEndpointOptions.Password.Password); if (!tlsCertificate.HasPrivateKey) { throw new InvalidOperationException("The certificate for TLS encryption must contain the private key."); diff --git a/Source/MQTTnet/Server/IMqttServerCredentials.cs b/Source/MQTTnet/Server/IMqttServerCredentials.cs new file mode 100644 index 00000000..5e75be90 --- /dev/null +++ b/Source/MQTTnet/Server/IMqttServerCredentials.cs @@ -0,0 +1,6 @@ +using System; + +public interface IMqttServerCredentials +{ + String Password { get; } +} diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs index 1fcd9812..de6b1a01 100644 --- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs +++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs @@ -82,9 +82,10 @@ namespace MQTTnet.Server return this; } - public MqttServerOptionsBuilder WithEncryptionCertificate(byte[] value) + public MqttServerOptionsBuilder WithEncryptionCertificate(byte[] value, IMqttServerCredentials password = null) { _options.TlsEndpointOptions.Certificate = value; + _options.TlsEndpointOptions.Password = password; return this; } @@ -94,6 +95,14 @@ namespace MQTTnet.Server return this; } + public MqttServerOptionsBuilder WithClientCertificate(RemoteCertificateValidationCallback validationCallback = null, bool checkCertificateRevocation = false) + { + _options.TlsEndpointOptions.ClientCertificateRequired = true; + _options.TlsEndpointOptions.CheckCertificateRevocation = checkCertificateRevocation; + _options.TlsEndpointOptions.CertificateValidationCallback = validationCallback; + return this; + } + public MqttServerOptionsBuilder WithoutEncryptedEndpoint() { _options.TlsEndpointOptions.IsEnabled = false; @@ -107,7 +116,7 @@ namespace MQTTnet.Server return this; } #endif - + public MqttServerOptionsBuilder WithStorage(IMqttServerStorage value) { _options.Storage = value; diff --git a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs index 282bef9d..8d652308 100644 --- a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs @@ -12,6 +12,8 @@ namespace MQTTnet.Server public byte[] Certificate { get; set; } + public IMqttServerCredentials Password { get; set; } + public bool ClientCertificateRequired { get; set; } public bool CheckCertificateRevocation { get; set; } From 9d63500f95a2ee835a9095bafd02fe91f8e48920 Mon Sep 17 00:00:00 2001 From: Craig Lutgen Date: Wed, 31 Jul 2019 13:27:33 -0500 Subject: [PATCH 02/19] Fix build issue with UWP --- Source/MQTTnet/Server/MqttServerOptionsBuilder.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs index de6b1a01..84042713 100644 --- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs +++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs @@ -95,13 +95,15 @@ namespace MQTTnet.Server return this; } +#if !WINDOWS_UWP public MqttServerOptionsBuilder WithClientCertificate(RemoteCertificateValidationCallback validationCallback = null, bool checkCertificateRevocation = false) { _options.TlsEndpointOptions.ClientCertificateRequired = true; _options.TlsEndpointOptions.CheckCertificateRevocation = checkCertificateRevocation; - _options.TlsEndpointOptions.CertificateValidationCallback = validationCallback; + _options.TlsEndpointOptions.RemoteCertificateValidationCallback = validationCallback; return this; } +#endif public MqttServerOptionsBuilder WithoutEncryptedEndpoint() { From 30c5147c62d11183d8f606ba652da091caf14f9d Mon Sep 17 00:00:00 2001 From: HansM Date: Fri, 2 Aug 2019 08:46:12 +0200 Subject: [PATCH 03/19] Fixed bug reports issue template. --- .github/ISSUE_TEMPLATE/bug_report.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ee70ac0d..d78b1981 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,11 +11,12 @@ assignees: '' A clear and concise description of what the bug is. ### Which project is your bug related to? -- [x] Client -- [ ] ManagedClient -- [ ] MQTTnet.Server standalone -- [ ] Server -- [ ] Generic + +- Client +- ManagedClient +- MQTTnet.Server standalone +- Server +- Generic ### To Reproduce Steps to reproduce the behavior: From b82e5a48a4f4e6a2e898fe85d4688e3495b1bca2 Mon Sep 17 00:00:00 2001 From: HansM Date: Fri, 2 Aug 2019 08:46:35 +0200 Subject: [PATCH 04/19] Fixed custom issue template. --- .github/ISSUE_TEMPLATE/custom.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index 8ec115e0..4ee93d11 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -11,8 +11,9 @@ assignees: '' A clear and concise description of what you want to know. ### Which project is your bug related to? -- [x] Client -- [ ] ManagedClient -- [ ] MQTTnet.Server standalone -- [ ] Server -- [ ] Generic + +- Client +- ManagedClient +- MQTTnet.Server standalone +- Server +- Generic From 8607ceb3b7b0a2906a8e9a52b566ac2a9757bcf7 Mon Sep 17 00:00:00 2001 From: HansM Date: Fri, 2 Aug 2019 08:47:09 +0200 Subject: [PATCH 05/19] Fixed feature request issue template. --- .github/ISSUE_TEMPLATE/feature_request.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 23a133d8..93719329 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -12,11 +12,12 @@ Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Example. I'm am trying to do [...] but [...] ### Which project is your feature request related to? -- [x] Client -- [ ] ManagedClient -- [ ] MQTTnet.Server standalone -- [ ] Server -- [ ] Generic + +- Client +- ManagedClient +- MQTTnet.Server standalone +- Server +- Generic ### Describe the solution you'd like A clear and concise description of what you want to happen. From 59d2a8e551f09e9eb57597798a40e024f3a7147c Mon Sep 17 00:00:00 2001 From: Craig Lutgen Date: Thu, 8 Aug 2019 13:35:14 -0500 Subject: [PATCH 06/19] Changed server crentials property name from password to certificateCredentials --- Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs | 2 +- Source/MQTTnet/Server/MqttServerOptionsBuilder.cs | 4 ++-- Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs index 8ef8c513..e3dcab88 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs @@ -48,7 +48,7 @@ namespace MQTTnet.Implementations throw new ArgumentException("TLS certificate is not set."); } - var tlsCertificate = new X509Certificate2(options.TlsEndpointOptions.Certificate, options.TlsEndpointOptions.Password.Password); + var tlsCertificate = new X509Certificate2(options.TlsEndpointOptions.Certificate, options.TlsEndpointOptions.CertificateCredentials.Password); if (!tlsCertificate.HasPrivateKey) { throw new InvalidOperationException("The certificate for TLS encryption must contain the private key."); diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs index 84042713..5991e7d5 100644 --- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs +++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs @@ -82,10 +82,10 @@ namespace MQTTnet.Server return this; } - public MqttServerOptionsBuilder WithEncryptionCertificate(byte[] value, IMqttServerCredentials password = null) + public MqttServerOptionsBuilder WithEncryptionCertificate(byte[] value, IMqttServerCredentials credentials = null) { _options.TlsEndpointOptions.Certificate = value; - _options.TlsEndpointOptions.Password = password; + _options.TlsEndpointOptions.CertificateCredentials = credentials; return this; } diff --git a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs index 8d652308..e92d9877 100644 --- a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs @@ -12,7 +12,7 @@ namespace MQTTnet.Server public byte[] Certificate { get; set; } - public IMqttServerCredentials Password { get; set; } + public IMqttServerCredentials CertificateCredentials { get; set; } public bool ClientCertificateRequired { get; set; } From 0f14ddcf7995354d46bb8929d4f9ba647283168b Mon Sep 17 00:00:00 2001 From: HansM Date: Fri, 9 Aug 2019 11:13:06 +0200 Subject: [PATCH 07/19] Updated bug report issue template. --- .github/ISSUE_TEMPLATE/bug_report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d78b1981..f2280abb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -36,9 +36,11 @@ Add any other context about the problem here. Include debugging or logging information here: ```batch +\\ Put your logging output here. ``` ### Code example Please provide full code examples below where possible to make it easier for the developers to check your issues. ```csharp +\\ Put your code here. ``` From ad5b0caa4dc0cc8880dc6d59e8a59dfc794476eb Mon Sep 17 00:00:00 2001 From: HansM Date: Fri, 9 Aug 2019 11:13:40 +0200 Subject: [PATCH 08/19] Fixed spelling issue in feature request issue template. --- .github/ISSUE_TEMPLATE/custom.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index 4ee93d11..ae9462de 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -10,7 +10,7 @@ assignees: '' ### Describe your question A clear and concise description of what you want to know. -### Which project is your bug related to? +### Which project is your feature request related to? - Client - ManagedClient From 048206eb1e6e78553e73e584c69d5f17b56e8956 Mon Sep 17 00:00:00 2001 From: HansM Date: Fri, 9 Aug 2019 11:14:52 +0200 Subject: [PATCH 09/19] Fixed my spelling mistake from before. --- .github/ISSUE_TEMPLATE/custom.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index ae9462de..76dd9c07 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -10,7 +10,7 @@ assignees: '' ### Describe your question A clear and concise description of what you want to know. -### Which project is your feature request related to? +### Which project is your question related to? - Client - ManagedClient From 01aa75471ca9ac801b6313032f459cf26171f906 Mon Sep 17 00:00:00 2001 From: SeppPenner Date: Fri, 9 Aug 2019 11:20:28 +0200 Subject: [PATCH 10/19] Updated description of issue templates. --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/custom.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f2280abb..1941a25b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Create a report to help us improve +about: Create a report to help us improve. title: '' labels: '' assignees: '' diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index 76dd9c07..fb7bdc39 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -1,6 +1,6 @@ --- name: Custom issue template -about: Describe this issue template's purpose here. +about: Do you have a question related to the project? Use this template. title: '' labels: '' assignees: '' diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 93719329..c76e79f3 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,6 +1,6 @@ --- name: Feature request -about: Suggest an idea for this project +about: Suggest an idea for this project. title: '' labels: '' assignees: '' From 524f69582954fb4efbd2005119acd4d5705982ab Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Fri, 9 Aug 2019 22:21:42 +0200 Subject: [PATCH 11/19] Update docs. --- Build/MQTTnet.nuspec | 1 + Source/MQTTnet/MQTTnet.csproj | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index 8fc2673c..6aafdc68 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -19,6 +19,7 @@ * [Server] Fixed: Sending Large packets with AspnetCore based connection throws System.ArgumentException. * [Server] Fixed wrong usage of socket option _NoDelay_. * [Server] Added remote certificate validation callback (thanks to @rudacs). +* [Server] Add support for certificate passwords (thanks to @cslutgen). * [MQTTnet.Server] Added REST API for publishing basic messages. Copyright Christian Kratky 2016-2019 diff --git a/Source/MQTTnet/MQTTnet.csproj b/Source/MQTTnet/MQTTnet.csproj index 5e0251da..61ca5177 100644 --- a/Source/MQTTnet/MQTTnet.csproj +++ b/Source/MQTTnet/MQTTnet.csproj @@ -41,13 +41,13 @@ RELEASE;NETSTANDARD1_3 - + - + From 2300e68fff459314dcf4db3ef80a1b66d5c0086f Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 10:41:36 +0200 Subject: [PATCH 12/19] Add UnitTests for RPC. --- Tests/MQTTnet.Core.Tests/RPC_Tests.cs | 67 +++++++++++++++++++++------ 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/Tests/MQTTnet.Core.Tests/RPC_Tests.cs b/Tests/MQTTnet.Core.Tests/RPC_Tests.cs index b0babfa0..9f03172d 100644 --- a/Tests/MQTTnet.Core.Tests/RPC_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/RPC_Tests.cs @@ -8,6 +8,8 @@ using MQTTnet.Client.Receiving; using MQTTnet.Exceptions; using MQTTnet.Extensions.Rpc; using MQTTnet.Protocol; +using MQTTnet.Client.Options; +using MQTTnet.Formatter; namespace MQTTnet.Tests { @@ -15,26 +17,39 @@ namespace MQTTnet.Tests public class RPC_Tests { [TestMethod] - public async Task Execute_Success() + public Task Execute_Success_With_QoS_0() { - using (var testEnvironment = new TestEnvironment()) - { - await testEnvironment.StartServerAsync(); - var responseSender = await testEnvironment.ConnectClientAsync(); - await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping"); + return Execute_Success(MqttQualityOfServiceLevel.AtMostOnce, MqttProtocolVersion.V311); + } - responseSender.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(async e => - { - await responseSender.PublishAsync(e.ApplicationMessage.Topic + "/response", "pong"); - }); + [TestMethod] + public Task Execute_Success_With_QoS_1() + { + return Execute_Success(MqttQualityOfServiceLevel.AtLeastOnce, MqttProtocolVersion.V311); + } - var requestSender = await testEnvironment.ConnectClientAsync(); + [TestMethod] + public Task Execute_Success_With_QoS_2() + { + return Execute_Success(MqttQualityOfServiceLevel.ExactlyOnce, MqttProtocolVersion.V311); + } - var rpcClient = new MqttRpcClient(requestSender); - var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), "ping", "", MqttQualityOfServiceLevel.AtMostOnce); + [TestMethod] + public Task Execute_Success_With_QoS_0_MQTT_V5() + { + return Execute_Success(MqttQualityOfServiceLevel.AtMostOnce, MqttProtocolVersion.V500); + } - Assert.AreEqual("pong", Encoding.UTF8.GetString(response)); - } + [TestMethod] + public Task Execute_Success_With_QoS_1_MQTT_V5() + { + return Execute_Success(MqttQualityOfServiceLevel.AtLeastOnce, MqttProtocolVersion.V500); + } + + [TestMethod] + public Task Execute_Success_With_QoS_2_MQTT_V5() + { + return Execute_Success(MqttQualityOfServiceLevel.ExactlyOnce, MqttProtocolVersion.V500); } [TestMethod] @@ -51,5 +66,27 @@ namespace MQTTnet.Tests await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce); } } + + private async Task Execute_Success(MqttQualityOfServiceLevel qosLevel, MqttProtocolVersion protocolVersion) + { + using (var testEnvironment = new TestEnvironment()) + { + await testEnvironment.StartServerAsync(); + var responseSender = await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithProtocolVersion(protocolVersion)); + await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping"); + + responseSender.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(async e => + { + await responseSender.PublishAsync(e.ApplicationMessage.Topic + "/response", "pong"); + }); + + var requestSender = await testEnvironment.ConnectClientAsync(); + + var rpcClient = new MqttRpcClient(requestSender); + var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), "ping", "", qosLevel); + + Assert.AreEqual("pong", Encoding.UTF8.GetString(response)); + } + } } } From 4a7ff9e9ed1404230971700137065c58a2a871bb Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 21:45:41 +0200 Subject: [PATCH 13/19] Add TLS certificate password support for MQTTnet.Server. --- .../Configuration/CertificateSettingsModel.cs | 35 +++++++++++++++++++ .../Configuration/TcpEndpointModel.cs | 23 ++---------- .../MQTTnet.Server/Mqtt/MqttServerService.cs | 22 +++++++++--- Source/MQTTnet.Server/appsettings.json | 7 ++-- 4 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 Source/MQTTnet.Server/Configuration/CertificateSettingsModel.cs diff --git a/Source/MQTTnet.Server/Configuration/CertificateSettingsModel.cs b/Source/MQTTnet.Server/Configuration/CertificateSettingsModel.cs new file mode 100644 index 00000000..89eb48b2 --- /dev/null +++ b/Source/MQTTnet.Server/Configuration/CertificateSettingsModel.cs @@ -0,0 +1,35 @@ +using System.IO; + +namespace MQTTnet.Server.Configuration +{ + public class CertificateSettingsModel + { + /// + /// Path to certificate. + /// + public string Path { get; set; } + + /// + /// Password of certificate. + /// + public string Password { get; set; } + + /// + /// Read certificate file. + /// + public byte[] ReadCertificate() + { + if (string.IsNullOrEmpty(Path) || string.IsNullOrWhiteSpace(Path)) + { + throw new FileNotFoundException("No path set"); + } + + if (!File.Exists(Path)) + { + throw new FileNotFoundException($"Could not find Certificate in path: {Path}"); + } + + return File.ReadAllBytes(Path); + } + } +} diff --git a/Source/MQTTnet.Server/Configuration/TcpEndpointModel.cs b/Source/MQTTnet.Server/Configuration/TcpEndpointModel.cs index 82213901..8693268d 100644 --- a/Source/MQTTnet.Server/Configuration/TcpEndpointModel.cs +++ b/Source/MQTTnet.Server/Configuration/TcpEndpointModel.cs @@ -9,9 +9,9 @@ namespace MQTTnet.Server.Configuration public class TcpEndPointModel { /// - /// Path to Certificate + /// Certificate settings. /// - public string CertificatePath { get; set; } + public CertificateSettingsModel Certificate { get; set; } /// /// Enabled / Disable @@ -33,25 +33,6 @@ namespace MQTTnet.Server.Configuration /// public int Port { get; set; } = 1883; - /// - /// Read Certificate file - /// - /// - public byte[] ReadCertificate() - { - if (string.IsNullOrEmpty(CertificatePath) || string.IsNullOrWhiteSpace(CertificatePath)) - { - throw new FileNotFoundException("No path set"); - } - - if (!File.Exists(CertificatePath)) - { - throw new FileNotFoundException($"Could not find Certificate in path: {CertificatePath}"); - } - - return File.ReadAllBytes(CertificatePath); - } - /// /// Read IPv4 /// diff --git a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs index efb00104..b8c463fc 100644 --- a/Source/MQTTnet.Server/Mqtt/MqttServerService.cs +++ b/Source/MQTTnet.Server/Mqtt/MqttServerService.cs @@ -47,7 +47,7 @@ namespace MQTTnet.Server.Mqtt MqttSubscriptionInterceptor mqttSubscriptionInterceptor, MqttApplicationMessageInterceptor mqttApplicationMessageInterceptor, MqttServerStorage mqttServerStorage, - PythonScriptHostService pythonScriptHostService, + PythonScriptHostService pythonScriptHostService, ILogger logger) { _settings = mqttSettings ?? throw new ArgumentNullException(nameof(mqttSettings)); @@ -179,7 +179,7 @@ namespace MQTTnet.Server.Mqtt .WithApplicationMessageInterceptor(_mqttApplicationMessageInterceptor) .WithSubscriptionInterceptor(_mqttSubscriptionInterceptor) .WithStorage(_mqttServerStorage); - + // Configure unencrypted connections if (_settings.TcpEndPoint.Enabled) { @@ -210,9 +210,23 @@ namespace MQTTnet.Server.Mqtt { options .WithEncryptedEndpoint() - .WithEncryptionSslProtocol(SslProtocols.Tls12) - .WithEncryptionCertificate(_settings.EncryptedTcpEndPoint.ReadCertificate()); + .WithEncryptionSslProtocol(SslProtocols.Tls12); + + if (!string.IsNullOrEmpty(_settings.EncryptedTcpEndPoint?.Certificate?.Path)) + { + IMqttServerCertificateCredentials certificateCredentials = null; + if (!string.IsNullOrEmpty(_settings.EncryptedTcpEndPoint?.Certificate?.Password)) + { + certificateCredentials = new MqttServerCertificateCredentials + { + Password = _settings.EncryptedTcpEndPoint.Certificate.Password + }; + } + + options.WithEncryptionCertificate(_settings.EncryptedTcpEndPoint.Certificate.ReadCertificate(), certificateCredentials); + } + if (_settings.EncryptedTcpEndPoint.TryReadIPv4(out var address4)) { options.WithEncryptedEndpointBoundIPAddress(address4); diff --git a/Source/MQTTnet.Server/appsettings.json b/Source/MQTTnet.Server/appsettings.json index 8ea10d6b..71eaf206 100644 --- a/Source/MQTTnet.Server/appsettings.json +++ b/Source/MQTTnet.Server/appsettings.json @@ -27,7 +27,10 @@ "IPv4": "*", "IPv6": "*", "Port": 8883, - "CertificatePath": "/absolute/path/to/pfx" + "Certificate": { + "Path": "/absolute/path/to/pfx", + "Password": "" + } }, "WebSocketEndPoint": { "Enabled": true, @@ -63,4 +66,4 @@ } }, "AllowedHosts": "*" -} +} \ No newline at end of file From 8ad1fb287144b0ff8fa34a5736afd48bfdae2835 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 21:46:13 +0200 Subject: [PATCH 14/19] Refactor server certificate classes (breaking change). --- Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs | 4 ++++ Source/MQTTnet/Server/IMqttServerCredentials.cs | 6 ------ Source/MQTTnet/Server/MqttServerCertificateCredentials.cs | 7 +++++++ Source/MQTTnet/Server/MqttServerOptionsBuilder.cs | 2 +- Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs delete mode 100644 Source/MQTTnet/Server/IMqttServerCredentials.cs create mode 100644 Source/MQTTnet/Server/MqttServerCertificateCredentials.cs diff --git a/Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs b/Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs new file mode 100644 index 00000000..3f5fe0ea --- /dev/null +++ b/Source/MQTTnet/Server/IMqttServerCertificateCredentials.cs @@ -0,0 +1,4 @@ +public interface IMqttServerCertificateCredentials +{ + string Password { get; } +} diff --git a/Source/MQTTnet/Server/IMqttServerCredentials.cs b/Source/MQTTnet/Server/IMqttServerCredentials.cs deleted file mode 100644 index 5e75be90..00000000 --- a/Source/MQTTnet/Server/IMqttServerCredentials.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System; - -public interface IMqttServerCredentials -{ - String Password { get; } -} diff --git a/Source/MQTTnet/Server/MqttServerCertificateCredentials.cs b/Source/MQTTnet/Server/MqttServerCertificateCredentials.cs new file mode 100644 index 00000000..05b6c5f0 --- /dev/null +++ b/Source/MQTTnet/Server/MqttServerCertificateCredentials.cs @@ -0,0 +1,7 @@ +namespace MQTTnet.Server +{ + public class MqttServerCertificateCredentials : IMqttServerCertificateCredentials + { + public string Password { get; set; } + } +} diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs index 5991e7d5..c25af84b 100644 --- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs +++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs @@ -82,7 +82,7 @@ namespace MQTTnet.Server return this; } - public MqttServerOptionsBuilder WithEncryptionCertificate(byte[] value, IMqttServerCredentials credentials = null) + public MqttServerOptionsBuilder WithEncryptionCertificate(byte[] value, IMqttServerCertificateCredentials credentials = null) { _options.TlsEndpointOptions.Certificate = value; _options.TlsEndpointOptions.CertificateCredentials = credentials; diff --git a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs index e92d9877..9bf325b1 100644 --- a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs @@ -12,7 +12,7 @@ namespace MQTTnet.Server public byte[] Certificate { get; set; } - public IMqttServerCredentials CertificateCredentials { get; set; } + public IMqttServerCertificateCredentials CertificateCredentials { get; set; } public bool ClientCertificateRequired { get; set; } From 6d0e2c20223a3d313276983ab389c7e560e4a7a1 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 22:07:57 +0200 Subject: [PATCH 15/19] Remove dedicated UWP builds and code. --- Build/MQTTnet.nuspec | 30 +- Build/build.ps1 | 8 - MQTTnet.noUWP.sln | 260 ------------------ .../MQTTnet.Extensions.ManagedClient.csproj | 16 +- .../MQTTnet.Extensions.Rpc.csproj | 16 +- .../MQTTnet.Extensions.WebSocket4Net.csproj | 16 +- .../TargetFrameworkInfoProvider.cs | 6 - Source/MQTTnet/Formatter/MqttPacketReader.cs | 53 ---- .../Implementations/MqttTcpChannel.Uwp.cs | 196 ------------- .../MQTTnet/Implementations/MqttTcpChannel.cs | 6 +- .../MqttTcpServerAdapter.Uwp.cs | 122 -------- .../Implementations/MqttTcpServerAdapter.cs | 6 +- .../Implementations/MqttTcpServerListener.cs | 10 +- .../Implementations/MqttWebSocketChannel.cs | 6 +- Source/MQTTnet/MQTTnet.csproj | 31 +-- .../Server/MqttServerOptionsBuilder.cs | 6 +- .../MqttServerTcpEndpointBaseOptions.cs | 4 - .../Server/MqttServerTlsTcpEndpointOptions.cs | 4 +- .../MainPage.xaml.cs | 13 +- 19 files changed, 26 insertions(+), 783 deletions(-) delete mode 100644 MQTTnet.noUWP.sln delete mode 100644 Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs delete mode 100644 Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index 6aafdc68..eded1fd9 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -11,16 +11,9 @@ false MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol. -* [Core] Nuget packages with symbols are now also published to improve debugging. -* [Core] Improve task handling (thanks to @mwinterb) -* [ManagedClient] Fix a race condition in the message storage (thanks to @PaulFake). -* [Server] Added items dictionary to client session in order to share data across interceptors as along as the session exists. -* [Server] Exposed CONNECT packet properties in Application Message and Subscription interceptor. -* [Server] Fixed: Sending Large packets with AspnetCore based connection throws System.ArgumentException. -* [Server] Fixed wrong usage of socket option _NoDelay_. -* [Server] Added remote certificate validation callback (thanks to @rudacs). -* [Server] Add support for certificate passwords (thanks to @cslutgen). -* [MQTTnet.Server] Added REST API for publishing basic messages. +* [Core] Removed dedicated UWP builds. The lib is now supporting net452, netstandard1.3 and netstandard2.0 only (which covers mostly everything currently supported by MS). +* [Server] Refactoring of TLS certificate handling (BREAKING CHANGE!) +* [MQTTnet.Server] Added support for passwords when using TLS certificate (BREAKING CHANGE!) Copyright Christian Kratky 2016-2019 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 @@ -37,31 +30,22 @@ - - - + + + + - - - - - - - - - - \ No newline at end of file diff --git a/Build/build.ps1 b/Build/build.ps1 index 33f27677..08107dc3 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -14,34 +14,26 @@ Write-Host # Build the core library &$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the ASP.NET Core 2.0 extension &$msbuild ..\Source\MQTTnet.AspNetCore\MQTTnet.AspNetCore.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the RPC extension &$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the Managed Client extension &$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the WebSocket4Net extension &$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" -&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Create NuGet packages. diff --git a/MQTTnet.noUWP.sln b/MQTTnet.noUWP.sln deleted file mode 100644 index 3d842a5e..00000000 --- a/MQTTnet.noUWP.sln +++ /dev/null @@ -1,260 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27004.2010 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9248C2E1-B9D6-40BF-81EC-86004D7765B4}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{32A630A7-2598-41D7-B625-204CD906F5FB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet", "Source\MQTTnet\MQTTnet.csproj", "{3587E506-55A2-4EB3-99C7-DC01E42D25D2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{67C28AC1-BC3A-420A-BE9C-FA2401431CF9}" - ProjectSection(SolutionItems) = preProject - Build\build.ps1 = Build\build.ps1 - Build\MQTTnet.AspNetCore.nuspec = Build\MQTTnet.AspNetCore.nuspec - Build\MQTTnet.Extensions.ManagedClient.nuspec = Build\MQTTnet.Extensions.ManagedClient.nuspec - Build\MQTTnet.Extensions.Rpc.nuspec = Build\MQTTnet.Extensions.Rpc.nuspec - Build\MQTTnet.nuspec = Build\MQTTnet.nuspec - Build\upload.ps1 = Build\upload.ps1 - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}" - ProjectSection(SolutionItems) = preProject - .bettercodehub.yml = .bettercodehub.yml - appveyor.yml = appveyor.yml - LICENSE = LICENSE - README.md = README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.NetCore", "Tests\MQTTnet.TestApp.NetCore\MQTTnet.TestApp.NetCore.csproj", "{3D283AAD-AAA8-4339-8394-52F80B6304DB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.AspNetCore2", "Tests\MQTTnet.TestApp.AspNetCore2\MQTTnet.TestApp.AspNetCore2.csproj", "{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore", "Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj", "{F10C4060-F7EE-4A83-919F-FF723E72F94A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{12816BCC-AF9E-44A9-9AE5-C246AF2A0587}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.Rpc", "Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj", "{C444E9C8-95FA-430E-9126-274129DE16CD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Benchmarks", "Tests\MQTTnet.Benchmarks\MQTTnet.Benchmarks.csproj", "{998D04DD-7CB0-45F5-A393-E2495C16399E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.ManagedClient", "Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj", "{C400533A-8EBA-4F0B-BF4D-295C3708604B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore.Tests", "Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj", "{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Tests", "Tests\MQTTnet.Core.Tests\MQTTnet.Tests.csproj", "{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Server", "Source\MQTTnet.Server\MQTTnet.Server.csproj", "{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.WebSocket4Net", "Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj", "{9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.ActiveCfg = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.Build.0 = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.ActiveCfg = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.Build.0 = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.ActiveCfg = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.Build.0 = Debug|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.Build.0 = Release|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.ActiveCfg = Release|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.Build.0 = Release|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.ActiveCfg = Release|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.Build.0 = Release|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.ActiveCfg = Release|Any CPU - {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.Build.0 = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.ActiveCfg = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.Build.0 = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.ActiveCfg = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.Build.0 = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.ActiveCfg = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.Build.0 = Debug|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.Build.0 = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.ActiveCfg = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.Build.0 = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.ActiveCfg = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.Build.0 = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.ActiveCfg = Release|Any CPU - {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.Build.0 = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.ActiveCfg = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.Build.0 = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.ActiveCfg = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.Build.0 = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.ActiveCfg = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.Build.0 = Debug|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.Build.0 = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.ActiveCfg = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.Build.0 = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.ActiveCfg = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.Build.0 = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.ActiveCfg = Release|Any CPU - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.Build.0 = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.ActiveCfg = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.Build.0 = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.ActiveCfg = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.Build.0 = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.ActiveCfg = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.Build.0 = Debug|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.Build.0 = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.ActiveCfg = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.Build.0 = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.ActiveCfg = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.Build.0 = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.ActiveCfg = Release|Any CPU - {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.Build.0 = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.ActiveCfg = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.Build.0 = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.ActiveCfg = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.Build.0 = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.ActiveCfg = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.Build.0 = Debug|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.Build.0 = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.ActiveCfg = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.Build.0 = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.ActiveCfg = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.Build.0 = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.ActiveCfg = Release|Any CPU - {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.Build.0 = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.Build.0 = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.ActiveCfg = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.Build.0 = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.ActiveCfg = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.Build.0 = Debug|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.Build.0 = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.ActiveCfg = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.Build.0 = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.ActiveCfg = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.Build.0 = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.ActiveCfg = Release|Any CPU - {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.Build.0 = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.ActiveCfg = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.Build.0 = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.ActiveCfg = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.Build.0 = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.ActiveCfg = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.Build.0 = Debug|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.Build.0 = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.ActiveCfg = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.Build.0 = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.ActiveCfg = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.Build.0 = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.ActiveCfg = Release|Any CPU - {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.Build.0 = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.ActiveCfg = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.Build.0 = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.ActiveCfg = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.Build.0 = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.ActiveCfg = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.Build.0 = Debug|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.Build.0 = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.ActiveCfg = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.Build.0 = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.ActiveCfg = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.Build.0 = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.ActiveCfg = Release|Any CPU - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.Build.0 = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.ActiveCfg = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.Build.0 = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.ActiveCfg = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.Build.0 = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.ActiveCfg = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.Build.0 = Debug|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.Build.0 = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.ActiveCfg = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.Build.0 = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.ActiveCfg = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.Build.0 = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.ActiveCfg = Release|Any CPU - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.Build.0 = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.ActiveCfg = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.Build.0 = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.ActiveCfg = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.Build.0 = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.ActiveCfg = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.Build.0 = Debug|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.Build.0 = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.ActiveCfg = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.Build.0 = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.ActiveCfg = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.Build.0 = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.ActiveCfg = Release|Any CPU - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.Build.0 = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|ARM.ActiveCfg = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|ARM.Build.0 = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x64.ActiveCfg = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x64.Build.0 = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x86.ActiveCfg = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x86.Build.0 = Debug|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|Any CPU.Build.0 = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|ARM.ActiveCfg = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|ARM.Build.0 = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x64.ActiveCfg = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x64.Build.0 = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x86.ActiveCfg = Release|Any CPU - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {3587E506-55A2-4EB3-99C7-DC01E42D25D2} = {32A630A7-2598-41D7-B625-204CD906F5FB} - {3D283AAD-AAA8-4339-8394-52F80B6304DB} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} - {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} - {F10C4060-F7EE-4A83-919F-FF723E72F94A} = {32A630A7-2598-41D7-B625-204CD906F5FB} - {C444E9C8-95FA-430E-9126-274129DE16CD} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587} - {998D04DD-7CB0-45F5-A393-E2495C16399E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} - {C400533A-8EBA-4F0B-BF4D-295C3708604B} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587} - {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} - {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} - {DADEA836-5CC3-474C-A2D8-4D0F31118CD7} = {32A630A7-2598-41D7-B625-204CD906F5FB} - {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {07536672-5CBC-4BE3-ACE0-708A431A7894} - EndGlobalSection -EndGlobal diff --git a/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj b/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj index b59b7f40..80131c44 100644 --- a/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj +++ b/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj @@ -2,27 +2,13 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452;net461 - $(TargetFrameworks);uap10.0 + $(TargetFrameworks);net452 - - false - UAP,Version=v10.0 - UAP - 10.0.17134.0 - 10.0.10240.0 - .NETCore - v5.0 - $(DefineConstants);WINDOWS_UWP - en - $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets - - diff --git a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj index b59b7f40..80131c44 100644 --- a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj +++ b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj @@ -2,27 +2,13 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452;net461 - $(TargetFrameworks);uap10.0 + $(TargetFrameworks);net452 - - false - UAP,Version=v10.0 - UAP - 10.0.17134.0 - 10.0.10240.0 - .NETCore - v5.0 - $(DefineConstants);WINDOWS_UWP - en - $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets - - diff --git a/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj b/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj index bdf26c6f..639e0488 100644 --- a/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj +++ b/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj @@ -2,27 +2,13 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452;net461 - $(TargetFrameworks);uap10.0 + $(TargetFrameworks);net452 - - false - UAP,Version=v10.0 - UAP - 10.0.17134.0 - 10.0.10240.0 - .NETCore - v5.0 - $(DefineConstants);WINDOWS_UWP - en - $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets - - diff --git a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs b/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs index efbf08b8..fec08097 100644 --- a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs +++ b/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs @@ -8,16 +8,10 @@ { #if NET452 return "net452"; -#elif NET461 - return "net461"; -#elif NET472 - return "net472"; #elif NETSTANDARD1_3 return "netstandard1.3"; #elif NETSTANDARD2_0 return "netstandard2.0"; -#elif WINDOWS_UWP - return "uap10.0"; #endif } } diff --git a/Source/MQTTnet/Formatter/MqttPacketReader.cs b/Source/MQTTnet/Formatter/MqttPacketReader.cs index 2589c5b2..5cd4dcf4 100644 --- a/Source/MQTTnet/Formatter/MqttPacketReader.cs +++ b/Source/MQTTnet/Formatter/MqttPacketReader.cs @@ -55,16 +55,7 @@ namespace MQTTnet.Formatter }; } -#if WINDOWS_UWP - // UWP will have a dead lock when calling this not async. var bodyLength = await ReadBodyLengthAsync(buffer[1], cancellationToken).ConfigureAwait(false); -#else - // Here the async/await pattern is not used because the overhead of context switches - // is too big for reading 1 byte in a row. We expect that the remaining data was sent - // directly after the initial bytes. If the client disconnects just in this moment we - // will get an exception anyway. - var bodyLength = ReadBodyLength(buffer[1], cancellationToken); -#endif if (!bodyLength.HasValue) { @@ -81,49 +72,6 @@ namespace MQTTnet.Formatter }; } -#if !WINDOWS_UWP - private int? ReadBodyLength(byte initialEncodedByte, CancellationToken cancellationToken) - { - var offset = 0; - var multiplier = 128; - var value = initialEncodedByte & 127; - int encodedByte = initialEncodedByte; - - while ((encodedByte & 128) != 0) - { - offset++; - if (offset > 3) - { - throw new MqttProtocolViolationException("Remaining length is invalid."); - } - - if (cancellationToken.IsCancellationRequested) - { - return null; - } - - var readCount = _channel.ReadAsync(_singleByteBuffer, 0, 1, cancellationToken).GetAwaiter().GetResult(); - - if (cancellationToken.IsCancellationRequested) - { - return null; - } - - if (readCount == 0) - { - return null; - } - - encodedByte = _singleByteBuffer[0]; - - value += (encodedByte & 127) * multiplier; - multiplier *= 128; - } - - return value; - } -#else - private async Task ReadBodyLengthAsync(byte initialEncodedByte, CancellationToken cancellationToken) { var offset = 0; @@ -164,6 +112,5 @@ namespace MQTTnet.Formatter return value; } -#endif } } diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs deleted file mode 100644 index cb0f71c2..00000000 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs +++ /dev/null @@ -1,196 +0,0 @@ -#if WINDOWS_UWP -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; -using System.Threading; -using System.Threading.Tasks; -using Windows.Networking; -using Windows.Networking.Sockets; -using Windows.Security.Cryptography.Certificates; -using MQTTnet.Channel; -using MQTTnet.Client.Options; -using MQTTnet.Server; - -namespace MQTTnet.Implementations -{ - public class MqttTcpChannel : IMqttChannel - { - private readonly MqttClientTcpOptions _options; - private readonly int _bufferSize; - - private StreamSocket _socket; - private Stream _readStream; - private Stream _writeStream; - - public MqttTcpChannel(IMqttClientOptions clientOptions) - { - _options = (MqttClientTcpOptions)clientOptions.ChannelOptions; - _bufferSize = _options.BufferSize; - } - - public MqttTcpChannel(StreamSocket socket, X509Certificate2 clientCertificate, IMqttServerOptions serverOptions) - { - _socket = socket ?? throw new ArgumentNullException(nameof(socket)); - _bufferSize = serverOptions.DefaultEndpointOptions.BufferSize; - - CreateStreams(); - - IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12; - ClientCertificate = clientCertificate; - - Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort; - } - - public static Func> CustomIgnorableServerCertificateErrorsResolver { get; set; } - - public string Endpoint { get; private set; } - - public bool IsSecureConnection { get; } - - public X509Certificate2 ClientCertificate { get; } - - public async Task ConnectAsync(CancellationToken cancellationToken) - { - if (_socket == null) - { - _socket = new StreamSocket(); - _socket.Control.NoDelay = _options.NoDelay; - _socket.Control.KeepAlive = true; - } - - if (_options.TlsOptions?.UseTls != true) - { - await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString()); - } - else - { - _socket.Control.ClientCertificate = LoadCertificate(_options); - - foreach (var ignorableChainValidationResult in ResolveIgnorableServerCertificateErrors()) - { - _socket.Control.IgnorableServerCertificateErrors.Add(ignorableChainValidationResult); - } - - var socketProtectionLevel = SocketProtectionLevel.Tls12; - if (_options.TlsOptions.SslProtocol == SslProtocols.Tls11) - { - socketProtectionLevel = SocketProtectionLevel.Tls11; - } - else if (_options.TlsOptions.SslProtocol == SslProtocols.Tls) - { - socketProtectionLevel = SocketProtectionLevel.Tls10; - } - - await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), socketProtectionLevel); - } - - Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort; - - CreateStreams(); - } - - public Task DisconnectAsync(CancellationToken cancellationToken) - { - Dispose(); - return Task.FromResult(0); - } - - public Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - return _readStream.ReadAsync(buffer, offset, count, cancellationToken); - } - - public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) - { - // In the write method only the internal buffer will be filled. So here is no - // async/await required. The real network transmit is done when calling the - // Flush method. - _writeStream.Write(buffer, offset, count); - return _writeStream.FlushAsync(cancellationToken); - } - - public void Dispose() - { - TryDispose(_readStream, () => _readStream = null); - TryDispose(_writeStream, () => _writeStream = null); - TryDispose(_socket, () => _socket = null); - } - - private static Certificate LoadCertificate(IMqttClientChannelOptions options) - { - if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any()) - { - return null; - } - - if (options.TlsOptions.Certificates.Count > 1) - { - throw new NotSupportedException("Only one client certificate is supported for UWP."); - } - - return new Certificate(options.TlsOptions.Certificates.First().AsBuffer()); - } - - private IEnumerable ResolveIgnorableServerCertificateErrors() - { - if (CustomIgnorableServerCertificateErrorsResolver != null) - { - return CustomIgnorableServerCertificateErrorsResolver(_options); - } - - var result = new List(); - - if (_options.TlsOptions.IgnoreCertificateRevocationErrors) - { - result.Add(ChainValidationResult.RevocationInformationMissing); - //_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked); Not supported. - result.Add(ChainValidationResult.RevocationFailure); - } - - if (_options.TlsOptions.IgnoreCertificateChainErrors) - { - result.Add(ChainValidationResult.IncompleteChain); - } - - if (_options.TlsOptions.AllowUntrustedCertificates) - { - result.Add(ChainValidationResult.Untrusted); - } - - return result; - } - - private void CreateStreams() - { - // Attention! Do not set the buffer for the read method. This will - // limit the internal buffer and the read operation will hang forever - // if more data than the buffer size was received. - _readStream = _socket.InputStream.AsStreamForRead(); - - _writeStream = _socket.OutputStream.AsStreamForWrite(_bufferSize); - } - - private static void TryDispose(IDisposable disposable, Action afterDispose) - { - try - { - disposable?.Dispose(); - } - catch (ObjectDisposedException) - { - } - catch (NullReferenceException) - { - } - finally - { - afterDispose(); - } - } - } -} -#endif \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs index 12fd2bbb..9a68e550 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs @@ -1,4 +1,3 @@ -#if !WINDOWS_UWP using System; using System.Net.Security; using System.Net.Sockets; @@ -72,7 +71,7 @@ namespace MQTTnet.Implementations // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430 using (cancellationToken.Register(() => socket.Dispose())) { -#if NET452 || NET461 +#if NET452 await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, _options.Server, _options.GetPort(), null).ConfigureAwait(false); #else await socket.ConnectAsync(_options.Server, _options.GetPort()).ConfigureAwait(false); @@ -220,5 +219,4 @@ namespace MQTTnet.Implementations return certificates; } } -} -#endif +} \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs deleted file mode 100644 index 3b24bd13..00000000 --- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs +++ /dev/null @@ -1,122 +0,0 @@ -#if WINDOWS_UWP -using Windows.Networking.Sockets; -using MQTTnet.Adapter; -using MQTTnet.Diagnostics; -using MQTTnet.Formatter; -using MQTTnet.Server; -using System; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Security.Cryptography.X509Certificates; -using System.Threading.Tasks; - -namespace MQTTnet.Implementations -{ - public class MqttTcpServerAdapter : IMqttServerAdapter - { - private readonly IMqttNetChildLogger _logger; - - private IMqttServerOptions _options; - private StreamSocketListener _listener; - - public MqttTcpServerAdapter(IMqttNetChildLogger logger) - { - if (logger == null) throw new ArgumentNullException(nameof(logger)); - - _logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter)); - } - - public Func ClientHandler { get; set; } - - public async Task StartAsync(IMqttServerOptions options) - { - _options = options ?? throw new ArgumentNullException(nameof(options)); - - if (_listener != null) throw new InvalidOperationException("Server is already started."); - - if (options.DefaultEndpointOptions.IsEnabled) - { - _listener = new StreamSocketListener(); - - // This also affects the client sockets. - _listener.Control.NoDelay = options.DefaultEndpointOptions.NoDelay; - _listener.Control.KeepAlive = true; - _listener.Control.QualityOfService = SocketQualityOfService.LowLatency; - _listener.ConnectionReceived += OnConnectionReceivedAsync; - - await _listener.BindServiceNameAsync(options.DefaultEndpointOptions.Port.ToString(), SocketProtectionLevel.PlainSocket); - } - - if (options.TlsEndpointOptions.IsEnabled) - { - throw new NotSupportedException("TLS servers are not supported for UWP apps."); - } - } - - public Task StopAsync() - { - if (_listener != null) - { - _listener.ConnectionReceived -= OnConnectionReceivedAsync; - } - - return Task.FromResult(0); - } - - public void Dispose() - { - _listener?.Dispose(); - _listener = null; - } - - private 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."); - } - } - - using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket, clientCertificate, _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"); - } - } - } - } -} -#endif \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs index e3dcab88..b1ec1825 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs @@ -1,5 +1,4 @@ -#if !WINDOWS_UWP -using System; +using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; @@ -128,5 +127,4 @@ namespace MQTTnet.Implementations return clientHandler(channelAdapter); } } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs index d57888eb..93b247f6 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs @@ -1,5 +1,4 @@ -#if !WINDOWS_UWP -using System; +using System; using System.IO; using System.Net; using System.Net.Security; @@ -96,7 +95,7 @@ namespace MQTTnet.Implementations { _socket?.Dispose(); -#if NETSTANDARD1_3 || NETSTANDARD2_0 || NET461 || NET472 +#if NETSTANDARD1_3 || NETSTANDARD2_0 _tlsCertificate?.Dispose(); #endif } @@ -107,7 +106,7 @@ namespace MQTTnet.Implementations { try { -#if NET452 || NET461 +#if NET452 var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null).ConfigureAwait(false); #else var clientSocket = await _socket.AcceptAsync().ConfigureAwait(false); @@ -224,5 +223,4 @@ namespace MQTTnet.Implementations } } } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs index 38e43422..e27cd09f 100644 --- a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs +++ b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs @@ -161,10 +161,8 @@ namespace MQTTnet.Implementations return null; } -#if WINDOWS_UWP - throw new NotSupportedException("Proxies are not supported in UWP."); -#elif NETSTANDARD1_3 - throw new NotSupportedException("Proxies are not supported in netstandard 1.3."); +#if NETSTANDARD1_3 + throw new NotSupportedException("Proxies are not supported in netstandard1.3."); #else var proxyUri = new Uri(_options.ProxyOptions.Address); diff --git a/Source/MQTTnet/MQTTnet.csproj b/Source/MQTTnet/MQTTnet.csproj index 61ca5177..1616d73a 100644 --- a/Source/MQTTnet/MQTTnet.csproj +++ b/Source/MQTTnet/MQTTnet.csproj @@ -2,8 +2,7 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452;net461 - $(TargetFrameworks);uap10.0 + $(TargetFrameworks);net452 MQTTnet MQTTnet False @@ -16,30 +15,13 @@ false - - false - UAP,Version=v10.0 - UAP - 10.0.17134.0 - 10.0.10586.212 - .NETCore - v5.0 - $(DefineConstants);WINDOWS_UWP - en - $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets - - Full - - - - - + @@ -53,14 +35,7 @@ - - - - - - - \ No newline at end of file diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs index c25af84b..0f21728c 100644 --- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs +++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs @@ -95,7 +95,6 @@ namespace MQTTnet.Server return this; } -#if !WINDOWS_UWP public MqttServerOptionsBuilder WithClientCertificate(RemoteCertificateValidationCallback validationCallback = null, bool checkCertificateRevocation = false) { _options.TlsEndpointOptions.ClientCertificateRequired = true; @@ -103,7 +102,6 @@ namespace MQTTnet.Server _options.TlsEndpointOptions.RemoteCertificateValidationCallback = validationCallback; return this; } -#endif public MqttServerOptionsBuilder WithoutEncryptedEndpoint() { @@ -111,14 +109,12 @@ namespace MQTTnet.Server return this; } -#if !WINDOWS_UWP public MqttServerOptionsBuilder WithRemoteCertificateValidationCallback(RemoteCertificateValidationCallback value) { _options.TlsEndpointOptions.RemoteCertificateValidationCallback = value; return this; } -#endif - + public MqttServerOptionsBuilder WithStorage(IMqttServerStorage value) { _options.Storage = value; diff --git a/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs b/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs index 7f305fe8..29776aaf 100644 --- a/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs @@ -12,10 +12,6 @@ namespace MQTTnet.Server public bool NoDelay { get; set; } = true; -#if WINDOWS_UWP - public int BufferSize { get; set; } = 4096; -#endif - public IPAddress BoundInterNetworkAddress { get; set; } = IPAddress.Any; public IPAddress BoundInterNetworkV6Address { get; set; } = IPAddress.IPv6Any; diff --git a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs index 9bf325b1..c9c7791f 100644 --- a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs @@ -17,10 +17,8 @@ namespace MQTTnet.Server public bool ClientCertificateRequired { get; set; } public bool CheckCertificateRevocation { get; set; } - -#if !WINDOWS_UWP public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; } -#endif + public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; } } diff --git a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs index 94abc418..13085b53 100644 --- a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs +++ b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs @@ -653,18 +653,7 @@ namespace MQTTnet.TestApp.UniversalWindows } // ---------------------------------- - - // For UWP apps: - MqttTcpChannel.CustomIgnorableServerCertificateErrorsResolver = o => - { - if (o.Server == "server_with_revoked_cert") - { - return new[] { ChainValidationResult.Revoked }; - } - - return new ChainValidationResult[0]; - }; - + { // Start a MQTT server. var mqttServer = new MqttFactory().CreateMqttServer(); From 6c53677e7d11f7e876ec7fb59fc58a89cbad4647 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 22:10:49 +0200 Subject: [PATCH 16/19] Update nugets. --- Build/MQTTnet.Extensions.ManagedClient.nuspec | 14 ++++---------- Build/MQTTnet.Extensions.Rpc.nuspec | 14 ++++---------- Build/MQTTnet.Extensions.WebSocket4Net.nuspec | 14 ++++---------- Build/MQTTnet.nuspec | 2 ++ 4 files changed, 14 insertions(+), 30 deletions(-) diff --git a/Build/MQTTnet.Extensions.ManagedClient.nuspec b/Build/MQTTnet.Extensions.ManagedClient.nuspec index edec7696..2ba0a5eb 100644 --- a/Build/MQTTnet.Extensions.ManagedClient.nuspec +++ b/Build/MQTTnet.Extensions.ManagedClient.nuspec @@ -19,24 +19,18 @@ + + + + - - - - - - - - - - diff --git a/Build/MQTTnet.Extensions.Rpc.nuspec b/Build/MQTTnet.Extensions.Rpc.nuspec index ce81cb6e..1a1b0877 100644 --- a/Build/MQTTnet.Extensions.Rpc.nuspec +++ b/Build/MQTTnet.Extensions.Rpc.nuspec @@ -19,24 +19,18 @@ + + + + - - - - - - - - - - diff --git a/Build/MQTTnet.Extensions.WebSocket4Net.nuspec b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec index 054933ed..ced0fe11 100644 --- a/Build/MQTTnet.Extensions.WebSocket4Net.nuspec +++ b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec @@ -19,24 +19,18 @@ + + + + - - - - - - - - - - diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index eded1fd9..93b4db5d 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -18,6 +18,8 @@ Copyright Christian Kratky 2016-2019 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 232605304e65f76f042c01ffc8f29842a5097eb3 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 22:10:49 +0200 Subject: [PATCH 17/19] Revert "Update nugets." This reverts commit 6c53677e7d11f7e876ec7fb59fc58a89cbad4647. --- Build/MQTTnet.Extensions.ManagedClient.nuspec | 14 ++++++++++---- Build/MQTTnet.Extensions.Rpc.nuspec | 14 ++++++++++---- Build/MQTTnet.Extensions.WebSocket4Net.nuspec | 14 ++++++++++---- Build/MQTTnet.nuspec | 2 -- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Build/MQTTnet.Extensions.ManagedClient.nuspec b/Build/MQTTnet.Extensions.ManagedClient.nuspec index 2ba0a5eb..edec7696 100644 --- a/Build/MQTTnet.Extensions.ManagedClient.nuspec +++ b/Build/MQTTnet.Extensions.ManagedClient.nuspec @@ -19,18 +19,24 @@ - - - - + + + + + + + + + + diff --git a/Build/MQTTnet.Extensions.Rpc.nuspec b/Build/MQTTnet.Extensions.Rpc.nuspec index 1a1b0877..ce81cb6e 100644 --- a/Build/MQTTnet.Extensions.Rpc.nuspec +++ b/Build/MQTTnet.Extensions.Rpc.nuspec @@ -19,18 +19,24 @@ - - - - + + + + + + + + + + diff --git a/Build/MQTTnet.Extensions.WebSocket4Net.nuspec b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec index ced0fe11..054933ed 100644 --- a/Build/MQTTnet.Extensions.WebSocket4Net.nuspec +++ b/Build/MQTTnet.Extensions.WebSocket4Net.nuspec @@ -19,18 +19,24 @@ - - - - + + + + + + + + + + diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index 93b4db5d..eded1fd9 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -18,8 +18,6 @@ Copyright Christian Kratky 2016-2019 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 9ac726b2712a62b8e646d1a59e78176e558459d0 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 22:07:57 +0200 Subject: [PATCH 18/19] Revert "Remove dedicated UWP builds and code." This reverts commit 6d0e2c20223a3d313276983ab389c7e560e4a7a1. --- Build/MQTTnet.nuspec | 30 +- Build/build.ps1 | 8 + MQTTnet.noUWP.sln | 260 ++++++++++++++++++ .../MQTTnet.Extensions.ManagedClient.csproj | 16 +- .../MQTTnet.Extensions.Rpc.csproj | 16 +- .../MQTTnet.Extensions.WebSocket4Net.csproj | 16 +- .../TargetFrameworkInfoProvider.cs | 6 + Source/MQTTnet/Formatter/MqttPacketReader.cs | 53 ++++ .../Implementations/MqttTcpChannel.Uwp.cs | 196 +++++++++++++ .../MQTTnet/Implementations/MqttTcpChannel.cs | 6 +- .../MqttTcpServerAdapter.Uwp.cs | 122 ++++++++ .../Implementations/MqttTcpServerAdapter.cs | 6 +- .../Implementations/MqttTcpServerListener.cs | 10 +- .../Implementations/MqttWebSocketChannel.cs | 6 +- Source/MQTTnet/MQTTnet.csproj | 31 ++- .../Server/MqttServerOptionsBuilder.cs | 6 +- .../MqttServerTcpEndpointBaseOptions.cs | 4 + .../Server/MqttServerTlsTcpEndpointOptions.cs | 4 +- .../MainPage.xaml.cs | 13 +- 19 files changed, 783 insertions(+), 26 deletions(-) create mode 100644 MQTTnet.noUWP.sln create mode 100644 Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs create mode 100644 Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index eded1fd9..6aafdc68 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -11,9 +11,16 @@ false MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol. -* [Core] Removed dedicated UWP builds. The lib is now supporting net452, netstandard1.3 and netstandard2.0 only (which covers mostly everything currently supported by MS). -* [Server] Refactoring of TLS certificate handling (BREAKING CHANGE!) -* [MQTTnet.Server] Added support for passwords when using TLS certificate (BREAKING CHANGE!) +* [Core] Nuget packages with symbols are now also published to improve debugging. +* [Core] Improve task handling (thanks to @mwinterb) +* [ManagedClient] Fix a race condition in the message storage (thanks to @PaulFake). +* [Server] Added items dictionary to client session in order to share data across interceptors as along as the session exists. +* [Server] Exposed CONNECT packet properties in Application Message and Subscription interceptor. +* [Server] Fixed: Sending Large packets with AspnetCore based connection throws System.ArgumentException. +* [Server] Fixed wrong usage of socket option _NoDelay_. +* [Server] Added remote certificate validation callback (thanks to @rudacs). +* [Server] Add support for certificate passwords (thanks to @cslutgen). +* [MQTTnet.Server] Added REST API for publishing basic messages. Copyright Christian Kratky 2016-2019 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 @@ -30,22 +37,31 @@ + + + - - - - + + + + + + + + + + \ No newline at end of file diff --git a/Build/build.ps1 b/Build/build.ps1 index 08107dc3..33f27677 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -14,26 +14,34 @@ Write-Host # Build the core library &$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the ASP.NET Core 2.0 extension &$msbuild ..\Source\MQTTnet.AspNetCore\MQTTnet.AspNetCore.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the RPC extension &$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the Managed Client extension &$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Build the WebSocket4Net extension &$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net461" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard1.3" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" &$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netstandard2.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" +&$msbuild ..\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx" # Create NuGet packages. diff --git a/MQTTnet.noUWP.sln b/MQTTnet.noUWP.sln new file mode 100644 index 00000000..3d842a5e --- /dev/null +++ b/MQTTnet.noUWP.sln @@ -0,0 +1,260 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2010 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9248C2E1-B9D6-40BF-81EC-86004D7765B4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{32A630A7-2598-41D7-B625-204CD906F5FB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet", "Source\MQTTnet\MQTTnet.csproj", "{3587E506-55A2-4EB3-99C7-DC01E42D25D2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{67C28AC1-BC3A-420A-BE9C-FA2401431CF9}" + ProjectSection(SolutionItems) = preProject + Build\build.ps1 = Build\build.ps1 + Build\MQTTnet.AspNetCore.nuspec = Build\MQTTnet.AspNetCore.nuspec + Build\MQTTnet.Extensions.ManagedClient.nuspec = Build\MQTTnet.Extensions.ManagedClient.nuspec + Build\MQTTnet.Extensions.Rpc.nuspec = Build\MQTTnet.Extensions.Rpc.nuspec + Build\MQTTnet.nuspec = Build\MQTTnet.nuspec + Build\upload.ps1 = Build\upload.ps1 + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}" + ProjectSection(SolutionItems) = preProject + .bettercodehub.yml = .bettercodehub.yml + appveyor.yml = appveyor.yml + LICENSE = LICENSE + README.md = README.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.NetCore", "Tests\MQTTnet.TestApp.NetCore\MQTTnet.TestApp.NetCore.csproj", "{3D283AAD-AAA8-4339-8394-52F80B6304DB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.AspNetCore2", "Tests\MQTTnet.TestApp.AspNetCore2\MQTTnet.TestApp.AspNetCore2.csproj", "{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore", "Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj", "{F10C4060-F7EE-4A83-919F-FF723E72F94A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{12816BCC-AF9E-44A9-9AE5-C246AF2A0587}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.Rpc", "Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj", "{C444E9C8-95FA-430E-9126-274129DE16CD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Benchmarks", "Tests\MQTTnet.Benchmarks\MQTTnet.Benchmarks.csproj", "{998D04DD-7CB0-45F5-A393-E2495C16399E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.ManagedClient", "Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj", "{C400533A-8EBA-4F0B-BF4D-295C3708604B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore.Tests", "Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj", "{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Tests", "Tests\MQTTnet.Core.Tests\MQTTnet.Tests.csproj", "{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Server", "Source\MQTTnet.Server\MQTTnet.Server.csproj", "{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.WebSocket4Net", "Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj", "{9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.ActiveCfg = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.Build.0 = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.ActiveCfg = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.Build.0 = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.ActiveCfg = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.Build.0 = Debug|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.Build.0 = Release|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.ActiveCfg = Release|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.Build.0 = Release|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.ActiveCfg = Release|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.Build.0 = Release|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.ActiveCfg = Release|Any CPU + {3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.Build.0 = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.ActiveCfg = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.Build.0 = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.Build.0 = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.Build.0 = Debug|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.Build.0 = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.ActiveCfg = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.Build.0 = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.ActiveCfg = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.Build.0 = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.ActiveCfg = Release|Any CPU + {3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.Build.0 = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.Build.0 = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.ActiveCfg = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.Build.0 = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.ActiveCfg = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.Build.0 = Debug|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.Build.0 = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.ActiveCfg = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.Build.0 = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.ActiveCfg = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.Build.0 = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.ActiveCfg = Release|Any CPU + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.Build.0 = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.ActiveCfg = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.Build.0 = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.ActiveCfg = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.Build.0 = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.ActiveCfg = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.Build.0 = Debug|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.Build.0 = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.ActiveCfg = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.Build.0 = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.ActiveCfg = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.Build.0 = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.ActiveCfg = Release|Any CPU + {F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.Build.0 = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.Build.0 = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.ActiveCfg = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.Build.0 = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.ActiveCfg = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.Build.0 = Debug|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.Build.0 = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.ActiveCfg = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.Build.0 = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.ActiveCfg = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.Build.0 = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.ActiveCfg = Release|Any CPU + {C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.Build.0 = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.Build.0 = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.ActiveCfg = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.Build.0 = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.ActiveCfg = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.Build.0 = Debug|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.Build.0 = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.ActiveCfg = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.Build.0 = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.ActiveCfg = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.Build.0 = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.ActiveCfg = Release|Any CPU + {998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.Build.0 = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.Build.0 = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.ActiveCfg = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.Build.0 = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.ActiveCfg = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.Build.0 = Debug|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.Build.0 = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.ActiveCfg = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.Build.0 = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.ActiveCfg = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.Build.0 = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.ActiveCfg = Release|Any CPU + {C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.Build.0 = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.Build.0 = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.ActiveCfg = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.Build.0 = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.ActiveCfg = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.Build.0 = Debug|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.Build.0 = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.ActiveCfg = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.Build.0 = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.ActiveCfg = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.Build.0 = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.ActiveCfg = Release|Any CPU + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.Build.0 = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.Build.0 = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.ActiveCfg = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.Build.0 = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.ActiveCfg = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.Build.0 = Debug|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.Build.0 = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.ActiveCfg = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.Build.0 = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.ActiveCfg = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.Build.0 = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.ActiveCfg = Release|Any CPU + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.Build.0 = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.ActiveCfg = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.Build.0 = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.ActiveCfg = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.Build.0 = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.ActiveCfg = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.Build.0 = Debug|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.Build.0 = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.ActiveCfg = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.Build.0 = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.ActiveCfg = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.Build.0 = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.ActiveCfg = Release|Any CPU + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.Build.0 = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|ARM.Build.0 = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x64.ActiveCfg = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x64.Build.0 = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x86.ActiveCfg = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Debug|x86.Build.0 = Debug|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|Any CPU.Build.0 = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|ARM.ActiveCfg = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|ARM.Build.0 = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x64.ActiveCfg = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x64.Build.0 = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x86.ActiveCfg = Release|Any CPU + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {3587E506-55A2-4EB3-99C7-DC01E42D25D2} = {32A630A7-2598-41D7-B625-204CD906F5FB} + {3D283AAD-AAA8-4339-8394-52F80B6304DB} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} + {C6FF8AEA-0855-41EC-A1F3-AC262225BAB9} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} + {F10C4060-F7EE-4A83-919F-FF723E72F94A} = {32A630A7-2598-41D7-B625-204CD906F5FB} + {C444E9C8-95FA-430E-9126-274129DE16CD} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587} + {998D04DD-7CB0-45F5-A393-E2495C16399E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} + {C400533A-8EBA-4F0B-BF4D-295C3708604B} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587} + {61B62223-F5D0-48E4-BBD6-2CBA9353CB5E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} + {9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4} + {DADEA836-5CC3-474C-A2D8-4D0F31118CD7} = {32A630A7-2598-41D7-B625-204CD906F5FB} + {9AE2F8DA-4178-470B-B8C4-88BE1DAE7D5F} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {07536672-5CBC-4BE3-ACE0-708A431A7894} + EndGlobalSection +EndGlobal diff --git a/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj b/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj index 80131c44..b59b7f40 100644 --- a/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj +++ b/Source/MQTTnet.Extensions.ManagedClient/MQTTnet.Extensions.ManagedClient.csproj @@ -2,13 +2,27 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452 + $(TargetFrameworks);net452;net461 + $(TargetFrameworks);uap10.0 + + false + UAP,Version=v10.0 + UAP + 10.0.17134.0 + 10.0.10240.0 + .NETCore + v5.0 + $(DefineConstants);WINDOWS_UWP + en + $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets + + diff --git a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj index 80131c44..b59b7f40 100644 --- a/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj +++ b/Source/MQTTnet.Extensions.Rpc/MQTTnet.Extensions.Rpc.csproj @@ -2,13 +2,27 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452 + $(TargetFrameworks);net452;net461 + $(TargetFrameworks);uap10.0 + + false + UAP,Version=v10.0 + UAP + 10.0.17134.0 + 10.0.10240.0 + .NETCore + v5.0 + $(DefineConstants);WINDOWS_UWP + en + $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets + + diff --git a/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj b/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj index 639e0488..bdf26c6f 100644 --- a/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj +++ b/Source/MQTTnet.Extensions.WebSocket4Net/MQTTnet.Extensions.WebSocket4Net.csproj @@ -2,13 +2,27 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452 + $(TargetFrameworks);net452;net461 + $(TargetFrameworks);uap10.0 + + false + UAP,Version=v10.0 + UAP + 10.0.17134.0 + 10.0.10240.0 + .NETCore + v5.0 + $(DefineConstants);WINDOWS_UWP + en + $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets + + diff --git a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs b/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs index fec08097..efbf08b8 100644 --- a/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs +++ b/Source/MQTTnet/Diagnostics/TargetFrameworkInfoProvider.cs @@ -8,10 +8,16 @@ { #if NET452 return "net452"; +#elif NET461 + return "net461"; +#elif NET472 + return "net472"; #elif NETSTANDARD1_3 return "netstandard1.3"; #elif NETSTANDARD2_0 return "netstandard2.0"; +#elif WINDOWS_UWP + return "uap10.0"; #endif } } diff --git a/Source/MQTTnet/Formatter/MqttPacketReader.cs b/Source/MQTTnet/Formatter/MqttPacketReader.cs index 5cd4dcf4..2589c5b2 100644 --- a/Source/MQTTnet/Formatter/MqttPacketReader.cs +++ b/Source/MQTTnet/Formatter/MqttPacketReader.cs @@ -55,7 +55,16 @@ namespace MQTTnet.Formatter }; } +#if WINDOWS_UWP + // UWP will have a dead lock when calling this not async. var bodyLength = await ReadBodyLengthAsync(buffer[1], cancellationToken).ConfigureAwait(false); +#else + // Here the async/await pattern is not used because the overhead of context switches + // is too big for reading 1 byte in a row. We expect that the remaining data was sent + // directly after the initial bytes. If the client disconnects just in this moment we + // will get an exception anyway. + var bodyLength = ReadBodyLength(buffer[1], cancellationToken); +#endif if (!bodyLength.HasValue) { @@ -72,6 +81,49 @@ namespace MQTTnet.Formatter }; } +#if !WINDOWS_UWP + private int? ReadBodyLength(byte initialEncodedByte, CancellationToken cancellationToken) + { + var offset = 0; + var multiplier = 128; + var value = initialEncodedByte & 127; + int encodedByte = initialEncodedByte; + + while ((encodedByte & 128) != 0) + { + offset++; + if (offset > 3) + { + throw new MqttProtocolViolationException("Remaining length is invalid."); + } + + if (cancellationToken.IsCancellationRequested) + { + return null; + } + + var readCount = _channel.ReadAsync(_singleByteBuffer, 0, 1, cancellationToken).GetAwaiter().GetResult(); + + if (cancellationToken.IsCancellationRequested) + { + return null; + } + + if (readCount == 0) + { + return null; + } + + encodedByte = _singleByteBuffer[0]; + + value += (encodedByte & 127) * multiplier; + multiplier *= 128; + } + + return value; + } +#else + private async Task ReadBodyLengthAsync(byte initialEncodedByte, CancellationToken cancellationToken) { var offset = 0; @@ -112,5 +164,6 @@ namespace MQTTnet.Formatter return value; } +#endif } } diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs new file mode 100644 index 00000000..cb0f71c2 --- /dev/null +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs @@ -0,0 +1,196 @@ +#if WINDOWS_UWP +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using Windows.Networking; +using Windows.Networking.Sockets; +using Windows.Security.Cryptography.Certificates; +using MQTTnet.Channel; +using MQTTnet.Client.Options; +using MQTTnet.Server; + +namespace MQTTnet.Implementations +{ + public class MqttTcpChannel : IMqttChannel + { + private readonly MqttClientTcpOptions _options; + private readonly int _bufferSize; + + private StreamSocket _socket; + private Stream _readStream; + private Stream _writeStream; + + public MqttTcpChannel(IMqttClientOptions clientOptions) + { + _options = (MqttClientTcpOptions)clientOptions.ChannelOptions; + _bufferSize = _options.BufferSize; + } + + public MqttTcpChannel(StreamSocket socket, X509Certificate2 clientCertificate, IMqttServerOptions serverOptions) + { + _socket = socket ?? throw new ArgumentNullException(nameof(socket)); + _bufferSize = serverOptions.DefaultEndpointOptions.BufferSize; + + CreateStreams(); + + IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12; + ClientCertificate = clientCertificate; + + Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort; + } + + public static Func> CustomIgnorableServerCertificateErrorsResolver { get; set; } + + public string Endpoint { get; private set; } + + public bool IsSecureConnection { get; } + + public X509Certificate2 ClientCertificate { get; } + + public async Task ConnectAsync(CancellationToken cancellationToken) + { + if (_socket == null) + { + _socket = new StreamSocket(); + _socket.Control.NoDelay = _options.NoDelay; + _socket.Control.KeepAlive = true; + } + + if (_options.TlsOptions?.UseTls != true) + { + await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString()); + } + else + { + _socket.Control.ClientCertificate = LoadCertificate(_options); + + foreach (var ignorableChainValidationResult in ResolveIgnorableServerCertificateErrors()) + { + _socket.Control.IgnorableServerCertificateErrors.Add(ignorableChainValidationResult); + } + + var socketProtectionLevel = SocketProtectionLevel.Tls12; + if (_options.TlsOptions.SslProtocol == SslProtocols.Tls11) + { + socketProtectionLevel = SocketProtectionLevel.Tls11; + } + else if (_options.TlsOptions.SslProtocol == SslProtocols.Tls) + { + socketProtectionLevel = SocketProtectionLevel.Tls10; + } + + await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), socketProtectionLevel); + } + + Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort; + + CreateStreams(); + } + + public Task DisconnectAsync(CancellationToken cancellationToken) + { + Dispose(); + return Task.FromResult(0); + } + + public Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + return _readStream.ReadAsync(buffer, offset, count, cancellationToken); + } + + public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + // In the write method only the internal buffer will be filled. So here is no + // async/await required. The real network transmit is done when calling the + // Flush method. + _writeStream.Write(buffer, offset, count); + return _writeStream.FlushAsync(cancellationToken); + } + + public void Dispose() + { + TryDispose(_readStream, () => _readStream = null); + TryDispose(_writeStream, () => _writeStream = null); + TryDispose(_socket, () => _socket = null); + } + + private static Certificate LoadCertificate(IMqttClientChannelOptions options) + { + if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any()) + { + return null; + } + + if (options.TlsOptions.Certificates.Count > 1) + { + throw new NotSupportedException("Only one client certificate is supported for UWP."); + } + + return new Certificate(options.TlsOptions.Certificates.First().AsBuffer()); + } + + private IEnumerable ResolveIgnorableServerCertificateErrors() + { + if (CustomIgnorableServerCertificateErrorsResolver != null) + { + return CustomIgnorableServerCertificateErrorsResolver(_options); + } + + var result = new List(); + + if (_options.TlsOptions.IgnoreCertificateRevocationErrors) + { + result.Add(ChainValidationResult.RevocationInformationMissing); + //_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked); Not supported. + result.Add(ChainValidationResult.RevocationFailure); + } + + if (_options.TlsOptions.IgnoreCertificateChainErrors) + { + result.Add(ChainValidationResult.IncompleteChain); + } + + if (_options.TlsOptions.AllowUntrustedCertificates) + { + result.Add(ChainValidationResult.Untrusted); + } + + return result; + } + + private void CreateStreams() + { + // Attention! Do not set the buffer for the read method. This will + // limit the internal buffer and the read operation will hang forever + // if more data than the buffer size was received. + _readStream = _socket.InputStream.AsStreamForRead(); + + _writeStream = _socket.OutputStream.AsStreamForWrite(_bufferSize); + } + + private static void TryDispose(IDisposable disposable, Action afterDispose) + { + try + { + disposable?.Dispose(); + } + catch (ObjectDisposedException) + { + } + catch (NullReferenceException) + { + } + finally + { + afterDispose(); + } + } + } +} +#endif \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttTcpChannel.cs b/Source/MQTTnet/Implementations/MqttTcpChannel.cs index 9a68e550..12fd2bbb 100644 --- a/Source/MQTTnet/Implementations/MqttTcpChannel.cs +++ b/Source/MQTTnet/Implementations/MqttTcpChannel.cs @@ -1,3 +1,4 @@ +#if !WINDOWS_UWP using System; using System.Net.Security; using System.Net.Sockets; @@ -71,7 +72,7 @@ namespace MQTTnet.Implementations // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430 using (cancellationToken.Register(() => socket.Dispose())) { -#if NET452 +#if NET452 || NET461 await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, _options.Server, _options.GetPort(), null).ConfigureAwait(false); #else await socket.ConnectAsync(_options.Server, _options.GetPort()).ConfigureAwait(false); @@ -219,4 +220,5 @@ namespace MQTTnet.Implementations return certificates; } } -} \ No newline at end of file +} +#endif diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs new file mode 100644 index 00000000..3b24bd13 --- /dev/null +++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs @@ -0,0 +1,122 @@ +#if WINDOWS_UWP +using Windows.Networking.Sockets; +using MQTTnet.Adapter; +using MQTTnet.Diagnostics; +using MQTTnet.Formatter; +using MQTTnet.Server; +using System; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; + +namespace MQTTnet.Implementations +{ + public class MqttTcpServerAdapter : IMqttServerAdapter + { + private readonly IMqttNetChildLogger _logger; + + private IMqttServerOptions _options; + private StreamSocketListener _listener; + + public MqttTcpServerAdapter(IMqttNetChildLogger logger) + { + if (logger == null) throw new ArgumentNullException(nameof(logger)); + + _logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter)); + } + + public Func ClientHandler { get; set; } + + public async Task StartAsync(IMqttServerOptions options) + { + _options = options ?? throw new ArgumentNullException(nameof(options)); + + if (_listener != null) throw new InvalidOperationException("Server is already started."); + + if (options.DefaultEndpointOptions.IsEnabled) + { + _listener = new StreamSocketListener(); + + // This also affects the client sockets. + _listener.Control.NoDelay = options.DefaultEndpointOptions.NoDelay; + _listener.Control.KeepAlive = true; + _listener.Control.QualityOfService = SocketQualityOfService.LowLatency; + _listener.ConnectionReceived += OnConnectionReceivedAsync; + + await _listener.BindServiceNameAsync(options.DefaultEndpointOptions.Port.ToString(), SocketProtectionLevel.PlainSocket); + } + + if (options.TlsEndpointOptions.IsEnabled) + { + throw new NotSupportedException("TLS servers are not supported for UWP apps."); + } + } + + public Task StopAsync() + { + if (_listener != null) + { + _listener.ConnectionReceived -= OnConnectionReceivedAsync; + } + + return Task.FromResult(0); + } + + public void Dispose() + { + _listener?.Dispose(); + _listener = null; + } + + private 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."); + } + } + + using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket, clientCertificate, _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"); + } + } + } + } +} +#endif \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs index b1ec1825..e3dcab88 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerAdapter.cs @@ -1,4 +1,5 @@ -using System; +#if !WINDOWS_UWP +using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; @@ -127,4 +128,5 @@ namespace MQTTnet.Implementations return clientHandler(channelAdapter); } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs index 93b247f6..d57888eb 100644 --- a/Source/MQTTnet/Implementations/MqttTcpServerListener.cs +++ b/Source/MQTTnet/Implementations/MqttTcpServerListener.cs @@ -1,4 +1,5 @@ -using System; +#if !WINDOWS_UWP +using System; using System.IO; using System.Net; using System.Net.Security; @@ -95,7 +96,7 @@ namespace MQTTnet.Implementations { _socket?.Dispose(); -#if NETSTANDARD1_3 || NETSTANDARD2_0 +#if NETSTANDARD1_3 || NETSTANDARD2_0 || NET461 || NET472 _tlsCertificate?.Dispose(); #endif } @@ -106,7 +107,7 @@ namespace MQTTnet.Implementations { try { -#if NET452 +#if NET452 || NET461 var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null).ConfigureAwait(false); #else var clientSocket = await _socket.AcceptAsync().ConfigureAwait(false); @@ -223,4 +224,5 @@ namespace MQTTnet.Implementations } } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs index e27cd09f..38e43422 100644 --- a/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs +++ b/Source/MQTTnet/Implementations/MqttWebSocketChannel.cs @@ -161,8 +161,10 @@ namespace MQTTnet.Implementations return null; } -#if NETSTANDARD1_3 - throw new NotSupportedException("Proxies are not supported in netstandard1.3."); +#if WINDOWS_UWP + throw new NotSupportedException("Proxies are not supported in UWP."); +#elif NETSTANDARD1_3 + throw new NotSupportedException("Proxies are not supported in netstandard 1.3."); #else var proxyUri = new Uri(_options.ProxyOptions.Address); diff --git a/Source/MQTTnet/MQTTnet.csproj b/Source/MQTTnet/MQTTnet.csproj index 1616d73a..61ca5177 100644 --- a/Source/MQTTnet/MQTTnet.csproj +++ b/Source/MQTTnet/MQTTnet.csproj @@ -2,7 +2,8 @@ netstandard1.3;netstandard2.0 - $(TargetFrameworks);net452 + $(TargetFrameworks);net452;net461 + $(TargetFrameworks);uap10.0 MQTTnet MQTTnet False @@ -15,13 +16,30 @@ false + + false + UAP,Version=v10.0 + UAP + 10.0.17134.0 + 10.0.10586.212 + .NETCore + v5.0 + $(DefineConstants);WINDOWS_UWP + en + $(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets + + Full + + - + @@ -35,7 +53,14 @@ + + + + + + + \ No newline at end of file diff --git a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs index 0f21728c..c25af84b 100644 --- a/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs +++ b/Source/MQTTnet/Server/MqttServerOptionsBuilder.cs @@ -95,6 +95,7 @@ namespace MQTTnet.Server return this; } +#if !WINDOWS_UWP public MqttServerOptionsBuilder WithClientCertificate(RemoteCertificateValidationCallback validationCallback = null, bool checkCertificateRevocation = false) { _options.TlsEndpointOptions.ClientCertificateRequired = true; @@ -102,6 +103,7 @@ namespace MQTTnet.Server _options.TlsEndpointOptions.RemoteCertificateValidationCallback = validationCallback; return this; } +#endif public MqttServerOptionsBuilder WithoutEncryptedEndpoint() { @@ -109,12 +111,14 @@ namespace MQTTnet.Server return this; } +#if !WINDOWS_UWP public MqttServerOptionsBuilder WithRemoteCertificateValidationCallback(RemoteCertificateValidationCallback value) { _options.TlsEndpointOptions.RemoteCertificateValidationCallback = value; return this; } - +#endif + public MqttServerOptionsBuilder WithStorage(IMqttServerStorage value) { _options.Storage = value; diff --git a/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs b/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs index 29776aaf..7f305fe8 100644 --- a/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTcpEndpointBaseOptions.cs @@ -12,6 +12,10 @@ namespace MQTTnet.Server public bool NoDelay { get; set; } = true; +#if WINDOWS_UWP + public int BufferSize { get; set; } = 4096; +#endif + public IPAddress BoundInterNetworkAddress { get; set; } = IPAddress.Any; public IPAddress BoundInterNetworkV6Address { get; set; } = IPAddress.IPv6Any; diff --git a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs index c9c7791f..9bf325b1 100644 --- a/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs +++ b/Source/MQTTnet/Server/MqttServerTlsTcpEndpointOptions.cs @@ -17,8 +17,10 @@ namespace MQTTnet.Server public bool ClientCertificateRequired { get; set; } public bool CheckCertificateRevocation { get; set; } - public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; } +#if !WINDOWS_UWP + public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; } +#endif public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; } } diff --git a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs index 13085b53..94abc418 100644 --- a/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs +++ b/Tests/MQTTnet.TestApp.UniversalWindows/MainPage.xaml.cs @@ -653,7 +653,18 @@ namespace MQTTnet.TestApp.UniversalWindows } // ---------------------------------- - + + // For UWP apps: + MqttTcpChannel.CustomIgnorableServerCertificateErrorsResolver = o => + { + if (o.Server == "server_with_revoked_cert") + { + return new[] { ChainValidationResult.Revoked }; + } + + return new ChainValidationResult[0]; + }; + { // Start a MQTT server. var mqttServer = new MqttFactory().CreateMqttServer(); From 0cfb8b402076c9dbd5c511757fdb47adb3431b59 Mon Sep 17 00:00:00 2001 From: Christian Kratky Date: Sun, 11 Aug 2019 22:25:05 +0200 Subject: [PATCH 19/19] Remove not async task handling. --- Source/MQTTnet/Formatter/MqttPacketReader.cs | 55 -------------------- 1 file changed, 55 deletions(-) diff --git a/Source/MQTTnet/Formatter/MqttPacketReader.cs b/Source/MQTTnet/Formatter/MqttPacketReader.cs index 2589c5b2..61698a1a 100644 --- a/Source/MQTTnet/Formatter/MqttPacketReader.cs +++ b/Source/MQTTnet/Formatter/MqttPacketReader.cs @@ -21,8 +21,6 @@ namespace MQTTnet.Formatter { // The MQTT fixed header contains 1 byte of flags and at least 1 byte for the remaining data length. // So in all cases at least 2 bytes must be read for a complete MQTT packet. - // async/await is used here because the next packet is received in a couple of minutes so the performance - // impact is acceptable according to a useless waiting thread. var buffer = fixedHeaderBuffer; var totalBytesRead = 0; @@ -55,16 +53,7 @@ namespace MQTTnet.Formatter }; } -#if WINDOWS_UWP - // UWP will have a dead lock when calling this not async. var bodyLength = await ReadBodyLengthAsync(buffer[1], cancellationToken).ConfigureAwait(false); -#else - // Here the async/await pattern is not used because the overhead of context switches - // is too big for reading 1 byte in a row. We expect that the remaining data was sent - // directly after the initial bytes. If the client disconnects just in this moment we - // will get an exception anyway. - var bodyLength = ReadBodyLength(buffer[1], cancellationToken); -#endif if (!bodyLength.HasValue) { @@ -81,49 +70,6 @@ namespace MQTTnet.Formatter }; } -#if !WINDOWS_UWP - private int? ReadBodyLength(byte initialEncodedByte, CancellationToken cancellationToken) - { - var offset = 0; - var multiplier = 128; - var value = initialEncodedByte & 127; - int encodedByte = initialEncodedByte; - - while ((encodedByte & 128) != 0) - { - offset++; - if (offset > 3) - { - throw new MqttProtocolViolationException("Remaining length is invalid."); - } - - if (cancellationToken.IsCancellationRequested) - { - return null; - } - - var readCount = _channel.ReadAsync(_singleByteBuffer, 0, 1, cancellationToken).GetAwaiter().GetResult(); - - if (cancellationToken.IsCancellationRequested) - { - return null; - } - - if (readCount == 0) - { - return null; - } - - encodedByte = _singleByteBuffer[0]; - - value += (encodedByte & 127) * multiplier; - multiplier *= 128; - } - - return value; - } -#else - private async Task ReadBodyLengthAsync(byte initialEncodedByte, CancellationToken cancellationToken) { var offset = 0; @@ -164,6 +110,5 @@ namespace MQTTnet.Formatter return value; } -#endif } }