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 12 kB

12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
12 years ago
12 years ago
10 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
10 years ago
10 years ago
10 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
10 years ago
10 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
12 years ago
12 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
10 years ago
12 years ago
12 years ago
12 years ago
12 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net.Sockets;
  5. using System.Net;
  6. using Shadowsocks.Encrypt;
  7. using Shadowsocks.Model;
  8. namespace Shadowsocks.Controller
  9. {
  10. class Local
  11. {
  12. private Server config;
  13. //private Encryptor encryptor;
  14. Socket _listener;
  15. public Local(Server config)
  16. {
  17. this.config = config;
  18. //this.encryptor = new Encryptor(config.method, config.password);
  19. }
  20. public void Start()
  21. {
  22. try
  23. {
  24. // Create a TCP/IP socket.
  25. _listener = new Socket(AddressFamily.InterNetwork,
  26. SocketType.Stream, ProtocolType.Tcp);
  27. IPEndPoint localEndPoint = new IPEndPoint(0, config.local_port);
  28. // Bind the socket to the local endpoint and listen for incoming connections.
  29. _listener.Bind(localEndPoint);
  30. _listener.Listen(100);
  31. // Start an asynchronous socket to listen for connections.
  32. Console.WriteLine("Shadowsocks started");
  33. _listener.BeginAccept(
  34. new AsyncCallback(AcceptCallback),
  35. _listener);
  36. }
  37. catch(SocketException)
  38. {
  39. _listener.Close();
  40. throw;
  41. }
  42. }
  43. public void Stop()
  44. {
  45. _listener.Close();
  46. }
  47. public void AcceptCallback(IAsyncResult ar)
  48. {
  49. try
  50. {
  51. // Get the socket that handles the client request.
  52. Socket listener = (Socket)ar.AsyncState;
  53. //if (!listener.Connected)
  54. //{
  55. // return;
  56. //}
  57. Socket conn = listener.EndAccept(ar);
  58. listener.BeginAccept(
  59. new AsyncCallback(AcceptCallback),
  60. listener);
  61. // Create the state object.
  62. Handler handler = new Handler();
  63. handler.connection = conn;
  64. //if (encryptor.method == "table")
  65. //{
  66. // handler.encryptor = encryptor;
  67. //}
  68. //else
  69. //{
  70. // handler.encryptor = new Encryptor(config.method, config.password);
  71. //}
  72. handler.encryptor = EncryptorFactory.GetEncryptor(config.method, config.password);
  73. handler.config = config;
  74. handler.Start();
  75. //handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
  76. // new AsyncCallback(ReadCallback), state);
  77. }
  78. catch
  79. {
  80. //Console.WriteLine(e.Message);
  81. }
  82. }
  83. }
  84. class Handler
  85. {
  86. //public Encryptor encryptor;
  87. public IEncryptor encryptor;
  88. public Server config;
  89. // Client socket.
  90. public Socket remote;
  91. public Socket connection;
  92. // Size of receive buffer.
  93. public const int RecvSize = 16384;
  94. public const int BufferSize = RecvSize + 32;
  95. // remote receive buffer
  96. public byte[] remoteRecvBuffer = new byte[RecvSize];
  97. // remote send buffer
  98. public byte[] remoteSendBuffer = new byte[BufferSize];
  99. // connection receive buffer
  100. public byte[] connetionRecvBuffer = new byte[RecvSize];
  101. // connection send buffer
  102. public byte[] connetionSendBuffer = new byte[BufferSize];
  103. // Received data string.
  104. public StringBuilder sb = new StringBuilder();
  105. private bool closed = false;
  106. public void Start()
  107. {
  108. try
  109. {
  110. // TODO async resolving
  111. IPAddress ipAddress;
  112. bool parsed = IPAddress.TryParse(config.server, out ipAddress);
  113. if (!parsed)
  114. {
  115. IPHostEntry ipHostInfo = Dns.GetHostEntry(config.server);
  116. ipAddress = ipHostInfo.AddressList[0];
  117. }
  118. IPEndPoint remoteEP = new IPEndPoint(ipAddress, config.server_port);
  119. remote = new Socket(ipAddress.AddressFamily,
  120. SocketType.Stream, ProtocolType.Tcp);
  121. // Connect to the remote endpoint.
  122. remote.BeginConnect(remoteEP,
  123. new AsyncCallback(ConnectCallback), null);
  124. }
  125. catch (Exception e)
  126. {
  127. Console.WriteLine(e.Message);
  128. this.Close();
  129. }
  130. }
  131. public void Close()
  132. {
  133. if (closed)
  134. {
  135. return;
  136. }
  137. closed = true;
  138. if (connection != null)
  139. {
  140. try
  141. {
  142. connection.Shutdown(SocketShutdown.Send);
  143. }
  144. catch (Exception e)
  145. {
  146. Console.WriteLine(e.Message);
  147. }
  148. }
  149. if (remote != null)
  150. {
  151. try
  152. {
  153. remote.Shutdown(SocketShutdown.Send);
  154. }
  155. catch (SocketException e)
  156. {
  157. Console.WriteLine(e.Message);
  158. }
  159. }
  160. ((IDisposable)encryptor).Dispose();
  161. }
  162. private void ConnectCallback(IAsyncResult ar)
  163. {
  164. try
  165. {
  166. // Complete the connection.
  167. remote.EndConnect(ar);
  168. //Console.WriteLine("Socket connected to {0}",
  169. // remote.RemoteEndPoint.ToString());
  170. HandshakeReceive();
  171. }
  172. catch (Exception e)
  173. {
  174. Console.WriteLine(e.Message);
  175. this.Close();
  176. }
  177. }
  178. private void HandshakeReceive()
  179. {
  180. try
  181. {
  182. connection.BeginReceive(connetionRecvBuffer, 0, 256, 0,
  183. new AsyncCallback(HandshakeReceiveCallback), null);
  184. }
  185. catch (Exception e)
  186. {
  187. Console.WriteLine(e.Message);
  188. this.Close();
  189. }
  190. }
  191. private void HandshakeReceiveCallback(IAsyncResult ar)
  192. {
  193. try
  194. {
  195. int bytesRead = connection.EndReceive(ar);
  196. if (bytesRead > 1)
  197. {
  198. byte[] response = { 5, 0 };
  199. if (connetionRecvBuffer[0] != 5)
  200. {
  201. // reject socks 4
  202. response = new byte[]{ 0, 91 };
  203. }
  204. connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(handshakeSendCallback), null);
  205. }
  206. else
  207. {
  208. this.Close();
  209. }
  210. }
  211. catch (Exception e)
  212. {
  213. Console.WriteLine(e.Message);
  214. this.Close();
  215. }
  216. }
  217. private void handshakeSendCallback(IAsyncResult ar)
  218. {
  219. try
  220. {
  221. connection.EndSend(ar);
  222. // +----+-----+-------+------+----------+----------+
  223. // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
  224. // +----+-----+-------+------+----------+----------+
  225. // | 1 | 1 | X'00' | 1 | Variable | 2 |
  226. // +----+-----+-------+------+----------+----------+
  227. // Skip first 3 bytes
  228. // TODO validate
  229. connection.BeginReceive(connetionRecvBuffer, 0, 3, 0,
  230. new AsyncCallback(handshakeReceive2Callback), null);
  231. }
  232. catch (Exception e)
  233. {
  234. Console.WriteLine(e.Message);
  235. this.Close();
  236. }
  237. }
  238. private void handshakeReceive2Callback(IAsyncResult ar)
  239. {
  240. try
  241. {
  242. int bytesRead = connection.EndReceive(ar);
  243. if (bytesRead > 0)
  244. {
  245. byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
  246. connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(startPipe), null);
  247. }
  248. else
  249. {
  250. this.Close();
  251. }
  252. }
  253. catch (Exception e)
  254. {
  255. Console.WriteLine(e.Message);
  256. this.Close();
  257. }
  258. }
  259. private void startPipe(IAsyncResult ar)
  260. {
  261. try
  262. {
  263. connection.EndReceive(ar);
  264. remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0,
  265. new AsyncCallback(pipeRemoteReceiveCallback), null);
  266. connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
  267. new AsyncCallback(pipeConnectionReceiveCallback), null);
  268. }
  269. catch (Exception e)
  270. {
  271. Console.WriteLine(e.Message);
  272. this.Close();
  273. }
  274. }
  275. private void pipeRemoteReceiveCallback(IAsyncResult ar)
  276. {
  277. try
  278. {
  279. int bytesRead = remote.EndReceive(ar);
  280. if (bytesRead > 0)
  281. {
  282. int bytesToSend;
  283. encryptor.Decrypt(remoteRecvBuffer, bytesRead, remoteSendBuffer, out bytesToSend);
  284. connection.BeginSend(remoteSendBuffer, 0, bytesToSend, 0, new AsyncCallback(pipeConnectionSendCallback), null);
  285. }
  286. else
  287. {
  288. Console.WriteLine("bytesRead: " + bytesRead.ToString());
  289. this.Close();
  290. }
  291. }
  292. catch (Exception e)
  293. {
  294. Console.WriteLine(e.Message);
  295. this.Close();
  296. }
  297. }
  298. private void pipeConnectionReceiveCallback(IAsyncResult ar)
  299. {
  300. try
  301. {
  302. int bytesRead = connection.EndReceive(ar);
  303. if (bytesRead > 0)
  304. {
  305. int bytesToSend;
  306. encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend);
  307. remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(pipeRemoteSendCallback), null);
  308. }
  309. else
  310. {
  311. this.Close();
  312. }
  313. }
  314. catch (Exception e)
  315. {
  316. Console.WriteLine(e.Message);
  317. this.Close();
  318. }
  319. }
  320. private void pipeRemoteSendCallback(IAsyncResult ar)
  321. {
  322. try
  323. {
  324. remote.EndSend(ar);
  325. connection.BeginReceive(this.connetionRecvBuffer, 0, RecvSize, 0,
  326. new AsyncCallback(pipeConnectionReceiveCallback), null);
  327. }
  328. catch (Exception e)
  329. {
  330. Console.WriteLine(e.Message);
  331. this.Close();
  332. }
  333. }
  334. private void pipeConnectionSendCallback(IAsyncResult ar)
  335. {
  336. try
  337. {
  338. connection.EndSend(ar);
  339. remote.BeginReceive(this.remoteRecvBuffer, 0, RecvSize, 0,
  340. new AsyncCallback(pipeRemoteReceiveCallback), null);
  341. }
  342. catch (Exception e)
  343. {
  344. Console.WriteLine(e.Message);
  345. this.Close();
  346. }
  347. }
  348. }
  349. }