Browse Source

Expose client certificate at MQTT connection validator. Make DualMode optional.

release/3.x.x
Christian Kratky 5 years ago
parent
commit
60c6074953
19 changed files with 116 additions and 30 deletions
  1. +3
    -0
      Source/MQTTnet.AspnetCore/MqttConnectionContext.cs
  2. +18
    -11
      Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs
  3. +2
    -0
      Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttChannel.cs
  4. +3
    -0
      Source/MQTTnet/Adapter/IMqttChannelAdapter.cs
  5. +3
    -0
      Source/MQTTnet/Adapter/MqttChannelAdapter.cs
  6. +2
    -0
      Source/MQTTnet/Channel/IMqttChannel.cs
  7. +1
    -0
      Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
  8. +1
    -1
      Source/MQTTnet/Client/Options/MqttClientTcpOptions.cs
  9. +5
    -1
      Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs
  10. +14
    -3
      Source/MQTTnet/Implementations/MqttTcpChannel.cs
  11. +19
    -3
      Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs
  12. +12
    -2
      Source/MQTTnet/Implementations/MqttTcpServerListener.cs
  13. +13
    -4
      Source/MQTTnet/Implementations/MqttWebSocketChannel.cs
  14. +3
    -0
      Source/MQTTnet/Internal/TestMqttChannel.cs
  15. +3
    -2
      Source/MQTTnet/Server/MqttClientSessionsManager.cs
  16. +7
    -2
      Source/MQTTnet/Server/MqttConnectionValidatorContext.cs
  17. +3
    -0
      Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs
  18. +3
    -0
      Tests/MQTTnet.Core.Tests/Mockups/TestMqttCommunicationAdapter.cs
  19. +1
    -1
      Tests/MQTTnet.Core.Tests/MqttTcpChannel_Tests.cs

+ 3
- 0
Source/MQTTnet.AspnetCore/MqttConnectionContext.cs View File

@@ -7,6 +7,7 @@ using MQTTnet.Formatter;
using MQTTnet.Packets; using MQTTnet.Packets;
using System; using System;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;


@@ -48,6 +49,8 @@ namespace MQTTnet.AspNetCore


public bool IsSecureConnection => Http?.HttpContext?.Request?.IsHttps ?? false; public bool IsSecureConnection => Http?.HttpContext?.Request?.IsHttps ?? false;


public X509Certificate2 ClientCertificate => Http?.HttpContext?.Connection?.ClientCertificate;

private IHttpContextFeature Http => Connection.Features.Get<IHttpContextFeature>(); private IHttpContextFeature Http => Connection.Features.Get<IHttpContextFeature>();


public ConnectionContext Connection { get; } public ConnectionContext Connection { get; }


+ 18
- 11
Source/MQTTnet.AspnetCore/MqttWebSocketServerAdapter.cs View File

@@ -40,19 +40,26 @@ namespace MQTTnet.AspNetCore
var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}"; var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}";
var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false); var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false);
var isSecureConnection = clientCertificate != null;
clientCertificate?.Dispose();

var clientHandler = ClientHandler;
if (clientHandler != null)
try
{ {
var writer = new SpanBasedMqttPacketWriter();
var formatter = new MqttPacketFormatterAdapter(writer);
var channel = new MqttWebSocketChannel(webSocket, endpoint, isSecureConnection);
using (var channelAdapter = new MqttChannelAdapter(channel, formatter, _logger.CreateChildLogger(nameof(MqttWebSocketServerAdapter))))
var isSecureConnection = clientCertificate != null;

var clientHandler = ClientHandler;
if (clientHandler != null)
{ {
await clientHandler(channelAdapter).ConfigureAwait(false);
}
var writer = new SpanBasedMqttPacketWriter();
var formatter = new MqttPacketFormatterAdapter(writer);
var channel = new MqttWebSocketChannel(webSocket, endpoint, isSecureConnection, clientCertificate);

using (var channelAdapter = new MqttChannelAdapter(channel, formatter, _logger.CreateChildLogger(nameof(MqttWebSocketServerAdapter))))
{
await clientHandler(channelAdapter).ConfigureAwait(false);
}
}
}
finally
{
clientCertificate?.Dispose();
} }
} }




+ 2
- 0
Source/MQTTnet.Extensions.WebSocket4Net/WebSocket4NetMqttChannel.cs View File

@@ -35,6 +35,8 @@ namespace MQTTnet.Extensions.WebSocket4Net


public bool IsSecureConnection { get; private set; } public bool IsSecureConnection { get; private set; }


public X509Certificate2 ClientCertificate { get; }

public async Task ConnectAsync(CancellationToken cancellationToken) public async Task ConnectAsync(CancellationToken cancellationToken)
{ {
var uri = _webSocketOptions.Uri; var uri = _webSocketOptions.Uri;


+ 3
- 0
Source/MQTTnet/Adapter/IMqttChannelAdapter.cs View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Formatter; using MQTTnet.Formatter;
@@ -12,6 +13,8 @@ namespace MQTTnet.Adapter


bool IsSecureConnection { get; } bool IsSecureConnection { get; }


X509Certificate2 ClientCertificate { get; }

MqttPacketFormatterAdapter PacketFormatterAdapter { get; } MqttPacketFormatterAdapter PacketFormatterAdapter { get; }


long BytesSent { get; } long BytesSent { get; }


+ 3
- 0
Source/MQTTnet/Adapter/MqttChannelAdapter.cs View File

@@ -2,6 +2,7 @@ using System;
using System.IO; using System.IO;
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Channel; using MQTTnet.Channel;
@@ -47,6 +48,8 @@ namespace MQTTnet.Adapter


public bool IsSecureConnection => _channel.IsSecureConnection; public bool IsSecureConnection => _channel.IsSecureConnection;


public X509Certificate2 ClientCertificate => _channel.ClientCertificate;

public MqttPacketFormatterAdapter PacketFormatterAdapter { get; } public MqttPacketFormatterAdapter PacketFormatterAdapter { get; }


public long BytesSent => Interlocked.Read(ref _bytesSent); public long BytesSent => Interlocked.Read(ref _bytesSent);


+ 2
- 0
Source/MQTTnet/Channel/IMqttChannel.cs View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;


@@ -8,6 +9,7 @@ namespace MQTTnet.Channel
{ {
string Endpoint { get; } string Endpoint { get; }
bool IsSecureConnection { get; } bool IsSecureConnection { get; }
X509Certificate2 ClientCertificate { get; }


Task ConnectAsync(CancellationToken cancellationToken); Task ConnectAsync(CancellationToken cancellationToken);
Task DisconnectAsync(CancellationToken cancellationToken); Task DisconnectAsync(CancellationToken cancellationToken);


+ 1
- 0
Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs View File

@@ -156,6 +156,7 @@ namespace MQTTnet.Client.Options
return this; return this;
} }


// TODO: Consider creating _MqttClientTcpOptionsBuilder_ as overload.
public MqttClientOptionsBuilder WithTcpServer(Action<MqttClientTcpOptions> optionsBuilder) public MqttClientOptionsBuilder WithTcpServer(Action<MqttClientTcpOptions> optionsBuilder)
{ {
if (optionsBuilder == null) throw new ArgumentNullException(nameof(optionsBuilder)); if (optionsBuilder == null) throw new ArgumentNullException(nameof(optionsBuilder));


+ 1
- 1
Source/MQTTnet/Client/Options/MqttClientTcpOptions.cs View File

@@ -10,7 +10,7 @@ namespace MQTTnet.Client.Options


public int BufferSize { get; set; } = 65536; public int BufferSize { get; set; } = 65536;


public bool DualMode { get; set; } = true;
public bool? DualMode { get; set; }


public bool NoDelay { get; set; } = true; public bool NoDelay { get; set; } = true;




+ 5
- 1
Source/MQTTnet/Implementations/MqttTcpChannel.Uwp.cs View File

@@ -5,6 +5,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime; using System.Runtime.InteropServices.WindowsRuntime;
using System.Security.Authentication; using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Windows.Networking; using Windows.Networking;
@@ -31,7 +32,7 @@ namespace MQTTnet.Implementations
_bufferSize = _options.BufferSize; _bufferSize = _options.BufferSize;
} }


public MqttTcpChannel(StreamSocket socket, IMqttServerOptions serverOptions)
public MqttTcpChannel(StreamSocket socket, X509Certificate2 clientCertificate, IMqttServerOptions serverOptions)
{ {
_socket = socket ?? throw new ArgumentNullException(nameof(socket)); _socket = socket ?? throw new ArgumentNullException(nameof(socket));
_bufferSize = serverOptions.DefaultEndpointOptions.BufferSize; _bufferSize = serverOptions.DefaultEndpointOptions.BufferSize;
@@ -39,6 +40,7 @@ namespace MQTTnet.Implementations
CreateStreams(); CreateStreams();


IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12; IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12;
ClientCertificate = clientCertificate;


Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort; Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort;
} }
@@ -49,6 +51,8 @@ namespace MQTTnet.Implementations


public bool IsSecureConnection { get; } public bool IsSecureConnection { get; }


public X509Certificate2 ClientCertificate { get; }

public async Task ConnectAsync(CancellationToken cancellationToken) public async Task ConnectAsync(CancellationToken cancellationToken)
{ {
if (_socket == null) if (_socket == null)


+ 14
- 3
Source/MQTTnet/Implementations/MqttTcpChannel.cs View File

@@ -28,18 +28,22 @@ namespace MQTTnet.Implementations
IsSecureConnection = clientOptions.ChannelOptions?.TlsOptions?.UseTls == true; IsSecureConnection = clientOptions.ChannelOptions?.TlsOptions?.UseTls == true;
} }


public MqttTcpChannel(Stream stream, string endpoint)
public MqttTcpChannel(Stream stream, string endpoint, X509Certificate2 clientCertificate)
{ {
_stream = stream ?? throw new ArgumentNullException(nameof(stream)); _stream = stream ?? throw new ArgumentNullException(nameof(stream));


IsSecureConnection = stream is SslStream;
Endpoint = endpoint; Endpoint = endpoint;

IsSecureConnection = stream is SslStream;
ClientCertificate = clientCertificate;
} }


public string Endpoint { get; private set; } public string Endpoint { get; private set; }


public bool IsSecureConnection { get; } public bool IsSecureConnection { get; }


public X509Certificate2 ClientCertificate { get; }

public async Task ConnectAsync(CancellationToken cancellationToken) public async Task ConnectAsync(CancellationToken cancellationToken)
{ {
Socket socket; Socket socket;
@@ -55,9 +59,16 @@ namespace MQTTnet.Implementations


socket.ReceiveBufferSize = _options.BufferSize; socket.ReceiveBufferSize = _options.BufferSize;
socket.SendBufferSize = _options.BufferSize; socket.SendBufferSize = _options.BufferSize;
socket.DualMode = _options.DualMode;
socket.NoDelay = _options.NoDelay; socket.NoDelay = _options.NoDelay;


if (_options.DualMode.HasValue)
{
// It is important to avoid setting the flag if no specific value is set by the user
// because on IPv4 only networks the setter will always throw an exception. Regardless
// of the actual value.
socket.DualMode = _options.DualMode.Value;
}
// Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430 // Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430
using (cancellationToken.Register(() => socket.Dispose())) using (cancellationToken.Register(() => socket.Dispose()))
{ {


+ 19
- 3
Source/MQTTnet/Implementations/MqttTcpServerAdapter.Uwp.cs View File

@@ -1,11 +1,13 @@
#if WINDOWS_UWP #if WINDOWS_UWP
using System;
using System.Threading.Tasks;
using Windows.Networking.Sockets; using Windows.Networking.Sockets;
using MQTTnet.Adapter; using MQTTnet.Adapter;
using MQTTnet.Diagnostics; using MQTTnet.Diagnostics;
using MQTTnet.Formatter; using MQTTnet.Formatter;
using MQTTnet.Server; using MQTTnet.Server;
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;


namespace MQTTnet.Implementations namespace MQTTnet.Implementations
{ {
@@ -73,7 +75,21 @@ namespace MQTTnet.Implementations
var clientHandler = ClientHandler; var clientHandler = ClientHandler;
if (clientHandler != null) if (clientHandler != null)
{ {
using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket, _options), new MqttPacketFormatterAdapter(), _logger))
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); await clientHandler(clientAdapter).ConfigureAwait(false);
} }


+ 12
- 2
Source/MQTTnet/Implementations/MqttTcpServerListener.cs View File

@@ -112,17 +112,27 @@ namespace MQTTnet.Implementations


stream = new NetworkStream(clientSocket, true); stream = new NetworkStream(clientSocket, true);


X509Certificate2 clientCertificate = null;

if (_tlsCertificate != null) if (_tlsCertificate != null)
{ {
var sslStream = new SslStream(stream, false); var sslStream = new SslStream(stream, false);
await sslStream.AuthenticateAsServerAsync(_tlsCertificate, false, _tlsOptions.SslProtocol, false).ConfigureAwait(false);

await sslStream.AuthenticateAsServerAsync(
_tlsCertificate,
_tlsOptions.ClientCertificateRequired,
_tlsOptions.SslProtocol,
_tlsOptions.CheckCertificateRevocation).ConfigureAwait(false);

stream = sslStream; stream = sslStream;

clientCertificate = sslStream.RemoteCertificate as X509Certificate2;
} }


var clientHandler = ClientHandler; var clientHandler = ClientHandler;
if (clientHandler != null) if (clientHandler != null)
{ {
using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(stream, remoteEndPoint), new MqttPacketFormatterAdapter(), _logger))
using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(stream, remoteEndPoint, clientCertificate), new MqttPacketFormatterAdapter(), _logger))
{ {
await clientHandler(clientAdapter).ConfigureAwait(false); await clientHandler(clientAdapter).ConfigureAwait(false);
} }


+ 13
- 4
Source/MQTTnet/Implementations/MqttWebSocketChannel.cs View File

@@ -11,9 +11,9 @@ namespace MQTTnet.Implementations
{ {
public class MqttWebSocketChannel : IMqttChannel public class MqttWebSocketChannel : IMqttChannel
{ {
private readonly SemaphoreSlim _sendLock = new SemaphoreSlim(1, 1);
private readonly MqttClientWebSocketOptions _options; private readonly MqttClientWebSocketOptions _options;


private SemaphoreSlim _sendLock = new SemaphoreSlim(1, 1);
private WebSocket _webSocket; private WebSocket _webSocket;


public MqttWebSocketChannel(MqttClientWebSocketOptions options) public MqttWebSocketChannel(MqttClientWebSocketOptions options)
@@ -21,18 +21,21 @@ namespace MQTTnet.Implementations
_options = options ?? throw new ArgumentNullException(nameof(options)); _options = options ?? throw new ArgumentNullException(nameof(options));
} }


public MqttWebSocketChannel(WebSocket webSocket, string endpoint, bool isSecureConnection)
public MqttWebSocketChannel(WebSocket webSocket, string endpoint, bool isSecureConnection, X509Certificate2 clientCertificate)
{ {
_webSocket = webSocket ?? throw new ArgumentNullException(nameof(webSocket)); _webSocket = webSocket ?? throw new ArgumentNullException(nameof(webSocket));


Endpoint = endpoint; Endpoint = endpoint;
IsSecureConnection = isSecureConnection; IsSecureConnection = isSecureConnection;
ClientCertificate = clientCertificate;
} }


public string Endpoint { get; } public string Endpoint { get; }


public bool IsSecureConnection { get; private set; } public bool IsSecureConnection { get; private set; }


public X509Certificate2 ClientCertificate { get; private set; }

public async Task ConnectAsync(CancellationToken cancellationToken) public async Task ConnectAsync(CancellationToken cancellationToken)
{ {
var uri = _options.Uri; var uri = _options.Uri;
@@ -114,9 +117,14 @@ namespace MQTTnet.Implementations


public async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) public async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{ {
// This lock is required because the client will throw an exception if _SendAsync_ is
// The lock is required because the client will throw an exception if _SendAsync_ is
// called from multiple threads at the same time. But this issue only happens with several // called from multiple threads at the same time. But this issue only happens with several
// framework versions. // framework versions.
if (_sendLock == null)
{
return;
}

await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false); await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false);
try try
{ {
@@ -124,13 +132,14 @@ namespace MQTTnet.Implementations
} }
finally finally
{ {
_sendLock.Release();
_sendLock?.Release();
} }
} }


public void Dispose() public void Dispose()
{ {
_sendLock?.Dispose(); _sendLock?.Dispose();
_sendLock = null;


try try
{ {


+ 3
- 0
Source/MQTTnet/Internal/TestMqttChannel.cs View File

@@ -1,4 +1,5 @@
using System.IO; using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Channel; using MQTTnet.Channel;
@@ -18,6 +19,8 @@ namespace MQTTnet.Internal


public bool IsSecureConnection { get; } = false; public bool IsSecureConnection { get; } = false;


public X509Certificate2 ClientCertificate { get; }

public Task ConnectAsync(CancellationToken cancellationToken) public Task ConnectAsync(CancellationToken cancellationToken)
{ {
return Task.FromResult(0); return Task.FromResult(0);


+ 3
- 2
Source/MQTTnet/Server/MqttClientSessionsManager.cs View File

@@ -136,7 +136,7 @@ namespace MQTTnet.Server
await connection.StopAsync().ConfigureAwait(false); await connection.StopAsync().ConfigureAwait(false);
} }


if (_sessions.TryRemove(clientId, out var session))
if (_sessions.TryRemove(clientId, out _))
{ {
} }


@@ -296,7 +296,8 @@ namespace MQTTnet.Server
connectPacket.Password, connectPacket.Password,
connectPacket.WillMessage, connectPacket.WillMessage,
clientAdapter.Endpoint, clientAdapter.Endpoint,
clientAdapter.IsSecureConnection);
clientAdapter.IsSecureConnection,
clientAdapter.ClientCertificate);


var connectionValidator = _options.ConnectionValidator; var connectionValidator = _options.ConnectionValidator;




+ 7
- 2
Source/MQTTnet/Server/MqttConnectionValidatorContext.cs View File

@@ -1,4 +1,5 @@
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using MQTTnet.Protocol; using MQTTnet.Protocol;


namespace MQTTnet.Server namespace MQTTnet.Server
@@ -11,7 +12,8 @@ namespace MQTTnet.Server
byte[] password, byte[] password,
MqttApplicationMessage willMessage, MqttApplicationMessage willMessage,
string endpoint, string endpoint,
bool isSecureConnection)
bool isSecureConnection,
X509Certificate2 clientCertificate)
{ {
ClientId = clientId; ClientId = clientId;
Username = username; Username = username;
@@ -19,6 +21,7 @@ namespace MQTTnet.Server
WillMessage = willMessage; WillMessage = willMessage;
Endpoint = endpoint; Endpoint = endpoint;
IsSecureConnection = isSecureConnection; IsSecureConnection = isSecureConnection;
ClientCertificate = clientCertificate;
} }


public string ClientId { get; } public string ClientId { get; }
@@ -35,6 +38,8 @@ namespace MQTTnet.Server


public bool IsSecureConnection { get; } public bool IsSecureConnection { get; }


public X509Certificate2 ClientCertificate { get; }

public MqttConnectReturnCode ReturnCode { get; set; } = MqttConnectReturnCode.ConnectionAccepted; public MqttConnectReturnCode ReturnCode { get; set; } = MqttConnectReturnCode.ConnectionAccepted;
} }
} }

+ 3
- 0
Tests/MQTTnet.Benchmarks/SerializerBenchmark.cs View File

@@ -1,6 +1,7 @@
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
using MQTTnet.Packets; using MQTTnet.Packets;
using System; using System;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Adapter; using MQTTnet.Adapter;
@@ -77,6 +78,8 @@ namespace MQTTnet.Benchmarks


public bool IsSecureConnection { get; } = false; public bool IsSecureConnection { get; } = false;


public X509Certificate2 ClientCertificate { get; }

public void Reset() public void Reset()
{ {
_position = _buffer.Offset; _position = _buffer.Offset;


+ 3
- 0
Tests/MQTTnet.Core.Tests/Mockups/TestMqttCommunicationAdapter.cs View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Security.Cryptography.X509Certificates;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MQTTnet.Adapter; using MQTTnet.Adapter;
@@ -18,6 +19,8 @@ namespace MQTTnet.Tests.Mockups


public bool IsSecureConnection { get; } = false; public bool IsSecureConnection { get; } = false;


public X509Certificate2 ClientCertificate { get; }

public MqttPacketFormatterAdapter PacketFormatterAdapter { get; } = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311); public MqttPacketFormatterAdapter PacketFormatterAdapter { get; } = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311);


public long BytesSent { get; } public long BytesSent { get; }


+ 1
- 1
Tests/MQTTnet.Core.Tests/MqttTcpChannel_Tests.cs View File

@@ -39,7 +39,7 @@ namespace MQTTnet.Tests


await Task.Delay(100, ct.Token); await Task.Delay(100, ct.Token);


var tcpChannel = new MqttTcpChannel(new NetworkStream(clientSocket, true), "test");
var tcpChannel = new MqttTcpChannel(new NetworkStream(clientSocket, true), "test", null);


var buffer = new byte[1]; var buffer = new byte[1];
await tcpChannel.ReadAsync(buffer, 0, 1, ct.Token); await tcpChannel.ReadAsync(buffer, 0, 1, ct.Token);


Loading…
Cancel
Save