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

13 years ago
13 years ago
11 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
13 years ago
11 years ago
13 years ago
11 years ago
11 years ago
13 years ago
11 years ago
13 years ago
11 years ago
11 years ago
11 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
11 years ago
11 years ago
11 years ago
13 years ago
11 years ago
11 years ago
11 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
11 years ago
11 years ago
11 years ago
11 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
11 years ago
11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
11 years ago
13 years ago
13 years ago
11 years ago
11 years ago
13 years ago
13 years ago
13 years ago
13 years ago
13 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Net.Sockets;
  5. using System.Net;
  6. using Shadowsocks.Encryption;
  7. using Shadowsocks.Model;
  8. namespace Shadowsocks.Controller
  9. {
  10. class Local
  11. {
  12. private Server _server;
  13. private bool _shareOverLAN;
  14. //private Encryptor encryptor;
  15. Socket _listener;
  16. public Local(Configuration config)
  17. {
  18. this._server = config.GetCurrentServer();
  19. _shareOverLAN = config.shareOverLan;
  20. //this.encryptor = new Encryptor(config.method, config.password);
  21. }
  22. public void Start()
  23. {
  24. try
  25. {
  26. // Create a TCP/IP socket.
  27. _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  28. _listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
  29. IPEndPoint localEndPoint = null;
  30. if (_shareOverLAN)
  31. {
  32. localEndPoint = new IPEndPoint(IPAddress.Any, _server.local_port);
  33. }
  34. else
  35. {
  36. localEndPoint = new IPEndPoint(IPAddress.Loopback, _server.local_port);
  37. }
  38. // Bind the socket to the local endpoint and listen for incoming connections.
  39. _listener.Bind(localEndPoint);
  40. _listener.Listen(100);
  41. // Start an asynchronous socket to listen for connections.
  42. Console.WriteLine("Shadowsocks started");
  43. _listener.BeginAccept(
  44. new AsyncCallback(AcceptCallback),
  45. _listener);
  46. }
  47. catch(SocketException)
  48. {
  49. _listener.Close();
  50. throw;
  51. }
  52. }
  53. public void Stop()
  54. {
  55. _listener.Close();
  56. // Console.WriteLine("Shadowsocks stopped");
  57. }
  58. public void AcceptCallback(IAsyncResult ar)
  59. {
  60. Socket listener = (Socket)ar.AsyncState;
  61. try
  62. {
  63. Socket conn = listener.EndAccept(ar);
  64. conn.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
  65. Handler handler = new Handler();
  66. handler.connection = conn;
  67. handler.encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
  68. handler.config = _server;
  69. handler.Start();
  70. }
  71. catch
  72. {
  73. //Console.WriteLine(e.Message);
  74. }
  75. finally
  76. {
  77. try
  78. {
  79. listener.BeginAccept(
  80. new AsyncCallback(AcceptCallback),
  81. listener);
  82. }
  83. catch
  84. {
  85. //Console.WriteLine(e.Message);
  86. }
  87. }
  88. }
  89. }
  90. class Handler
  91. {
  92. //public Encryptor encryptor;
  93. public IEncryptor encryptor;
  94. public Server config;
  95. // Client socket.
  96. public Socket remote;
  97. public Socket connection;
  98. // Size of receive buffer.
  99. public const int RecvSize = 16384;
  100. public const int BufferSize = RecvSize + 32;
  101. // remote receive buffer
  102. private byte[] remoteRecvBuffer = new byte[RecvSize];
  103. // remote send buffer
  104. private byte[] remoteSendBuffer = new byte[BufferSize];
  105. // connection receive buffer
  106. private byte[] connetionRecvBuffer = new byte[RecvSize];
  107. // connection send buffer
  108. private byte[] connetionSendBuffer = new byte[BufferSize];
  109. // Received data string.
  110. private bool connectionShutdown = false;
  111. private bool remoteShutdown = false;
  112. private bool closed = false;
  113. private object encryptionLock = new object();
  114. private object decryptionLock = new object();
  115. public void Start()
  116. {
  117. try
  118. {
  119. // TODO async resolving
  120. IPAddress ipAddress;
  121. bool parsed = IPAddress.TryParse(config.server, out ipAddress);
  122. if (!parsed)
  123. {
  124. IPHostEntry ipHostInfo = Dns.GetHostEntry(config.server);
  125. ipAddress = ipHostInfo.AddressList[0];
  126. }
  127. IPEndPoint remoteEP = new IPEndPoint(ipAddress, config.server_port);
  128. remote = new Socket(ipAddress.AddressFamily,
  129. SocketType.Stream, ProtocolType.Tcp);
  130. remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
  131. // Connect to the remote endpoint.
  132. remote.BeginConnect(remoteEP,
  133. new AsyncCallback(ConnectCallback), null);
  134. }
  135. catch (Exception e)
  136. {
  137. Logging.LogUsefulException(e);
  138. this.Close();
  139. }
  140. }
  141. private void CheckClose()
  142. {
  143. if (connectionShutdown && remoteShutdown)
  144. {
  145. this.Close();
  146. }
  147. }
  148. public void Close()
  149. {
  150. lock (this)
  151. {
  152. if (closed)
  153. {
  154. return;
  155. }
  156. closed = true;
  157. }
  158. if (connection != null)
  159. {
  160. try
  161. {
  162. connection.Shutdown(SocketShutdown.Both);
  163. connection.Close();
  164. }
  165. catch (Exception e)
  166. {
  167. Logging.LogUsefulException(e);
  168. }
  169. }
  170. if (remote != null)
  171. {
  172. try
  173. {
  174. remote.Shutdown(SocketShutdown.Both);
  175. remote.Close();
  176. }
  177. catch (SocketException e)
  178. {
  179. Logging.LogUsefulException(e);
  180. }
  181. }
  182. lock (encryptionLock)
  183. {
  184. lock (decryptionLock)
  185. {
  186. ((IDisposable)encryptor).Dispose();
  187. }
  188. }
  189. }
  190. private void ConnectCallback(IAsyncResult ar)
  191. {
  192. if (closed)
  193. {
  194. return;
  195. }
  196. try
  197. {
  198. // Complete the connection.
  199. remote.EndConnect(ar);
  200. //Console.WriteLine("Socket connected to {0}",
  201. // remote.RemoteEndPoint.ToString());
  202. HandshakeReceive();
  203. }
  204. catch (Exception e)
  205. {
  206. Logging.LogUsefulException(e);
  207. this.Close();
  208. }
  209. }
  210. private void HandshakeReceive()
  211. {
  212. if (closed)
  213. {
  214. return;
  215. }
  216. try
  217. {
  218. connection.BeginReceive(connetionRecvBuffer, 0, 256, 0,
  219. new AsyncCallback(HandshakeReceiveCallback), null);
  220. }
  221. catch (Exception e)
  222. {
  223. Logging.LogUsefulException(e);
  224. this.Close();
  225. }
  226. }
  227. private void HandshakeReceiveCallback(IAsyncResult ar)
  228. {
  229. if (closed)
  230. {
  231. return;
  232. }
  233. try
  234. {
  235. int bytesRead = connection.EndReceive(ar);
  236. if (bytesRead > 1)
  237. {
  238. byte[] response = { 5, 0 };
  239. if (connetionRecvBuffer[0] != 5)
  240. {
  241. // reject socks 4
  242. response = new byte[]{ 0, 91 };
  243. Console.WriteLine("socks 5 protocol error");
  244. }
  245. connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(HandshakeSendCallback), null);
  246. }
  247. else
  248. {
  249. this.Close();
  250. }
  251. }
  252. catch (Exception e)
  253. {
  254. Logging.LogUsefulException(e);
  255. this.Close();
  256. }
  257. }
  258. private void HandshakeSendCallback(IAsyncResult ar)
  259. {
  260. if (closed)
  261. {
  262. return;
  263. }
  264. try
  265. {
  266. connection.EndSend(ar);
  267. // +----+-----+-------+------+----------+----------+
  268. // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
  269. // +----+-----+-------+------+----------+----------+
  270. // | 1 | 1 | X'00' | 1 | Variable | 2 |
  271. // +----+-----+-------+------+----------+----------+
  272. // Skip first 3 bytes
  273. // TODO validate
  274. connection.BeginReceive(connetionRecvBuffer, 0, 3, 0,
  275. new AsyncCallback(handshakeReceive2Callback), null);
  276. }
  277. catch (Exception e)
  278. {
  279. Logging.LogUsefulException(e);
  280. this.Close();
  281. }
  282. }
  283. private void handshakeReceive2Callback(IAsyncResult ar)
  284. {
  285. if (closed)
  286. {
  287. return;
  288. }
  289. try
  290. {
  291. int bytesRead = connection.EndReceive(ar);
  292. if (bytesRead > 0)
  293. {
  294. byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
  295. connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(StartPipe), null);
  296. }
  297. else
  298. {
  299. Console.WriteLine("failed to recv data in handshakeReceive2Callback");
  300. this.Close();
  301. }
  302. }
  303. catch (Exception e)
  304. {
  305. Logging.LogUsefulException(e);
  306. this.Close();
  307. }
  308. }
  309. private void StartPipe(IAsyncResult ar)
  310. {
  311. if (closed)
  312. {
  313. return;
  314. }
  315. try
  316. {
  317. connection.EndReceive(ar);
  318. remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0,
  319. new AsyncCallback(PipeRemoteReceiveCallback), null);
  320. connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
  321. new AsyncCallback(PipeConnectionReceiveCallback), null);
  322. }
  323. catch (Exception e)
  324. {
  325. Logging.LogUsefulException(e);
  326. this.Close();
  327. }
  328. }
  329. private void PipeRemoteReceiveCallback(IAsyncResult ar)
  330. {
  331. if (closed)
  332. {
  333. return;
  334. }
  335. try
  336. {
  337. int bytesRead = remote.EndReceive(ar);
  338. if (bytesRead > 0)
  339. {
  340. int bytesToSend;
  341. lock (decryptionLock)
  342. {
  343. if (closed)
  344. {
  345. return;
  346. }
  347. encryptor.Decrypt(remoteRecvBuffer, bytesRead, remoteSendBuffer, out bytesToSend);
  348. }
  349. connection.BeginSend(remoteSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeConnectionSendCallback), null);
  350. }
  351. else
  352. {
  353. //Console.WriteLine("bytesRead: " + bytesRead.ToString());
  354. connection.Shutdown(SocketShutdown.Send);
  355. connectionShutdown = true;
  356. CheckClose();
  357. }
  358. }
  359. catch (Exception e)
  360. {
  361. Logging.LogUsefulException(e);
  362. this.Close();
  363. }
  364. }
  365. private void PipeConnectionReceiveCallback(IAsyncResult ar)
  366. {
  367. if (closed)
  368. {
  369. return;
  370. }
  371. try
  372. {
  373. int bytesRead = connection.EndReceive(ar);
  374. if (bytesRead > 0)
  375. {
  376. int bytesToSend;
  377. lock (encryptionLock)
  378. {
  379. if (closed)
  380. {
  381. return;
  382. }
  383. encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend);
  384. }
  385. remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null);
  386. }
  387. else
  388. {
  389. remote.Shutdown(SocketShutdown.Send);
  390. remoteShutdown = true;
  391. CheckClose();
  392. }
  393. }
  394. catch (Exception e)
  395. {
  396. Logging.LogUsefulException(e);
  397. this.Close();
  398. }
  399. }
  400. private void PipeRemoteSendCallback(IAsyncResult ar)
  401. {
  402. if (closed)
  403. {
  404. return;
  405. }
  406. try
  407. {
  408. remote.EndSend(ar);
  409. connection.BeginReceive(this.connetionRecvBuffer, 0, RecvSize, 0,
  410. new AsyncCallback(PipeConnectionReceiveCallback), null);
  411. }
  412. catch (Exception e)
  413. {
  414. Logging.LogUsefulException(e);
  415. this.Close();
  416. }
  417. }
  418. private void PipeConnectionSendCallback(IAsyncResult ar)
  419. {
  420. if (closed)
  421. {
  422. return;
  423. }
  424. try
  425. {
  426. connection.EndSend(ar);
  427. remote.BeginReceive(this.remoteRecvBuffer, 0, RecvSize, 0,
  428. new AsyncCallback(PipeRemoteReceiveCallback), null);
  429. }
  430. catch (Exception e)
  431. {
  432. Logging.LogUsefulException(e);
  433. this.Close();
  434. }
  435. }
  436. }
  437. }