This commit is contained in:
Christian
2022-02-20 21:10:46 +01:00
committed by GitHub
parent 47e674e4d3
commit 2ce9b94ec9
608 changed files with 22364 additions and 19420 deletions
@@ -1,3 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.Net;
@@ -43,10 +47,16 @@ namespace MQTTnet.Implementations
// We cannot use the _NoDelay_ property from the socket because there is an issue in .NET 4.5.2, 4.6.
// The decompiled code is: this.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, value ? 1 : 0);
// Which is wrong because the "NoDelay" should be set and not "Debug".
get => (int)_socket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) > 0;
get => (int)_socket.GetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay) != 0;
set => _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, value ? 1 : 0);
}
public LingerOption LingerState
{
get => _socket.LingerState;
set => _socket.LingerState = value;
}
public bool DualMode
{
get => _socket.DualMode;
@@ -58,7 +68,7 @@ namespace MQTTnet.Implementations
get => _socket.ReceiveBufferSize;
set => _socket.ReceiveBufferSize = value;
}
public int SendBufferSize
{
get => _socket.SendBufferSize;
@@ -79,6 +89,8 @@ namespace MQTTnet.Implementations
set => _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, value ? 1 : 0);
}
public bool IsConnected => _socket.Connected;
public async Task<CrossPlatformSocket> AcceptAsync()
{
try
@@ -97,9 +109,14 @@ namespace MQTTnet.Implementations
}
}
public EndPoint LocalEndPoint => _socket.LocalEndPoint;
public void Bind(EndPoint localEndPoint)
{
if (localEndPoint is null) throw new ArgumentNullException(nameof(localEndPoint));
if (localEndPoint is null)
{
throw new ArgumentNullException(nameof(localEndPoint));
}
_socket.Bind(localEndPoint);
}
@@ -111,24 +128,31 @@ namespace MQTTnet.Implementations
public async Task ConnectAsync(string host, int port, CancellationToken cancellationToken)
{
if (host is null) throw new ArgumentNullException(nameof(host));
if (host is null)
{
throw new ArgumentNullException(nameof(host));
}
cancellationToken.ThrowIfCancellationRequested();
try
{
_networkStream?.Dispose();
#if NET5_0_OR_GREATER
await _socket.ConnectAsync(host, port, cancellationToken).ConfigureAwait(false);
#else
// Workaround for: https://github.com/dotnet/corefx/issues/24430
using (cancellationToken.Register(_socketDisposeAction))
{
cancellationToken.ThrowIfCancellationRequested();
#if NET452 || NET461
await Task.Factory.FromAsync(_socket.BeginConnect, _socket.EndConnect, host, port, null).ConfigureAwait(false);
#else
await _socket.ConnectAsync(host, port).ConfigureAwait(false);
#endif
_networkStream = new NetworkStream(_socket, true);
}
#endif
_networkStream = new NetworkStream(_socket, true);
}
catch (SocketException socketException)
{
@@ -137,6 +161,11 @@ namespace MQTTnet.Implementations
throw new OperationCanceledException();
}
if (socketException.SocketErrorCode == SocketError.TimedOut)
{
throw new MqttCommunicationTimedOutException();
}
throw new MqttCommunicationException($"Error while connecting with host '{host}:{port}'.", socketException);
}
catch (ObjectDisposedException)
@@ -197,7 +226,7 @@ namespace MQTTnet.Implementations
}
#if NET452 || NET461
class SocketWrapper
sealed class SocketWrapper
{
readonly Socket _socket;
readonly ArraySegment<byte> _buffer;
@@ -224,4 +253,4 @@ namespace MQTTnet.Implementations
}
#endif
}
}
}
@@ -1,23 +1,19 @@
using MQTTnet.Adapter;
using MQTTnet.Client.Options;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
using System;
using MQTTnet.Channel;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Client;
namespace MQTTnet.Implementations
{
public class MqttClientAdapterFactory : IMqttClientAdapterFactory
public sealed class MqttClientAdapterFactory : IMqttClientAdapterFactory
{
readonly IMqttNetLogger _logger;
public MqttClientAdapterFactory(IMqttNetLogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options)
public IMqttChannelAdapter CreateClientAdapter(MqttClientOptions options, MqttPacketInspector packetInspector, IMqttNetLogger logger)
{
if (options == null) throw new ArgumentNullException(nameof(options));
@@ -42,8 +38,9 @@ namespace MQTTnet.Implementations
}
}
var packetFormatterAdapter = new MqttPacketFormatterAdapter(options.ProtocolVersion, new MqttPacketWriter());
return new MqttChannelAdapter(channel, packetFormatterAdapter, options.PacketInspector, _logger);
var bufferWriter = new MqttBufferWriter(options.WriterBufferSize, options.WriterBufferSizeMax);
var packetFormatterAdapter = new MqttPacketFormatterAdapter(options.ProtocolVersion, bufferWriter);
return new MqttChannelAdapter(channel, packetFormatterAdapter, packetInspector, logger);
}
}
}
@@ -1,3 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if WINDOWS_UWP
using System;
using System.Collections.Generic;
@@ -12,7 +16,7 @@ using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Security.Cryptography.Certificates;
using MQTTnet.Channel;
using MQTTnet.Client.Options;
using MQTTnet.Client;
using MQTTnet.Server;
namespace MQTTnet.Implementations
@@ -26,13 +30,13 @@ namespace MQTTnet.Implementations
Stream _readStream;
Stream _writeStream;
public MqttTcpChannel(IMqttClientOptions clientOptions)
public MqttTcpChannel(MqttClientOptions clientOptions)
{
_options = (MqttClientTcpOptions)clientOptions.ChannelOptions;
_bufferSize = _options.BufferSize;
}
public MqttTcpChannel(StreamSocket socket, X509Certificate2 clientCertificate, IMqttServerOptions serverOptions)
public MqttTcpChannel(StreamSocket socket, X509Certificate2 clientCertificate, MqttServerOptions serverOptions)
{
_socket = socket ?? throw new ArgumentNullException(nameof(socket));
_bufferSize = serverOptions.DefaultEndpointOptions.BufferSize;
@@ -1,24 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if !WINDOWS_UWP
using MQTTnet.Channel;
using MQTTnet.Client.Options;
using System;
using System.IO;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Runtime.ExceptionServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Channel;
using MQTTnet.Client;
using MQTTnet.Exceptions;
namespace MQTTnet.Implementations
{
public sealed class MqttTcpChannel : IMqttChannel
{
readonly IMqttClientOptions _clientOptions;
readonly MqttClientTcpOptions _tcpOptions;
readonly MqttClientOptions _clientOptions;
readonly Action _disposeAction;
readonly MqttClientTcpOptions _tcpOptions;
Stream _stream;
@@ -27,7 +30,7 @@ namespace MQTTnet.Implementations
_disposeAction = Dispose;
}
public MqttTcpChannel(IMqttClientOptions clientOptions) : this()
public MqttTcpChannel(MqttClientOptions clientOptions) : this()
{
_clientOptions = clientOptions ?? throw new ArgumentNullException(nameof(clientOptions));
_tcpOptions = (MqttClientTcpOptions)clientOptions.ChannelOptions;
@@ -45,12 +48,12 @@ namespace MQTTnet.Implementations
ClientCertificate = clientCertificate;
}
public X509Certificate2 ClientCertificate { get; }
public string Endpoint { get; private set; }
public bool IsSecureConnection { get; }
public X509Certificate2 ClientCertificate { get; }
public async Task ConnectAsync(CancellationToken cancellationToken)
{
CrossPlatformSocket socket = null;
@@ -67,9 +70,14 @@ namespace MQTTnet.Implementations
socket.ReceiveBufferSize = _tcpOptions.BufferSize;
socket.SendBufferSize = _tcpOptions.BufferSize;
socket.SendTimeout = (int)_clientOptions.CommunicationTimeout.TotalMilliseconds;
socket.SendTimeout = (int)_clientOptions.Timeout.TotalMilliseconds;
socket.NoDelay = _tcpOptions.NoDelay;
if (socket.LingerState != null)
{
socket.LingerState = _tcpOptions.LingerState;
}
if (_tcpOptions.DualMode.HasValue)
{
// It is important to avoid setting the flag if no specific value is set by the user
@@ -89,7 +97,7 @@ namespace MQTTnet.Implementations
var sslStream = new SslStream(networkStream, false, InternalUserCertificateValidationCallback);
try
{
#if NETCOREAPP3_1 || NET5_0
#if NETCOREAPP3_1 || NET5_0_OR_GREATER
var sslOptions = new SslClientAuthenticationOptions
{
ApplicationProtocols = _tcpOptions.TlsOptions.ApplicationProtocols,
@@ -101,12 +109,13 @@ namespace MQTTnet.Implementations
await sslStream.AuthenticateAsClientAsync(sslOptions, cancellationToken).ConfigureAwait(false);
#else
await sslStream.AuthenticateAsClientAsync(_tcpOptions.Server, LoadCertificates(), _tcpOptions.TlsOptions.SslProtocol, !_tcpOptions.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false);
await sslStream.AuthenticateAsClientAsync(_tcpOptions.Server, LoadCertificates(), _tcpOptions.TlsOptions.SslProtocol,
!_tcpOptions.TlsOptions.IgnoreCertificateRevocationErrors).ConfigureAwait(false);
#endif
}
catch
{
#if NETSTANDARD2_1 || NETCOREAPP3_1 || NET5_0
#if NETSTANDARD2_1 || NETCOREAPP3_1 || NET5_0_OR_GREATER
await sslStream.DisposeAsync().ConfigureAwait(false);
#else
sslStream.Dispose();
@@ -137,6 +146,30 @@ namespace MQTTnet.Implementations
return Task.FromResult(0);
}
public void Dispose()
{
// When the stream is disposed it will also close the socket and this will also dispose it.
// So there is no need to dispose the socket again.
// https://stackoverflow.com/questions/3601521/should-i-manually-dispose-the-socket-after-closing-it
try
{
#if !NETSTANDARD1_3
_stream?.Close();
#endif
_stream?.Dispose();
}
catch (ObjectDisposedException)
{
}
catch (NullReferenceException)
{
}
finally
{
_stream = null;
}
}
public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -219,42 +252,12 @@ namespace MQTTnet.Implementations
}
}
public void Dispose()
{
// When the stream is disposed it will also close the socket and this will also dispose it.
// So there is no need to dispose the socket again.
// https://stackoverflow.com/questions/3601521/should-i-manually-dispose-the-socket-after-closing-it
try
{
_stream?.Dispose();
}
catch (ObjectDisposedException)
{
}
catch (NullReferenceException)
{
}
_stream = null;
}
bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
#region OBSOLETE
#pragma warning disable CS0618 // Type or member is obsolete
var certificateValidationCallback = _tcpOptions?.TlsOptions?.CertificateValidationCallback;
#pragma warning restore CS0618 // Type or member is obsolete
if (certificateValidationCallback != null)
{
return certificateValidationCallback(x509Certificate, chain, sslPolicyErrors, _clientOptions);
}
#endregion
var certificateValidationHandler = _tcpOptions?.TlsOptions?.CertificateValidationHandler;
if (certificateValidationHandler != null)
{
var context = new MqttClientCertificateValidationCallbackContext
var eventArgs = new MqttClientCertificateValidationEventArgs
{
Certificate = x509Certificate,
Chain = chain,
@@ -262,31 +265,10 @@ namespace MQTTnet.Implementations
ClientOptions = _tcpOptions
};
return certificateValidationHandler(context);
return certificateValidationHandler(eventArgs);
}
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.RevocationStatusUnknown || c.Status == X509ChainStatusFlags.Revoked || c.Status == X509ChainStatusFlags.OfflineRevocation))
{
if (_tcpOptions?.TlsOptions?.IgnoreCertificateRevocationErrors != true)
{
return false;
}
}
if (chain.ChainStatus.Any(c => c.Status == X509ChainStatusFlags.PartialChain))
{
if (_tcpOptions?.TlsOptions?.IgnoreCertificateChainErrors != true)
{
return false;
}
}
return _tcpOptions?.TlsOptions?.AllowUntrustedCertificates == true;
return sslPolicyErrors == SslPolicyErrors.None;
}
X509CertificateCollection LoadCertificates()
@@ -306,4 +288,4 @@ namespace MQTTnet.Implementations
}
}
}
#endif
#endif
@@ -1,38 +1,40 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if WINDOWS_UWP
using Windows.Networking.Sockets;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Formatter;
using MQTTnet.Server;
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using MQTTnet.Server;
using MQTTnet.Diagnostics;
namespace MQTTnet.Implementations
{
public sealed class MqttTcpServerAdapter : IMqttServerAdapter
{
readonly MqttNetSourceLogger _logger;
readonly IMqttNetLogger _rootLogger;
IMqttServerOptions _options;
IMqttNetLogger _rootLogger;
MqttNetSourceLogger _logger;
MqttServerOptions _options;
StreamSocketListener _listener;
public MqttTcpServerAdapter(IMqttNetLogger logger)
{
_rootLogger = logger ?? throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttTcpServerAdapter));
}
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
public async Task StartAsync(IMqttServerOptions options)
public async Task StartAsync(MqttServerOptions options, IMqttNetLogger logger)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
if (_listener != null) throw new InvalidOperationException("Server is already started.");
if (logger is null) throw new ArgumentNullException(nameof(logger));
_rootLogger = logger;
_logger = logger.WithSource(nameof(MqttTcpServerAdapter));
_options = options ?? throw new ArgumentNullException(nameof(options));
if (options.DefaultEndpointOptions.IsEnabled)
{
_listener = new StreamSocketListener();
@@ -42,7 +44,7 @@ namespace MQTTnet.Implementations
_listener.Control.KeepAlive = true;
_listener.Control.QualityOfService = SocketQualityOfService.LowLatency;
_listener.ConnectionReceived += OnConnectionReceivedAsync;
await _listener.BindServiceNameAsync(options.DefaultEndpointOptions.Port.ToString(), SocketProtectionLevel.PlainSocket);
}
@@ -88,8 +90,12 @@ namespace MQTTnet.Implementations
_logger.Warning(exception, "Unable to convert UWP certificate to X509Certificate2.");
}
}
using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket, clientCertificate, _options), new MqttPacketFormatterAdapter(new MqttPacketWriter()), null, _rootLogger))
var bufferWriter = new MqttBufferWriter(4096, 65535);
var packetFormatterAdapter = new MqttPacketFormatterAdapter(bufferWriter);
var tcpChannel = new MqttTcpChannel(args.Socket, clientCertificate, _options);
using (var clientAdapter = new MqttChannelAdapter(tcpChannel, packetFormatterAdapter, null, _rootLogger))
{
await clientHandler(clientAdapter).ConfigureAwait(false);
}
@@ -112,7 +118,7 @@ namespace MQTTnet.Implementations
args.Socket.Dispose();
}
catch (Exception exception)
{
{
_logger.Error(exception, "Error while cleaning up client connection.");
}
}
@@ -1,4 +1,8 @@
#if !WINDOWS_UWP
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if !WINDOWS_UWP
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Server;
@@ -9,37 +13,31 @@ using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Diagnostics.Logger;
namespace MQTTnet.Implementations
{
public sealed class MqttTcpServerAdapter : IMqttServerAdapter
{
readonly List<MqttTcpServerListener> _listeners = new List<MqttTcpServerListener>();
readonly MqttNetSourceLogger _logger;
readonly IMqttNetLogger _rootLogger;
MqttServerOptions _serverOptions;
CancellationTokenSource _cancellationTokenSource;
public MqttTcpServerAdapter(IMqttNetLogger logger)
{
_rootLogger = logger ?? throw new ArgumentNullException(nameof(logger));
_logger = logger.WithSource(nameof(MqttTcpServerAdapter));
}
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
public bool TreatSocketOpeningErrorAsWarning { get; set; }
public Task StartAsync(IMqttServerOptions options)
public Task StartAsync(MqttServerOptions options, IMqttNetLogger logger)
{
if (_cancellationTokenSource != null) throw new InvalidOperationException("Server is already started.");
_serverOptions = options;
_cancellationTokenSource = new CancellationTokenSource();
if (options.DefaultEndpointOptions.IsEnabled)
{
RegisterListeners(options.DefaultEndpointOptions, null, _cancellationTokenSource.Token);
RegisterListeners(options.DefaultEndpointOptions, null, logger, _cancellationTokenSource.Token);
}
if (options.TlsEndpointOptions?.IsEnabled == true)
@@ -55,7 +53,7 @@ namespace MQTTnet.Implementations
throw new InvalidOperationException("The certificate for TLS encryption must contain the private key.");
}
RegisterListeners(options.TlsEndpointOptions, tlsCertificate, _cancellationTokenSource.Token);
RegisterListeners(options.TlsEndpointOptions, tlsCertificate, logger, _cancellationTokenSource.Token);
}
return PlatformAbstractionLayer.CompletedTask;
@@ -92,11 +90,11 @@ namespace MQTTnet.Implementations
}
}
void RegisterListeners(MqttServerTcpEndpointBaseOptions options, X509Certificate2 tlsCertificate, CancellationToken cancellationToken)
void RegisterListeners(MqttServerTcpEndpointBaseOptions tcpEndpointOptions, X509Certificate2 tlsCertificate, IMqttNetLogger logger, CancellationToken cancellationToken)
{
if (!options.BoundInterNetworkAddress.Equals(IPAddress.None))
if (!tcpEndpointOptions.BoundInterNetworkAddress.Equals(IPAddress.None))
{
var listenerV4 = new MqttTcpServerListener(AddressFamily.InterNetwork, options, tlsCertificate, _rootLogger)
var listenerV4 = new MqttTcpServerListener(AddressFamily.InterNetwork, _serverOptions, tcpEndpointOptions, tlsCertificate, logger)
{
ClientHandler = OnClientAcceptedAsync
};
@@ -107,9 +105,9 @@ namespace MQTTnet.Implementations
}
}
if (!options.BoundInterNetworkV6Address.Equals(IPAddress.None))
if (!tcpEndpointOptions.BoundInterNetworkV6Address.Equals(IPAddress.None))
{
var listenerV6 = new MqttTcpServerListener(AddressFamily.InterNetworkV6, options, tlsCertificate, _rootLogger)
var listenerV6 = new MqttTcpServerListener(AddressFamily.InterNetworkV6, _serverOptions, tcpEndpointOptions, tlsCertificate, logger)
{
ClientHandler = OnClientAcceptedAsync
};
@@ -1,4 +1,8 @@
#if !WINDOWS_UWP
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#if !WINDOWS_UWP
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
@@ -12,7 +16,6 @@ using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Diagnostics.Logger;
namespace MQTTnet.Implementations
{
@@ -21,6 +24,7 @@ namespace MQTTnet.Implementations
readonly MqttNetSourceLogger _logger;
readonly IMqttNetLogger _rootLogger;
readonly AddressFamily _addressFamily;
readonly MqttServerOptions _serverOptions;
readonly MqttServerTcpEndpointBaseOptions _options;
readonly MqttServerTlsTcpEndpointOptions _tlsOptions;
readonly X509Certificate2 _tlsCertificate;
@@ -30,12 +34,14 @@ namespace MQTTnet.Implementations
public MqttTcpServerListener(
AddressFamily addressFamily,
MqttServerTcpEndpointBaseOptions options,
MqttServerOptions serverOptions,
MqttServerTcpEndpointBaseOptions tcpEndpointOptions,
X509Certificate2 tlsCertificate,
IMqttNetLogger logger)
{
_addressFamily = addressFamily;
_options = options;
_serverOptions = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
_options = tcpEndpointOptions ?? throw new ArgumentNullException(nameof(tcpEndpointOptions));
_tlsCertificate = tlsCertificate;
_rootLogger = logger;
_logger = logger.WithSource(nameof(MqttTcpServerListener));
@@ -60,12 +66,11 @@ namespace MQTTnet.Implementations
_localEndPoint = new IPEndPoint(boundIp, _options.Port);
_logger.Info("Starting TCP listener for {0} TLS={1}.", _localEndPoint, _tlsCertificate != null);
_logger.Info("Starting TCP listener (Endpoint='{0}', TLS={1}).", _localEndPoint, _tlsCertificate != null);
_socket = new CrossPlatformSocket(_addressFamily);
// Usage of socket options is described here: https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.setsocketoption?view=netcore-2.2
if (_options.ReuseAddress)
{
_socket.ReuseAddress = true;
@@ -76,9 +81,22 @@ namespace MQTTnet.Implementations
_socket.NoDelay = true;
}
if (_options.LingerState != null)
{
_socket.LingerState = _options.LingerState;
}
_socket.Bind(_localEndPoint);
// Get the local endpoint back from the socket. The port may have changed.
// This can happen when port 0 is used. Then the OS will choose the next free port.
_localEndPoint = (IPEndPoint)_socket.LocalEndPoint;
_options.Port = _localEndPoint.Port;
_socket.Listen(_options.ConnectionBacklog);
_logger.Verbose("TCP listener started (Endpoint='{0}'.", _localEndPoint);
Task.Run(() => AcceptClientConnectionsAsync(cancellationToken), cancellationToken).RunInBackground(_logger);
return true;
@@ -179,11 +197,11 @@ namespace MQTTnet.Implementations
var clientHandler = ClientHandler;
if (clientHandler != null)
{
using (var clientAdapter = new MqttChannelAdapter(
new MqttTcpChannel(stream, remoteEndPoint, clientCertificate),
new MqttPacketFormatterAdapter(new MqttPacketWriter()),
null,
_rootLogger))
var tcpChannel = new MqttTcpChannel(stream, remoteEndPoint, clientCertificate);
var bufferWriter = new MqttBufferWriter(_serverOptions.WriterBufferSize, _serverOptions.WriterBufferSizeMax);
var packetFormatterAdapter = new MqttPacketFormatterAdapter(bufferWriter);
using (var clientAdapter = new MqttChannelAdapter(tcpChannel, packetFormatterAdapter, null, _rootLogger))
{
await clientHandler(clientAdapter).ConfigureAwait(false);
}
@@ -1,5 +1,8 @@
using MQTTnet.Channel;
using MQTTnet.Client.Options;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using MQTTnet.Channel;
using MQTTnet.Internal;
using System;
using System.Net;
@@ -7,6 +10,7 @@ using System.Net.WebSockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet.Client;
namespace MQTTnet.Implementations
{
@@ -172,7 +176,7 @@ namespace MQTTnet.Implementations
clientWebSocket.Options.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
// TODO: Find a way to add client options to same callback. Problem is that they have a different type.
var context = new MqttClientCertificateValidationCallbackContext
var context = new MqttClientCertificateValidationEventArgs
{
Certificate = certificate,
Chain = chain,
@@ -1,4 +1,8 @@
using System;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading;
using System.Threading.Tasks;
@@ -16,6 +20,8 @@ namespace MQTTnet.Implementations
public static byte[] EmptyByteArray { get; } = Array.Empty<byte>();
#endif
public static ArraySegment<byte> EmptyByteArraySegment { get; } = new ArraySegment<byte>(EmptyByteArray);
public static void Sleep(TimeSpan timeout)
{
#if !NETSTANDARD1_3 && !WINDOWS_UWP