diff --git a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs index 9726fe0d..27ad4352 100644 --- a/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs +++ b/Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs @@ -19,11 +19,7 @@ namespace MQTTnet.Client.Options public Func CertificateValidationHandler { get; set; } -#if NETCOREAPP3_1 || NET5_0 - public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls13; -#else - public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; -#endif + public SslProtocols SslProtocol { get; set; } = SslProtocols.None; #if WINDOWS_UWP public IEnumerable> Certificates { get; set; } diff --git a/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs b/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs index 138fabc3..e2d57eed 100644 --- a/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs +++ b/Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net.Security; using System.Security.Authentication; @@ -26,11 +26,7 @@ namespace MQTTnet.Client.Options public List ApplicationProtocols { get; set; } #endif -#if NETCOREAPP3_1 || NET5_0 - public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls13; -#else - public SslProtocols SslProtocol { get; set; } = SslProtocols.Tls12; -#endif + public SslProtocols SslProtocol { get; set; } = SslProtocols.None; [Obsolete("This property will be removed soon. Use CertificateValidationHandler instead.")] public Func CertificateValidationCallback { get; set; } diff --git a/Source/MQTTnet/Server/Internal/MqttClientSessionsManager.cs b/Source/MQTTnet/Server/Internal/MqttClientSessionsManager.cs index f914904c..a18e3df6 100644 --- a/Source/MQTTnet/Server/Internal/MqttClientSessionsManager.cs +++ b/Source/MQTTnet/Server/Internal/MqttClientSessionsManager.cs @@ -107,9 +107,11 @@ namespace MQTTnet.Server.Internal return; } - clientConnection = await CreateClientConnection(connectPacket, channelAdapter, connectionValidatorContext.SessionItems).ConfigureAwait(false); - connAckPacket = _connAckPacketFactory.Create(connectionValidatorContext); + + // Pass connAckPacket so that IsSessionPresent flag can be set if the client session already exists + clientConnection = await CreateClientConnection(connectPacket, connAckPacket, channelAdapter, connectionValidatorContext.SessionItems).ConfigureAwait(false); + await channelAdapter.SendPacketAsync(connAckPacket, cancellationToken).ConfigureAwait(false); await _eventDispatcher.SafeNotifyClientConnectedAsync(connectPacket, channelAdapter).ConfigureAwait(false); @@ -517,7 +519,8 @@ namespace MQTTnet.Server.Internal } async Task CreateClientConnection( - MqttConnectPacket connectPacket, + MqttConnectPacket connectPacket, + MqttConnAckPacket connAckPacket, IMqttChannelAdapter channelAdapter, IDictionary sessionItems) { @@ -543,6 +546,7 @@ namespace MQTTnet.Server.Internal else { _logger.Verbose("Reusing existing session of client '{0}'.", connectPacket.ClientId); + connAckPacket.IsSessionPresent = true; } } diff --git a/Tests/MQTTnet.Core.Tests/MQTTv5/Server_Tests.cs b/Tests/MQTTnet.Core.Tests/MQTTv5/Server_Tests.cs index be589d5e..18fde518 100644 --- a/Tests/MQTTnet.Core.Tests/MQTTv5/Server_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/MQTTv5/Server_Tests.cs @@ -1,4 +1,4 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; using MQTTnet.Client; using MQTTnet.Client.Options; using MQTTnet.Formatter; @@ -38,5 +38,57 @@ namespace MQTTnet.Tests.MQTTv5 Assert.AreEqual(1, receivedMessagesCount); } } + + [TestMethod] + public async Task Validate_IsSessionPresent() + { + using (var testEnvironment = new TestEnvironment(TestContext)) + { + // Create server with persistent sessions enabled + + await testEnvironment.StartServer(o => o.WithPersistentSessions()); + + const string ClientId = "Client1"; + + // Create client without clean session and long session expiry interval + + var client1 = await testEnvironment.ConnectClient(o => o + .WithProtocolVersion(MqttProtocolVersion.V500) + .WithTcpServer("127.0.0.1", testEnvironment.ServerPort) + .WithSessionExpiryInterval(9999) + .WithCleanSession(false) + .WithClientId(ClientId) + .Build() + ); + + // Disconnect; empty session should remain on server + + await client1.DisconnectAsync(); + + // Simulate some time delay between connections + + await Task.Delay(1000); + + // Reconnect the same client ID to existing session + + var client2 = testEnvironment.CreateClient(); + var options = testEnvironment.Factory.CreateClientOptionsBuilder() + .WithProtocolVersion(MqttProtocolVersion.V500) + .WithTcpServer("127.0.0.1", testEnvironment.ServerPort) + .WithSessionExpiryInterval(9999) + .WithCleanSession(false) + .WithClientId(ClientId) + .Build(); + + + var result = await client2.ConnectAsync(options).ConfigureAwait(false); + + await client2.DisconnectAsync(); + + // Session should be present + + Assert.IsTrue(result.IsSessionPresent, "Session not present"); + } + } } }