Added EndPoint RemoteEndPoint {get;} property to channel (#2111)

* Added EndPoint RemoteEndPoint{get;} property

* Reformat code

* Reformat code

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
This commit is contained in:
老九
2024-12-02 11:52:24 +01:00
committed by GitHub
co-authored by christian
parent ef5b6c9b32
commit 8089c6bdbc
20 changed files with 91 additions and 55 deletions
@@ -61,21 +61,21 @@ public sealed class MqttConnectionContext : IMqttChannelAdapter
}
}
public string Endpoint
public EndPoint RemoteEndPoint
{
get
{
// mqtt over tcp
if (_connection.RemoteEndPoint != null)
{
return _connection.RemoteEndPoint.ToString();
return _connection.RemoteEndPoint;
}
// mqtt over websocket
var httpFeature = _connection.Features.Get<IHttpConnectionFeature>();
if (httpFeature?.RemoteIpAddress != null)
{
return new IPEndPoint(httpFeature.RemoteIpAddress, httpFeature.RemotePort).ToString();
return new IPEndPoint(httpFeature.RemoteIpAddress, httpFeature.RemotePort);
}
return null;
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Net;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@@ -28,7 +29,8 @@ public sealed class MqttWebSocketServerAdapter : IMqttServerAdapter
{
ArgumentNullException.ThrowIfNull(webSocket);
var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}";
var remoteAddress = httpContext.Connection.RemoteIpAddress;
var remoteEndPoint = remoteAddress == null ? null : new IPEndPoint(remoteAddress, httpContext.Connection.RemotePort);
var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false);
try
@@ -39,7 +41,7 @@ public sealed class MqttWebSocketServerAdapter : IMqttServerAdapter
if (clientHandler != null)
{
var formatter = new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535));
var channel = new MqttWebSocketChannel(webSocket, endpoint, isSecureConnection, clientCertificate);
var channel = new MqttWebSocketChannel(webSocket, remoteEndPoint, isSecureConnection, clientCertificate);
using (var channelAdapter = new MqttChannelAdapter(channel, formatter, _logger))
{
@@ -15,6 +15,7 @@ using MQTTnet.Formatter.V3;
using BenchmarkDotNet.Jobs;
using MQTTnet.Diagnostics.Logger;
using System.Buffers;
using System.Net;
namespace MQTTnet.Benchmarks
{
@@ -76,7 +77,7 @@ namespace MQTTnet.Benchmarks
_position = _buffer.Offset;
}
public string Endpoint { get; } = string.Empty;
public EndPoint RemoteEndPoint { get; set; }
public bool IsSecureConnection { get; } = false;
@@ -5,6 +5,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using MQTTnet.Formatter;
using MQTTnet.Packets;
@@ -14,11 +15,11 @@ namespace MQTTnet.Server
{
readonly MqttConnectPacket _connectPacket;
public ClientConnectedEventArgs(MqttConnectPacket connectPacket, MqttProtocolVersion protocolVersion, string endpoint, IDictionary sessionItems)
public ClientConnectedEventArgs(MqttConnectPacket connectPacket, MqttProtocolVersion protocolVersion, EndPoint remoteEndPoint, IDictionary sessionItems)
{
_connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));
ProtocolVersion = protocolVersion;
Endpoint = endpoint;
RemoteEndPoint = remoteEndPoint;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
@@ -35,7 +36,10 @@ namespace MQTTnet.Server
/// <summary>
/// Gets the endpoint of the connected client.
/// </summary>
public string Endpoint { get; }
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets the protocol version which is used by the connected client.
@@ -5,6 +5,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using MQTTnet.Packets;
using MQTTnet.Protocol;
@@ -18,12 +19,12 @@ namespace MQTTnet.Server
string clientId,
MqttDisconnectPacket disconnectPacket,
MqttClientDisconnectType disconnectType,
string endpoint,
EndPoint remoteEndPoint,
IDictionary sessionItems)
{
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
DisconnectType = disconnectType;
Endpoint = endpoint;
RemoteEndPoint = remoteEndPoint;
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
// The DISCONNECT packet can be null in case of a non clean disconnect or session takeover.
@@ -38,7 +39,10 @@ namespace MQTTnet.Server
public MqttClientDisconnectType DisconnectType { get; }
public string Endpoint { get; }
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets the reason code sent by the client.
@@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Net;
using System.Threading;
using MQTTnet.Packets;
@@ -11,11 +12,11 @@ namespace MQTTnet.Server
{
public sealed class InterceptingPacketEventArgs : EventArgs
{
public InterceptingPacketEventArgs(CancellationToken cancellationToken, string clientId, string endpoint, MqttPacket packet, IDictionary sessionItems)
public InterceptingPacketEventArgs(CancellationToken cancellationToken, string clientId, EndPoint remoteEndPoint, MqttPacket packet, IDictionary sessionItems)
{
CancellationToken = cancellationToken;
ClientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
Endpoint = endpoint;
RemoteEndPoint = remoteEndPoint;
Packet = packet ?? throw new ArgumentNullException(nameof(packet));
SessionItems = sessionItems;
}
@@ -34,7 +35,10 @@ namespace MQTTnet.Server
/// <summary>
/// Gets the endpoint of the sending or receiving client.
/// </summary>
public string Endpoint { get; }
public EndPoint RemoteEndPoint { get; }
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets or sets the MQTT packet which was received or will be sent.
@@ -5,6 +5,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using MQTTnet.Adapter;
@@ -70,7 +71,10 @@ namespace MQTTnet.Server
/// </summary>
public string ClientId => _connectPacket.ClientId;
public string Endpoint => ChannelAdapter.Endpoint;
public EndPoint RemoteEndPoint => ChannelAdapter.RemoteEndPoint;
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
public bool IsSecureConnection => ChannelAdapter.IsSecureConnection;
@@ -167,11 +167,11 @@ namespace MQTTnet.Server.Internal.Adapter
async Task TryHandleClientConnectionAsync(CrossPlatformSocket clientSocket)
{
Stream stream = null;
string remoteEndPoint = null;
EndPoint remoteEndPoint = null;
try
{
remoteEndPoint = clientSocket.RemoteEndPoint.ToString();
remoteEndPoint = clientSocket.RemoteEndPoint;
_logger.Verbose("TCP client '{0}' accepted (Local endpoint={1})", remoteEndPoint, _localEndPoint);
@@ -19,22 +19,18 @@ namespace MQTTnet.Server.Internal;
public sealed class MqttClientSessionsManager : ISubscriptionChangedNotification, IDisposable
{
readonly Dictionary<string, MqttConnectedClient> _clients = new(4096);
readonly AsyncLock _createConnectionSyncRoot = new();
readonly MqttServerEventContainer _eventContainer;
readonly MqttNetSourceLogger _logger;
readonly MqttServerOptions _options;
readonly MqttRetainedMessagesManager _retainedMessagesManager;
readonly IMqttNetLogger _rootLogger;
readonly ReaderWriterLockSlim _sessionsManagementLock = new();
// The _sessions dictionary contains all session, the _subscriberSessions hash set contains subscriber sessions only.
// See the MqttSubscription object for a detailed explanation.
readonly MqttSessionsStorage _sessionsStorage = new();
readonly HashSet<MqttSession> _subscriberSessions = new();
readonly HashSet<MqttSession> _subscriberSessions = [];
public MqttClientSessionsManager(MqttServerOptions options, MqttRetainedMessagesManager retainedMessagesManager, MqttServerEventContainer eventContainer, IMqttNetLogger logger)
{
@@ -365,7 +361,11 @@ public sealed class MqttClientSessionsManager : ISubscriptionChangedNotification
if (_eventContainer.ClientConnectedEvent.HasHandlers)
{
var eventArgs = new ClientConnectedEventArgs(connectPacket, channelAdapter.PacketFormatterAdapter.ProtocolVersion, channelAdapter.Endpoint, connectedClient.Session.Items);
var eventArgs = new ClientConnectedEventArgs(
connectPacket,
channelAdapter.PacketFormatterAdapter.ProtocolVersion,
channelAdapter.RemoteEndPoint,
connectedClient.Session.Items);
await _eventContainer.ClientConnectedEvent.TryInvokeAsync(eventArgs, _logger).ConfigureAwait(false);
}
@@ -403,7 +403,7 @@ public sealed class MqttClientSessionsManager : ISubscriptionChangedNotification
}
}
var endpoint = connectedClient.Endpoint;
var endpoint = connectedClient.RemoteEndPoint;
if (connectedClient.Id != null && !connectedClient.IsTakenOver && _eventContainer.ClientDisconnectedEvent.HasHandlers)
{
@@ -591,7 +591,12 @@ public sealed class MqttClientSessionsManager : ISubscriptionChangedNotification
if (_eventContainer.ClientDisconnectedEvent.HasHandlers)
{
var eventArgs = new ClientDisconnectedEventArgs(oldConnectedClient.Id, null, MqttClientDisconnectType.Takeover, oldConnectedClient.Endpoint, oldConnectedClient.Session.Items);
var eventArgs = new ClientDisconnectedEventArgs(
oldConnectedClient.Id,
null,
MqttClientDisconnectType.Takeover,
oldConnectedClient.RemoteEndPoint,
oldConnectedClient.Session.Items);
await _eventContainer.ClientDisconnectedEvent.TryInvokeAsync(eventArgs, _logger).ConfigureAwait(false);
}
@@ -655,14 +660,14 @@ public sealed class MqttClientSessionsManager : ISubscriptionChangedNotification
}
catch (OperationCanceledException)
{
_logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint);
_logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.RemoteEndPoint);
}
catch (MqttCommunicationTimedOutException)
{
_logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint);
_logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.RemoteEndPoint);
}
_logger.Warning("Client '{0}': First received packet was no 'CONNECT' packet [MQTT-3.1.0-1].", channelAdapter.Endpoint);
_logger.Warning("Client '{0}': First received packet was no 'CONNECT' packet [MQTT-3.1.0-1].", channelAdapter.RemoteEndPoint);
return null;
}
@@ -2,6 +2,7 @@
// 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.Net;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Exceptions;
@@ -45,7 +46,7 @@ public sealed class MqttConnectedClient : IDisposable
ConnectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));
ChannelAdapter = channelAdapter ?? throw new ArgumentNullException(nameof(channelAdapter));
Endpoint = channelAdapter.Endpoint;
RemoteEndPoint = channelAdapter.RemoteEndPoint;
Session = session ?? throw new ArgumentNullException(nameof(session));
ArgumentNullException.ThrowIfNull(logger);
@@ -59,14 +60,14 @@ public sealed class MqttConnectedClient : IDisposable
public MqttDisconnectPacket DisconnectPacket { get; private set; }
public string Endpoint { get; }
public string Id => ConnectPacket.ClientId;
public bool IsRunning { get; private set; }
public bool IsTakenOver { get; set; }
public EndPoint RemoteEndPoint { get; }
public MqttSession Session { get; }
public MqttClientStatistics Statistics { get; } = new();
@@ -338,7 +339,7 @@ public sealed class MqttConnectedClient : IDisposable
return packet;
}
var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, Endpoint, packet, Session.Items);
var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, RemoteEndPoint, packet, Session.Items);
await _eventContainer.InterceptingOutboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false);
if (!interceptingPacketEventArgs.ProcessPacket || packet == null)
@@ -384,7 +385,7 @@ public sealed class MqttConnectedClient : IDisposable
if (_eventContainer.InterceptingInboundPacketEvent.HasHandlers)
{
var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, Endpoint, currentPacket, Session.Items);
var interceptingPacketEventArgs = new InterceptingPacketEventArgs(cancellationToken, Id, RemoteEndPoint, currentPacket, Session.Items);
await _eventContainer.InterceptingInboundPacketEvent.InvokeAsync(interceptingPacketEventArgs).ConfigureAwait(false);
currentPacket = interceptingPacketEventArgs.Packet;
processPacket = interceptingPacketEventArgs.ProcessPacket;
@@ -560,10 +561,8 @@ public sealed class MqttConnectedClient : IDisposable
var disconnectPacket = MqttDisconnectPacketFactory.Create(options);
using (var timeout = new CancellationTokenSource(_serverOptions.DefaultCommunicationTimeout))
{
await SendPacketAsync(disconnectPacket, timeout.Token).ConfigureAwait(false);
}
using var timeout = new CancellationTokenSource(_serverOptions.DefaultCommunicationTimeout);
await SendPacketAsync(disconnectPacket, timeout.Token).ConfigureAwait(false);
}
catch (Exception exception)
{
@@ -4,6 +4,7 @@
using MQTTnet.Formatter;
using MQTTnet.Server.Internal;
using System.Net;
namespace MQTTnet.Server;
@@ -22,7 +23,10 @@ public sealed class MqttClientStatus
public DateTime ConnectedTimestamp => _client.Statistics.ConnectedTimestamp;
public string Endpoint => _client.Endpoint;
public EndPoint RemoteEndPoint => _client.RemoteEndPoint;
[Obsolete("Use RemoteEndPoint instead.")]
public string Endpoint => RemoteEndPoint?.ToString();
/// <summary>
/// Gets or sets the client identifier.
+3 -1
View File
@@ -43,7 +43,9 @@ namespace MQTTnet.TestApp
{
try
{
var options = new MqttServerOptions();
var options = new MqttServerOptionsBuilder()
.WithDefaultEndpoint()
.Build();
// Extend the timestamp for all messages from clients.
// Protect several topics from being subscribed from every client.
@@ -2,10 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.AspNetCore.Http;
using MQTTnet.Channel;
using MQTTnet.Internal;
using System.Buffers;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
@@ -26,7 +28,7 @@ namespace MQTTnet.Tests.Mockups
_stream = new MemoryStream(buffer);
}
public string Endpoint { get; } = "<Test channel>";
public EndPoint RemoteEndPoint { get; set; }
public bool IsSecureConnection { get; } = false;
+3 -2
View File
@@ -40,10 +40,11 @@ public class MqttTcpChannel_Tests
},
ct.Token);
var remoteEndPoint = new DnsEndPoint("localhost", 50001);
using var clientSocket = new CrossPlatformSocket(AddressFamily.InterNetwork, ProtocolType.Tcp);
await clientSocket.ConnectAsync(new DnsEndPoint("localhost", 50001), CancellationToken.None);
await clientSocket.ConnectAsync(remoteEndPoint, CancellationToken.None);
var tcpChannel = new MqttTcpChannel(clientSocket.GetStream(), "test", null);
var tcpChannel = new MqttTcpChannel(clientSocket.GetStream(), remoteEndPoint, null);
await Task.Delay(100, ct.Token);
+2 -2
View File
@@ -36,7 +36,7 @@ namespace MQTTnet.Tests.Server
Assert.IsNotNull(eventArgs);
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Connected_Event)));
Assert.IsTrue(eventArgs.Endpoint.Contains("127.0.0.1"));
Assert.IsTrue(eventArgs.RemoteEndPoint.ToString().Contains("127.0.0.1"));
Assert.AreEqual(MqttProtocolVersion.V311, eventArgs.ProtocolVersion);
Assert.AreEqual("TheUser", eventArgs.UserName);
}
@@ -64,7 +64,7 @@ namespace MQTTnet.Tests.Server
Assert.IsNotNull(eventArgs);
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Disconnected_Event)));
Assert.IsTrue(eventArgs.Endpoint.Contains("127.0.0.1"));
Assert.IsTrue(eventArgs.RemoteEndPoint.ToString().Contains("127.0.0.1"));
Assert.AreEqual(MqttClientDisconnectType.Clean, eventArgs.DisconnectType);
}
}
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
@@ -18,7 +19,8 @@ public interface IMqttChannelAdapter : IDisposable
long BytesSent { get; }
X509Certificate2 ClientCertificate { get; }
string Endpoint { get; }
EndPoint RemoteEndPoint { get; }
bool IsSecureConnection { get; }
+2 -1
View File
@@ -5,6 +5,7 @@
using System;
using System.Buffers;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
@@ -51,7 +52,7 @@ public sealed class MqttChannelAdapter : Disposable, IMqttChannelAdapter
public X509Certificate2 ClientCertificate => _channel.ClientCertificate;
public string Endpoint => _channel.Endpoint;
public EndPoint RemoteEndPoint => _channel.RemoteEndPoint;
public bool IsSecureConnection => _channel.IsSecureConnection;
+2 -1
View File
@@ -4,6 +4,7 @@
using System;
using System.Buffers;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
@@ -13,7 +14,7 @@ namespace MQTTnet.Channel;
public interface IMqttChannel : IDisposable
{
X509Certificate2 ClientCertificate { get; }
string Endpoint { get; }
EndPoint RemoteEndPoint { get; }
bool IsSecureConnection { get; }
@@ -37,11 +37,11 @@ namespace MQTTnet.Implementations
IsSecureConnection = clientOptions.ChannelOptions?.TlsOptions?.UseTls == true;
}
public MqttTcpChannel(Stream stream, string endpoint, X509Certificate2 clientCertificate) : this()
public MqttTcpChannel(Stream stream, EndPoint remoteEndPoint, X509Certificate2 clientCertificate) : this()
{
_stream = stream ?? throw new ArgumentNullException(nameof(stream));
Endpoint = endpoint;
RemoteEndPoint = remoteEndPoint;
IsSecureConnection = stream is SslStream;
ClientCertificate = clientCertificate;
@@ -49,7 +49,7 @@ namespace MQTTnet.Implementations
public X509Certificate2 ClientCertificate { get; }
public string Endpoint { get; private set; }
public EndPoint RemoteEndPoint { get; private set; }
public bool IsSecureConnection { get; }
@@ -175,7 +175,7 @@ namespace MQTTnet.Implementations
_stream = networkStream;
}
Endpoint = socket.RemoteEndPoint?.ToString();
RemoteEndPoint = socket.RemoteEndPoint;
}
catch (Exception)
{
@@ -26,18 +26,18 @@ namespace MQTTnet.Implementations
_options = options ?? throw new ArgumentNullException(nameof(options));
}
public MqttWebSocketChannel(WebSocket webSocket, string endpoint, bool isSecureConnection, X509Certificate2 clientCertificate)
public MqttWebSocketChannel(WebSocket webSocket, EndPoint remoteEndPoint, bool isSecureConnection, X509Certificate2 clientCertificate)
{
_webSocket = webSocket ?? throw new ArgumentNullException(nameof(webSocket));
Endpoint = endpoint;
RemoteEndPoint = remoteEndPoint;
IsSecureConnection = isSecureConnection;
ClientCertificate = clientCertificate;
}
public X509Certificate2 ClientCertificate { get; }
public string Endpoint { get; }
public EndPoint RemoteEndPoint { get; }
public bool IsSecureConnection { get; private set; }