Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace Proxy
- {
- class SocksProxy
- {
- public int Port;
- public SocksProxy(int port)
- {
- Port = port;
- }
- public void Listen()
- {
- Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- listener.Bind(new IPEndPoint(IPAddress.Any, Port));
- listener.Listen(1000);
- listener.BeginAccept(ListenerAccept, listener);
- }
- private void ListenerAccept(IAsyncResult ar)
- {
- Socket listener = (Socket)ar.AsyncState;
- listener.BeginAccept(ListenerAccept, listener);
- Socket local = listener.EndAccept(ar);
- Socket remote = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- byte[] buffer = new byte[9000];
- local.Receive(buffer, 0, buffer.Length, SocketFlags.None);
- if (buffer[0] == 5 && buffer[2] == 0)
- {
- buffer[1] = 0;
- local.Send(buffer, 0, 2, SocketFlags.None);
- int received = local.Receive(buffer, 0, buffer.Length, SocketFlags.None);
- if (buffer[1] != 1)
- throw new NotSupportedException("Only tcp connections");
- if (buffer[3] != 1 && buffer[3] != 3)
- throw new NotSupportedException("Only ipv4 or domain name");
- try
- {
- IPEndPoint remoteEndPoint = GetAddress(buffer);
- remote.Connect(remoteEndPoint);
- }
- catch (SocketException)
- {
- buffer[1] = 4;
- local.Send(buffer, 0, received, SocketFlags.None);
- local.Shutdown(SocketShutdown.Both);
- return;
- }
- buffer[1] = 0;
- local.Send(buffer, 0, received, SocketFlags.None);
- Socket[] sockets = new []{local, remote};
- ThreadPool.QueueUserWorkItem(SocketPool.AddConnections, sockets);
- NetworkState state = new NetworkState(local, remote);
- state.LocalSocket.BeginReceive(state.LocalBuffer, 0, state.LocalBuffer.Length, SocketFlags.None, LocalReceive, state);
- state.RemoteSocket.BeginReceive(state.RemoteBuffer, 0, state.RemoteBuffer.Length, SocketFlags.None, RemoteReceive, state);
- }
- }
- private IPEndPoint GetAddress(byte[] buf)
- {
- int port;
- switch (buf[3])
- {
- case 1:
- string ip = buf[4] + "." + buf[5] + "." + buf[6] + "." + buf[7];
- port = buf[8] * 256 + buf[9];
- return new IPEndPoint(IPAddress.Parse(ip), port);
- case 3:
- byte len = buf[4];
- string host = Encoding.ASCII.GetString(buf, 5, len);
- port = buf[len + 5] * 256 + buf[len + 6];
- IPAddress address;
- if (IPAddress.TryParse(host, out address))
- return new IPEndPoint(address, port);
- IPAddress[] addresses = Dns.GetHostEntry(host).AddressList;
- if (addresses.Length < 1)
- throw new SocketException();
- return new IPEndPoint(addresses[0], port);
- }
- throw new Exception();
- }
- private void LocalReceive(IAsyncResult ar)
- {
- NetworkState state = (NetworkState)ar.AsyncState;
- int received;
- try
- {
- received = state.LocalSocket.EndReceive(ar);
- }
- catch (ObjectDisposedException)
- {
- return;
- }
- if (received > 0)
- {
- try
- {
- state.RemoteSocket.Send(state.LocalBuffer, 0, received, SocketFlags.None);
- }
- catch (SocketException)
- {
- return;
- }
- state.LocalSocket.BeginReceive(state.LocalBuffer, 0, state.LocalBuffer.Length, SocketFlags.None, LocalReceive, state);
- }
- }
- private void RemoteReceive(IAsyncResult ar)
- {
- NetworkState state = (NetworkState)ar.AsyncState;
- int received;
- try
- {
- received = state.RemoteSocket.EndReceive(ar);
- }
- catch (ObjectDisposedException)
- {
- return;
- }
- if (received > 0)
- {
- try
- {
- state.LocalSocket.Send(state.RemoteBuffer, 0, received, SocketFlags.None);
- }
- catch (SocketException)
- {
- return;
- }
- state.RemoteSocket.BeginReceive(state.RemoteBuffer, 0, state.RemoteBuffer.Length, SocketFlags.None, RemoteReceive, state);
- }
- }
- }
- class NetworkState
- {
- public byte[] LocalBuffer;
- public byte[] RemoteBuffer;
- public readonly Socket LocalSocket;
- public readonly Socket RemoteSocket;
- public NetworkState(Socket local, Socket remote)
- {
- LocalBuffer = new byte[8192];
- RemoteBuffer = new byte[8192];
- LocalSocket = local;
- RemoteSocket = remote;
- }
- }
- public static class SocketPool
- {
- #pragma warning disable 169
- private static Timer _timer = new Timer(RemoveInactiveConnections, null, 15000, 20000);
- #pragma warning restore 169
- private static bool _removeIsWorking;
- private static readonly object ForLocking = new object();
- public static List<Tuple<Socket, Socket>> ActiveConnections = new List<Tuple<Socket, Socket>>();
- public static void AddConnections(object state)
- {
- Socket[] sockets = (Socket[])state;
- lock (ForLocking)
- ActiveConnections.Add(new Tuple<Socket, Socket>(sockets[0], sockets[1]));
- }
- private static void RemoveInactiveConnections(object state)
- {
- if (_removeIsWorking)
- return;
- _removeIsWorking = true;
- var forDelete = new List<Tuple<Socket, Socket>>();
- lock (ForLocking)
- foreach (var activeConnection in ActiveConnections)
- if (!IsActive(activeConnection.Item1) || !IsActive(activeConnection.Item2))
- forDelete.Add(activeConnection);
- foreach (var tuple in forDelete)
- {
- tuple.Item1.Close();
- tuple.Item2.Close();
- ActiveConnections.Remove(tuple);
- }
- _removeIsWorking = false;
- }
- private static bool IsActive(Socket s)
- {
- bool part1 = s.Poll(5000, SelectMode.SelectRead);
- bool part2 = (s.Available == 0);
- return !(part1 && part2);
- }
- }
- class Program
- {
- static void Main()
- {
- SocksProxy proxy = new SocksProxy(1080);
- proxy.Listen();
- Console.ReadKey();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement