PageRenderTime 79ms CodeModel.GetById 34ms RepoModel.GetById 2ms app.codeStats 0ms

/lib/socks5/proxy.js

https://gitlab.com/mba811/socks5_proxy
JavaScript | 324 lines | 308 code | 15 blank | 1 comment | 59 complexity | 846071b5fb5d7515f95160f7d4399be4 MD5 | raw file
  1. // Generated by CoffeeScript 1.6.3
  2. (function() {
  3. var connections, createServer, fs, inet, inetAton, inetNtoa, net, path, udpRelay, utils;
  4. net = require("net");
  5. udpRelay = require('./udprelay');
  6. fs = require("fs");
  7. path = require("path");
  8. utils = require('./utils');
  9. inet = require('./inet');
  10. inetNtoa = function(buf) {
  11. return buf[0] + "." + buf[1] + "." + buf[2] + "." + buf[3];
  12. };
  13. inetAton = function(ipStr) {
  14. var buf, i, parts;
  15. parts = ipStr.split(".");
  16. if (parts.length !== 4) {
  17. return null;
  18. } else {
  19. buf = new Buffer(4);
  20. i = 0;
  21. while (i < 4) {
  22. buf[i] = +parts[i];
  23. i++;
  24. }
  25. return buf;
  26. }
  27. };
  28. connections = 0;
  29. createServer = function(port, timeout) {
  30. var server;
  31. udpRelay.createServer(port, timeout);
  32. server = net.createServer(function(connection) {
  33. var addrLen, cachedPieces, clean, headerLength, remote, remoteAddr, remotePort, stage;
  34. connections += 1;
  35. stage = 0;
  36. headerLength = 0;
  37. remote = null;
  38. cachedPieces = [];
  39. addrLen = 0;
  40. remoteAddr = null;
  41. remotePort = null;
  42. utils.debug("connections: " + connections);
  43. clean = function() {
  44. utils.debug("clean");
  45. connections -= 1;
  46. remote = null;
  47. connection = null;
  48. return utils.debug("connections: " + connections);
  49. };
  50. connection.on("data", function(data) {
  51. var addrtype, buf, cmd, e, reply, tempBuf;
  52. utils.log(utils.EVERYTHING, "connection on data");
  53. if (stage === 10) {
  54. utils.error("stage cannot be 10");
  55. }
  56. if (stage === 5) {
  57. if (!remote.write(data)) {
  58. connection.pause();
  59. }
  60. return;
  61. }
  62. if (stage === 0) {
  63. tempBuf = new Buffer(2);
  64. tempBuf.write("\u0005\u0000", 0);
  65. console.log(data);
  66. connection.write(tempBuf);
  67. stage = 1;
  68. utils.debug("stage = 1");
  69. return;
  70. }
  71. if (stage === 1) {
  72. try {
  73. cmd = data[1];
  74. addrtype = data[3];
  75. if (cmd === 1) {
  76. } else if (cmd === 3) {
  77. utils.info("UDP assc request from " + connection.localAddress + ":" + connection.localPort);
  78. reply = new Buffer(10);
  79. reply.write("\u0005\u0000\u0000\u0001", 0, 4, "binary");
  80. utils.debug(connection.localAddress);
  81. inetAton(connection.localAddress).copy(reply, 4);
  82. reply.writeUInt16BE(connection.localPort, 8);
  83. connection.write(reply);
  84. stage = 10;
  85. } else {
  86. utils.error("unsupported cmd: " + cmd);
  87. reply = new Buffer("\u0005\u0007\u0000\u0001", "binary");
  88. connection.end(reply);
  89. return;
  90. }
  91. if (addrtype === 3) {
  92. addrLen = data[4];
  93. } else if (addrtype !== 1 && addrtype !== 4) {
  94. utils.error("unsupported addrtype: " + addrtype);
  95. connection.destroy();
  96. return;
  97. }
  98. if (addrtype === 1) {
  99. remoteAddr = inetNtoa(data.slice(4, 8));
  100. remotePort = data.readUInt16BE(8);
  101. headerLength = 10;
  102. } else if (addrtype === 4) {
  103. remoteAddr = inet.inet_ntop(data.slice(4, 20));
  104. remotePort = data.readUInt16BE(20);
  105. headerLength = 22;
  106. } else {
  107. remoteAddr = data.slice(5, 5 + addrLen).toString("binary");
  108. remotePort = data.readUInt16BE(5 + addrLen);
  109. headerLength = 5 + addrLen + 2;
  110. }
  111. if (cmd === 3) {
  112. utils.info("UDP assc: " + remoteAddr + ":" + remotePort);
  113. return;
  114. }
  115. buf = new Buffer(10);
  116. buf.write("\u0005\u0000\u0000\u0001", 0, 4, "binary");
  117. buf.write("\u0000\u0000\u0000\u0000", 4, 4, "binary");
  118. buf.writeInt16BE(2222, 8);
  119. connection.write(buf);
  120. remote = net.connect(remotePort, remoteAddr, function() {
  121. var i, piece;
  122. utils.info("connecting " + remoteAddr + ":" + remotePort);
  123. i = 0;
  124. while (i < cachedPieces.length) {
  125. piece = cachedPieces[i];
  126. if (remote) {
  127. remote.write(piece);
  128. }
  129. i++;
  130. }
  131. cachedPieces = null;
  132. stage = 5;
  133. return utils.debug("stage = 5");
  134. });
  135. remote.on("data", function(data) {
  136. var e;
  137. utils.log(utils.EVERYTHING, "remote on data");
  138. try {
  139. if (!connection.write(data)) {
  140. return remote.pause();
  141. }
  142. } catch (_error) {
  143. e = _error;
  144. utils.error(e);
  145. if (remote) {
  146. remote.destroy();
  147. }
  148. if (connection) {
  149. return connection.destroy();
  150. }
  151. }
  152. });
  153. remote.on("end", function() {
  154. utils.debug("remote on end");
  155. if (connection) {
  156. return connection.end();
  157. }
  158. });
  159. remote.on("error", function(e) {
  160. utils.debug("remote on error");
  161. return utils.error("remote " + remoteAddr + ":" + remotePort + " error: " + e);
  162. });
  163. remote.on("close", function(had_error) {
  164. utils.debug("remote on close:" + had_error);
  165. if (had_error) {
  166. if (connection) {
  167. return connection.destroy();
  168. }
  169. } else {
  170. if (connection) {
  171. return connection.end();
  172. }
  173. }
  174. });
  175. remote.on("drain", function() {
  176. utils.debug("remote on drain");
  177. return connection.resume();
  178. });
  179. remote.setTimeout(timeout, function() {
  180. utils.debug("remote on timeout");
  181. if (remote) {
  182. remote.destroy();
  183. }
  184. if (connection) {
  185. return connection.destroy();
  186. }
  187. });
  188. if (data.length > headerLength) {
  189. buf = new Buffer(data.length - headerLength);
  190. data.copy(buf, 0, headerLength);
  191. cachedPieces.push(buf);
  192. buf = null;
  193. }
  194. stage = 4;
  195. return utils.debug("stage = 4");
  196. } catch (_error) {
  197. e = _error;
  198. utils.error(e);
  199. throw e;
  200. if (connection) {
  201. connection.destroy();
  202. }
  203. if (remote) {
  204. return remote.destroy();
  205. }
  206. }
  207. } else {
  208. if (stage === 4) {
  209. return cachedPieces.push(data);
  210. }
  211. }
  212. });
  213. connection.on("end", function() {
  214. utils.debug("connection on end");
  215. if (remote) {
  216. return remote.end();
  217. }
  218. });
  219. connection.on("error", function(e) {
  220. utils.debug("connection on error");
  221. return utils.error("local error: " + e);
  222. });
  223. connection.on("close", function(had_error) {
  224. utils.debug("connection on close:" + had_error);
  225. if (had_error) {
  226. if (remote) {
  227. remote.destroy();
  228. }
  229. } else {
  230. if (remote) {
  231. remote.end();
  232. }
  233. }
  234. return clean();
  235. });
  236. connection.on("drain", function() {
  237. utils.debug("connection on drain");
  238. if (remote && stage === 5) {
  239. return remote.resume();
  240. }
  241. });
  242. return connection.setTimeout(timeout, function() {
  243. utils.debug("connection on timeout");
  244. if (remote) {
  245. remote.destroy();
  246. }
  247. if (connection) {
  248. return connection.destroy();
  249. }
  250. });
  251. });
  252. server.listen(port, function() {
  253. return utils.info("server listening at port " + port);
  254. });
  255. server.on("error", function(e) {
  256. if (e.code === "EADDRINUSE") {
  257. return utils.error("Address in use, aborting");
  258. } else {
  259. return utils.error(e);
  260. }
  261. });
  262. return server;
  263. };
  264. exports.createServer = createServer;
  265. exports.main = function() {
  266. var PORT, config, configContent, configFromArgs, configPath, k, s, timeout, v;
  267. console.log(utils.version);
  268. configFromArgs = utils.parseArgs();
  269. configPath = 'config.json';
  270. if (configFromArgs.config_file) {
  271. configPath = configFromArgs.config_file;
  272. }
  273. if (!fs.existsSync(configPath)) {
  274. configPath = path.resolve(__dirname, "config.json");
  275. if (!fs.existsSync(configPath)) {
  276. configPath = path.resolve(__dirname, "../../config.json");
  277. if (!fs.existsSync(configPath)) {
  278. configPath = null;
  279. }
  280. }
  281. }
  282. if (configPath) {
  283. utils.info('loading config from ' + configPath);
  284. configContent = fs.readFileSync(configPath);
  285. config = JSON.parse(configContent);
  286. } else {
  287. config = {};
  288. }
  289. for (k in configFromArgs) {
  290. v = configFromArgs[k];
  291. config[k] = v;
  292. }
  293. if (config.verbose) {
  294. utils.config(utils.DEBUG);
  295. }
  296. utils.checkConfig(config);
  297. PORT = config.local_port;
  298. timeout = Math.floor(config.timeout * 1000) || 600000;
  299. s = createServer(PORT, timeout);
  300. return s.on("error", function(e) {
  301. return process.stdout.on('drain', function() {
  302. return process.exit(1);
  303. });
  304. });
  305. };
  306. if (require.main === module) {
  307. exports.main();
  308. }
  309. }).call(this);