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