From 51496165c2fa046201cc7cda32688811f733be1e Mon Sep 17 00:00:00 2001 From: Kerry Jiang Date: Sat, 10 Aug 2024 13:22:57 -0700 Subject: [PATCH] expose source endpoint through app session --- src/SuperSocket.Connection/ConnectionBase.cs | 3 +++ src/SuperSocket.Connection/IConnection.cs | 3 +++ src/SuperSocket.Connection/PipeConnectionBase.cs | 7 +++++++ .../ProxyProtocol/IProxyProtocolPipelineFilter.cs | 10 ++++++++++ src/SuperSocket.ProtoBase/ProxyProtocol/ProxyInfo.cs | 10 ++++++++++ .../ProxyProtocol/ProxyProtocolPipelineFilter.cs | 3 ++- src/SuperSocket.Server/AppSession.cs | 10 +++++++++- 7 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/SuperSocket.ProtoBase/ProxyProtocol/IProxyProtocolPipelineFilter.cs diff --git a/src/SuperSocket.Connection/ConnectionBase.cs b/src/SuperSocket.Connection/ConnectionBase.cs index 2e091c0f9..e285cf19e 100644 --- a/src/SuperSocket.Connection/ConnectionBase.cs +++ b/src/SuperSocket.Connection/ConnectionBase.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using SuperSocket.ProtoBase; +using SuperSocket.ProtoBase.ProxyProtocol; namespace SuperSocket.Connection { @@ -30,6 +31,8 @@ public abstract class ConnectionBase : IConnection public CancellationToken ConnectionToken { get; protected set; } + public ProxyInfo ProxyInfo { get; protected set; } + protected virtual void OnClosed() { IsClosed = true; diff --git a/src/SuperSocket.Connection/IConnection.cs b/src/SuperSocket.Connection/IConnection.cs index bdf340bcf..140dde76f 100644 --- a/src/SuperSocket.Connection/IConnection.cs +++ b/src/SuperSocket.Connection/IConnection.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using SuperSocket.ProtoBase; +using SuperSocket.ProtoBase.ProxyProtocol; namespace SuperSocket.Connection { @@ -35,5 +36,7 @@ public interface IConnection CloseReason? CloseReason { get; } CancellationToken ConnectionToken { get; } + + ProxyInfo ProxyInfo { get; } } } diff --git a/src/SuperSocket.Connection/PipeConnectionBase.cs b/src/SuperSocket.Connection/PipeConnectionBase.cs index cba380d7a..976ed0cb0 100644 --- a/src/SuperSocket.Connection/PipeConnectionBase.cs +++ b/src/SuperSocket.Connection/PipeConnectionBase.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using Microsoft.Extensions.Logging; using SuperSocket.ProtoBase; +using SuperSocket.ProtoBase.ProxyProtocol; namespace SuperSocket.Connection { @@ -322,6 +323,12 @@ private bool ReaderBuffer(ref ReadOnlySequence buffer, IPipe if (nextFilter != null) { + // ProxyProtocolPipelineFilter always is the first filter and its next filter is the actual first filter. + if (bytesConsumedTotal == 0 && pipelineFilter is IProxyProtocolPipelineFilter proxyProtocolPipelineFilter) + { + ProxyInfo = proxyProtocolPipelineFilter.ProxyInfo; + } + nextFilter.Context = pipelineFilter.Context; // pass through the context _pipelineFilter = pipelineFilter = nextFilter; filterSwitched = true; diff --git a/src/SuperSocket.ProtoBase/ProxyProtocol/IProxyProtocolPipelineFilter.cs b/src/SuperSocket.ProtoBase/ProxyProtocol/IProxyProtocolPipelineFilter.cs new file mode 100644 index 000000000..2c0831896 --- /dev/null +++ b/src/SuperSocket.ProtoBase/ProxyProtocol/IProxyProtocolPipelineFilter.cs @@ -0,0 +1,10 @@ +using System; +using System.Buffers; + +namespace SuperSocket.ProtoBase.ProxyProtocol +{ + public interface IProxyProtocolPipelineFilter : IPipelineFilter + { + ProxyInfo ProxyInfo { get; } + } +} \ No newline at end of file diff --git a/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyInfo.cs b/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyInfo.cs index 0fc4e4d84..e39494443 100644 --- a/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyInfo.cs +++ b/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyInfo.cs @@ -25,6 +25,16 @@ public class ProxyInfo internal int AddressLength { get; set; } + public EndPoint SourceEndPoint { get; private set; } + + public EndPoint DestinationEndPoint { get; private set; } + + internal void Prepare() + { + SourceEndPoint = new IPEndPoint(SourceIPAddress, SourcePort); + DestinationEndPoint = new IPEndPoint(DestinationIPAddress, DestinationPort); + } + public ProxyInfo() { } diff --git a/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyProtocolPipelineFilter.cs b/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyProtocolPipelineFilter.cs index abbc83671..a5f7f06d2 100644 --- a/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyProtocolPipelineFilter.cs +++ b/src/SuperSocket.ProtoBase/ProxyProtocol/ProxyProtocolPipelineFilter.cs @@ -3,7 +3,7 @@ namespace SuperSocket.ProtoBase.ProxyProtocol { - public class ProxyProtocolPipelineFilter : PackagePartsPipelineFilter + public class ProxyProtocolPipelineFilter : PackagePartsPipelineFilter, IProxyProtocolPipelineFilter { private readonly IPipelineFilter _applicationPipelineFilter; @@ -29,6 +29,7 @@ protected override IPackagePartReader GetFirstPartReader() public override void Reset() { // This method will be called when the proxy package handling finishes + ProxyInfo.Prepare(); NextFilter = _applicationPipelineFilter; base.Reset(); Context = _originalFilterContext; diff --git a/src/SuperSocket.Server/AppSession.cs b/src/SuperSocket.Server/AppSession.cs index 03147b789..d7c156c1f 100644 --- a/src/SuperSocket.Server/AppSession.cs +++ b/src/SuperSocket.Server/AppSession.cs @@ -55,7 +55,15 @@ IConnection IAppSession.Connection public EndPoint RemoteEndPoint { - get { return _connection?.RemoteEndPoint; } + get + { + var connection = _connection; + + if (connection == null) + return null; + + return connection.ProxyInfo?.SourceEndPoint ?? connection.RemoteEndPoint; + } } public EndPoint LocalEndPoint