View difference between Paste ID: S87A59Ua and M7tM2z7v
SHOW: | | - or go back to the newest paste.
1-
namespace HttpProxy
1+
namespace Proxy
2
{
3
    class SocksProxy
4
    {
5
        public int Port;
6
7
        public SocksProxy(int port)
8
        {
9
            Port = port;
10
        }
11
12
13
14
        public void Listen()
15
        {
16
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
17
            listener.Bind(new IPEndPoint(IPAddress.Any, Port));
18
            listener.Listen(1000);
19
            listener.BeginAccept(ListenerAccept, listener);
20
        }
21
22
23
24
        private void ListenerAccept(IAsyncResult ar)
25
        {
26
            Socket listener = (Socket)ar.AsyncState;
27
            listener.BeginAccept(ListenerAccept, listener);
28
            Socket local = listener.EndAccept(ar);
29
            Socket remote = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
30
31
            byte[] buffer = new byte[9000];
32
            local.Receive(buffer, 0, buffer.Length, SocketFlags.None);
33
34
            if (buffer[0] == 5 && buffer[2] == 0)
35
            {
36
                buffer[1] = 0;
37
                local.Send(buffer, 0, 2, SocketFlags.None);
38
                int received = local.Receive(buffer, 0, buffer.Length, SocketFlags.None);
39
                if (buffer[1] != 1)
40
                    throw new NotSupportedException("Only tcp connections");
41
                if (buffer[3] != 1 && buffer[3] != 3)
42
                    throw new NotSupportedException("Only ipv4 or domain name");
43
44
                try
45
                {
46
                    IPEndPoint remoteEndPoint = GetAddress(buffer);
47
                    remote.Connect(remoteEndPoint);
48
                }
49
                catch (SocketException)
50
                {
51
                    buffer[1] = 4;
52
                    local.Send(buffer, 0, received, SocketFlags.None);
53
                    local.Shutdown(SocketShutdown.Both);
54
                    return;
55
                }
56
                buffer[1] = 0;
57
                local.Send(buffer, 0, received, SocketFlags.None);
58
                Socket[] sockets = new []{local, remote};
59
                ThreadPool.QueueUserWorkItem(SocketPool.AddConnections, sockets);
60
61
                NetworkState state = new NetworkState(local, remote);
62
                state.LocalSocket.BeginReceive(state.LocalBuffer, 0, state.LocalBuffer.Length, SocketFlags.None, LocalReceive, state);
63
                state.RemoteSocket.BeginReceive(state.RemoteBuffer, 0, state.RemoteBuffer.Length, SocketFlags.None, RemoteReceive, state);
64
            }
65
        }
66
67
        private IPEndPoint GetAddress(byte[] buf)
68
        {
69
            int port;
70
            switch (buf[3])
71
            {
72
                case 1:
73
                    string ip = buf[4] + "." + buf[5] + "." + buf[6] + "." + buf[7];
74
                    port = buf[8] * 256 + buf[9];
75
                    return new IPEndPoint(IPAddress.Parse(ip), port);
76
77
                case 3:
78
                    byte len = buf[4];
79
                    string host = Encoding.ASCII.GetString(buf, 5, len);
80
                    port = buf[len + 5] * 256 + buf[len + 6];
81
                    IPAddress address;
82
                    if (IPAddress.TryParse(host, out address))
83
                        return new IPEndPoint(address, port);
84
                    IPAddress[] addresses = Dns.GetHostEntry(host).AddressList;
85
                    if (addresses.Length < 1)
86
                        throw new SocketException();
87
                    return new IPEndPoint(addresses[0], port);
88
            }
89
            throw new Exception();
90
        }
91
92
        private void LocalReceive(IAsyncResult ar)
93
        {
94
            NetworkState state = (NetworkState)ar.AsyncState;
95
            int received;
96
            try
97
            {
98
                received = state.LocalSocket.EndReceive(ar);
99
            }
100
            catch (ObjectDisposedException)
101
            {
102
                return;
103
            }
104
105
            if (received > 0)
106
            {
107
                try
108
                {
109
                    state.RemoteSocket.Send(state.LocalBuffer, 0, received, SocketFlags.None);
110
                }
111
                catch (SocketException)
112
                {
113
                    return;
114
                }
115
                state.LocalSocket.BeginReceive(state.LocalBuffer, 0, state.LocalBuffer.Length, SocketFlags.None, LocalReceive, state);
116
            }
117
        }
118
119
        private void RemoteReceive(IAsyncResult ar)
120
        {
121
            NetworkState state = (NetworkState)ar.AsyncState;
122
            int received;
123
            try
124
            {
125
                received = state.RemoteSocket.EndReceive(ar);
126
            }
127
            catch (ObjectDisposedException)
128
            {
129
                return;
130
            }
131
132
            if (received > 0)
133
            {
134
                try
135
                {
136
                    state.LocalSocket.Send(state.RemoteBuffer, 0, received, SocketFlags.None);
137
                }
138
                catch (SocketException)
139
                {
140
                    return;
141
                }
142
                state.RemoteSocket.BeginReceive(state.RemoteBuffer, 0, state.RemoteBuffer.Length, SocketFlags.None, RemoteReceive, state);
143
            }
144
        }
145
    }
146
147
    class NetworkState
148
    {
149
        public byte[] LocalBuffer;
150
        public byte[] RemoteBuffer;
151
        public readonly Socket LocalSocket;
152
        public readonly Socket RemoteSocket;
153
154
        public NetworkState(Socket local, Socket remote)
155
        {
156
            LocalBuffer = new byte[8192];
157
            RemoteBuffer = new byte[8192];
158
            LocalSocket = local;
159
            RemoteSocket = remote;
160
        }
161
    }
162
163
    public static class SocketPool
164
    {
165
        #pragma warning disable 169
166
        private static Timer _timer = new Timer(RemoveInactiveConnections, null, 15000, 20000);
167
        #pragma warning restore 169
168
        private static bool _removeIsWorking;
169
        private static readonly object ForLocking = new object();
170
171
        public static List<Tuple<Socket, Socket>> ActiveConnections = new List<Tuple<Socket, Socket>>();
172
173
174
175
        public static void AddConnections(object state)
176
        {
177
            Socket[] sockets = (Socket[])state;
178
            lock (ForLocking)
179
                ActiveConnections.Add(new Tuple<Socket, Socket>(sockets[0], sockets[1]));
180
        }
181
182
183
184
        private static void RemoveInactiveConnections(object state)
185
        {
186
            if (_removeIsWorking)
187
                return;
188
            _removeIsWorking = true;
189
            var forDelete = new List<Tuple<Socket, Socket>>();
190
            lock (ForLocking)
191
                foreach (var activeConnection in ActiveConnections)
192
                    if (!IsActive(activeConnection.Item1) || !IsActive(activeConnection.Item2))
193
                        forDelete.Add(activeConnection);
194
            foreach (var tuple in forDelete)
195
            {
196
                tuple.Item1.Close();
197
                tuple.Item2.Close();
198
                ActiveConnections.Remove(tuple);
199
            }
200
            _removeIsWorking = false;
201
        }
202
203
        private static bool IsActive(Socket s)
204
        {
205
            bool part1 = s.Poll(5000, SelectMode.SelectRead);
206
            bool part2 = (s.Available == 0);
207
            return !(part1 && part2);
208
        }
209
    }
210
211
    class Program
212
    {
213
        static void Main()
214
        {
215
            SocksProxy proxy = new SocksProxy(1080);
216
            proxy.Listen();
217
            Console.ReadKey();
218
        }
219
    }
220
}