You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Local.cs 9.8 kB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net.Sockets;
  5. using System.Net;
  6. namespace shadowsocks_csharp
  7. {
  8. class Local
  9. {
  10. private Config config;
  11. private Encryptor encryptor;
  12. Socket listener;
  13. public Local(Config config)
  14. {
  15. this.config = config;
  16. this.encryptor = new Encryptor(config.password);
  17. }
  18. public void Start()
  19. {
  20. // Create a TCP/IP socket.
  21. listener = new Socket(AddressFamily.InterNetwork,
  22. SocketType.Stream, ProtocolType.Tcp);
  23. IPEndPoint localEndPoint = new IPEndPoint(0, config.local_port);
  24. // Bind the socket to the local endpoint and listen for incoming connections.
  25. listener.Bind(localEndPoint);
  26. listener.Listen(100);
  27. // Start an asynchronous socket to listen for connections.
  28. Console.WriteLine("Waiting for a connection...");
  29. listener.BeginAccept(
  30. new AsyncCallback(AcceptCallback),
  31. listener);
  32. }
  33. public void Stop()
  34. {
  35. listener.Close();
  36. }
  37. public void AcceptCallback(IAsyncResult ar)
  38. {
  39. try
  40. {
  41. // Get the socket that handles the client request.
  42. Socket listener = (Socket)ar.AsyncState;
  43. listener.BeginAccept(
  44. new AsyncCallback(AcceptCallback),
  45. listener);
  46. Socket conn = listener.EndAccept(ar);
  47. // Create the state object.
  48. Handler handler = new Handler();
  49. handler.connection = conn;
  50. handler.encryptor = encryptor;
  51. handler.config = config;
  52. handler.Start();
  53. //handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
  54. // new AsyncCallback(ReadCallback), state);
  55. }
  56. catch (Exception e)
  57. {
  58. Console.WriteLine(e.ToString());
  59. }
  60. }
  61. }
  62. class Handler
  63. {
  64. public Encryptor encryptor;
  65. public Config config;
  66. // Client socket.
  67. public Socket remote;
  68. public Socket connection;
  69. // Size of receive buffer.
  70. public const int BufferSize = 1500;
  71. // remote receive buffer
  72. public byte[] remoteBuffer = new byte[BufferSize];
  73. // connection receive buffer
  74. public byte[] connetionBuffer = new byte[BufferSize];
  75. // Received data string.
  76. public StringBuilder sb = new StringBuilder();
  77. public void Start()
  78. {
  79. // TODO async resolving
  80. IPHostEntry ipHostInfo = Dns.GetHostEntry(config.server);
  81. IPAddress ipAddress = ipHostInfo.AddressList[0];
  82. IPEndPoint remoteEP = new IPEndPoint(ipAddress, config.server_port);
  83. remote = new Socket(AddressFamily.InterNetwork,
  84. SocketType.Stream, ProtocolType.Tcp);
  85. // Connect to the remote endpoint.
  86. remote.BeginConnect(remoteEP,
  87. new AsyncCallback(connectCallback), null);
  88. }
  89. public void Close()
  90. {
  91. connection.Close();
  92. remote.Close();
  93. }
  94. private void connectCallback(IAsyncResult ar)
  95. {
  96. try
  97. {
  98. // Complete the connection.
  99. remote.EndConnect(ar);
  100. Console.WriteLine("Socket connected to {0}",
  101. remote.RemoteEndPoint.ToString());
  102. handshakeReceive();
  103. }
  104. catch (Exception e)
  105. {
  106. Console.WriteLine(e.ToString());
  107. this.Close();
  108. }
  109. }
  110. private void handshakeReceive()
  111. {
  112. try
  113. {
  114. connection.BeginReceive(new byte[256], 0, 256, 0,
  115. new AsyncCallback(handshakeReceiveCallback), null);
  116. }
  117. catch (Exception e)
  118. {
  119. Console.WriteLine(e.ToString());
  120. this.Close();
  121. }
  122. }
  123. private void handshakeReceiveCallback(IAsyncResult ar)
  124. {
  125. try
  126. {
  127. int bytesRead = connection.EndReceive(ar);
  128. if (bytesRead > 0)
  129. {
  130. byte[] response = { 5, 0 };
  131. connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(handshakeSendCallback), null);
  132. }
  133. else
  134. {
  135. this.Close();
  136. }
  137. }
  138. catch (Exception e)
  139. {
  140. Console.WriteLine(e.ToString());
  141. this.Close();
  142. }
  143. }
  144. private void handshakeSendCallback(IAsyncResult ar)
  145. {
  146. try
  147. {
  148. connection.EndSend(ar);
  149. // +----+-----+-------+------+----------+----------+
  150. // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
  151. // +----+-----+-------+------+----------+----------+
  152. // | 1 | 1 | X'00' | 1 | Variable | 2 |
  153. // +----+-----+-------+------+----------+----------+
  154. // Skip first 3 bytes
  155. // TODO validate
  156. connection.BeginReceive(new byte[3], 0, 3, 0,
  157. new AsyncCallback(handshakeReceive2Callback), null);
  158. }
  159. catch (Exception e)
  160. {
  161. Console.WriteLine(e.ToString());
  162. this.Close();
  163. }
  164. }
  165. private void handshakeReceive2Callback(IAsyncResult ar)
  166. {
  167. try
  168. {
  169. int bytesRead = connection.EndReceive(ar);
  170. if (bytesRead > 0)
  171. {
  172. byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
  173. connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(startPipe), null);
  174. }
  175. else
  176. {
  177. Console.WriteLine("bytesRead: " + bytesRead.ToString());
  178. this.Close();
  179. }
  180. }
  181. catch (Exception e)
  182. {
  183. Console.WriteLine(e.ToString());
  184. this.Close();
  185. }
  186. }
  187. private void startPipe(IAsyncResult ar)
  188. {
  189. try
  190. {
  191. connection.EndReceive(ar);
  192. remote.BeginReceive(remoteBuffer, 0, BufferSize, 0,
  193. new AsyncCallback(pipeRemoteReceiveCallback), null);
  194. connection.BeginReceive(connetionBuffer, 0, BufferSize, 0,
  195. new AsyncCallback(pipeConnectionReceiveCallback), null);
  196. }
  197. catch (Exception e)
  198. {
  199. Console.WriteLine(e.ToString());
  200. }
  201. }
  202. private void pipeRemoteReceiveCallback(IAsyncResult ar)
  203. {
  204. try
  205. {
  206. int bytesRead = remote.EndReceive(ar);
  207. if (bytesRead > 0)
  208. {
  209. encryptor.Decrypt(remoteBuffer, bytesRead);
  210. connection.BeginSend(remoteBuffer, 0, bytesRead, 0, new AsyncCallback(pipeConnectionSendCallback), null);
  211. }
  212. else
  213. {
  214. Console.WriteLine("bytesRead: " + bytesRead.ToString());
  215. this.Close();
  216. }
  217. }
  218. catch (Exception e)
  219. {
  220. Console.WriteLine(e.ToString());
  221. this.Close();
  222. }
  223. }
  224. private void pipeConnectionReceiveCallback(IAsyncResult ar)
  225. {
  226. try
  227. {
  228. int bytesRead = connection.EndReceive(ar);
  229. if (bytesRead > 0)
  230. {
  231. encryptor.Encrypt(connetionBuffer, bytesRead);
  232. remote.BeginSend(connetionBuffer, 0, bytesRead, 0, new AsyncCallback(pipeRemoteSendCallback), null);
  233. }
  234. else
  235. {
  236. Console.WriteLine("bytesRead: " + bytesRead.ToString());
  237. this.Close();
  238. }
  239. }
  240. catch (Exception e)
  241. {
  242. Console.WriteLine(e.ToString());
  243. this.Close();
  244. }
  245. }
  246. private void pipeRemoteSendCallback(IAsyncResult ar)
  247. {
  248. try
  249. {
  250. remote.EndSend(ar);
  251. connection.BeginReceive(this.connetionBuffer, 0, BufferSize, 0,
  252. new AsyncCallback(pipeConnectionReceiveCallback), null);
  253. }
  254. catch (Exception e)
  255. {
  256. Console.WriteLine(e.ToString());
  257. this.Close();
  258. }
  259. }
  260. private void pipeConnectionSendCallback(IAsyncResult ar)
  261. {
  262. try
  263. {
  264. connection.EndSend(ar);
  265. remote.BeginReceive(this.remoteBuffer, 0, BufferSize, 0,
  266. new AsyncCallback(pipeRemoteReceiveCallback), null);
  267. }
  268. catch (Exception e)
  269. {
  270. Console.WriteLine(e.ToString());
  271. this.Close();
  272. }
  273. }
  274. }
  275. }

No Description

Contributors (1)