/lib/socks5/proxy.js
JavaScript | 324 lines | 308 code | 15 blank | 1 comment | 59 complexity | 846071b5fb5d7515f95160f7d4399be4 MD5 | raw file
- // Generated by CoffeeScript 1.6.3
- (function() {
- var connections, createServer, fs, inet, inetAton, inetNtoa, net, path, udpRelay, utils;
- net = require("net");
- udpRelay = require('./udprelay');
- fs = require("fs");
- path = require("path");
- utils = require('./utils');
- inet = require('./inet');
- inetNtoa = function(buf) {
- return buf[0] + "." + buf[1] + "." + buf[2] + "." + buf[3];
- };
- inetAton = function(ipStr) {
- var buf, i, parts;
- parts = ipStr.split(".");
- if (parts.length !== 4) {
- return null;
- } else {
- buf = new Buffer(4);
- i = 0;
- while (i < 4) {
- buf[i] = +parts[i];
- i++;
- }
- return buf;
- }
- };
- connections = 0;
- createServer = function(port, timeout) {
- var server;
- udpRelay.createServer(port, timeout);
- server = net.createServer(function(connection) {
- var addrLen, cachedPieces, clean, headerLength, remote, remoteAddr, remotePort, stage;
- connections += 1;
- stage = 0;
- headerLength = 0;
- remote = null;
- cachedPieces = [];
- addrLen = 0;
- remoteAddr = null;
- remotePort = null;
- utils.debug("connections: " + connections);
- clean = function() {
- utils.debug("clean");
- connections -= 1;
- remote = null;
- connection = null;
- return utils.debug("connections: " + connections);
- };
- connection.on("data", function(data) {
- var addrtype, buf, cmd, e, reply, tempBuf;
- utils.log(utils.EVERYTHING, "connection on data");
- if (stage === 10) {
- utils.error("stage cannot be 10");
- }
- if (stage === 5) {
- if (!remote.write(data)) {
- connection.pause();
- }
- return;
- }
- if (stage === 0) {
- tempBuf = new Buffer(2);
- tempBuf.write("\u0005\u0000", 0);
- console.log(data);
- connection.write(tempBuf);
- stage = 1;
- utils.debug("stage = 1");
- return;
- }
- if (stage === 1) {
- try {
- cmd = data[1];
- addrtype = data[3];
- if (cmd === 1) {
- } else if (cmd === 3) {
- utils.info("UDP assc request from " + connection.localAddress + ":" + connection.localPort);
- reply = new Buffer(10);
- reply.write("\u0005\u0000\u0000\u0001", 0, 4, "binary");
- utils.debug(connection.localAddress);
- inetAton(connection.localAddress).copy(reply, 4);
- reply.writeUInt16BE(connection.localPort, 8);
- connection.write(reply);
- stage = 10;
- } else {
- utils.error("unsupported cmd: " + cmd);
- reply = new Buffer("\u0005\u0007\u0000\u0001", "binary");
- connection.end(reply);
- return;
- }
- if (addrtype === 3) {
- addrLen = data[4];
- } else if (addrtype !== 1 && addrtype !== 4) {
- utils.error("unsupported addrtype: " + addrtype);
- connection.destroy();
- return;
- }
- if (addrtype === 1) {
- remoteAddr = inetNtoa(data.slice(4, 8));
- remotePort = data.readUInt16BE(8);
- headerLength = 10;
- } else if (addrtype === 4) {
- remoteAddr = inet.inet_ntop(data.slice(4, 20));
- remotePort = data.readUInt16BE(20);
- headerLength = 22;
- } else {
- remoteAddr = data.slice(5, 5 + addrLen).toString("binary");
- remotePort = data.readUInt16BE(5 + addrLen);
- headerLength = 5 + addrLen + 2;
- }
- if (cmd === 3) {
- utils.info("UDP assc: " + remoteAddr + ":" + remotePort);
- return;
- }
- buf = new Buffer(10);
- buf.write("\u0005\u0000\u0000\u0001", 0, 4, "binary");
- buf.write("\u0000\u0000\u0000\u0000", 4, 4, "binary");
- buf.writeInt16BE(2222, 8);
- connection.write(buf);
- remote = net.connect(remotePort, remoteAddr, function() {
- var i, piece;
- utils.info("connecting " + remoteAddr + ":" + remotePort);
- i = 0;
- while (i < cachedPieces.length) {
- piece = cachedPieces[i];
- if (remote) {
- remote.write(piece);
- }
- i++;
- }
- cachedPieces = null;
- stage = 5;
- return utils.debug("stage = 5");
- });
- remote.on("data", function(data) {
- var e;
- utils.log(utils.EVERYTHING, "remote on data");
- try {
- if (!connection.write(data)) {
- return remote.pause();
- }
- } catch (_error) {
- e = _error;
- utils.error(e);
- if (remote) {
- remote.destroy();
- }
- if (connection) {
- return connection.destroy();
- }
- }
- });
- remote.on("end", function() {
- utils.debug("remote on end");
- if (connection) {
- return connection.end();
- }
- });
- remote.on("error", function(e) {
- utils.debug("remote on error");
- return utils.error("remote " + remoteAddr + ":" + remotePort + " error: " + e);
- });
- remote.on("close", function(had_error) {
- utils.debug("remote on close:" + had_error);
- if (had_error) {
- if (connection) {
- return connection.destroy();
- }
- } else {
- if (connection) {
- return connection.end();
- }
- }
- });
- remote.on("drain", function() {
- utils.debug("remote on drain");
- return connection.resume();
- });
- remote.setTimeout(timeout, function() {
- utils.debug("remote on timeout");
- if (remote) {
- remote.destroy();
- }
- if (connection) {
- return connection.destroy();
- }
- });
- if (data.length > headerLength) {
- buf = new Buffer(data.length - headerLength);
- data.copy(buf, 0, headerLength);
- cachedPieces.push(buf);
- buf = null;
- }
- stage = 4;
- return utils.debug("stage = 4");
- } catch (_error) {
- e = _error;
- utils.error(e);
- throw e;
- if (connection) {
- connection.destroy();
- }
- if (remote) {
- return remote.destroy();
- }
- }
- } else {
- if (stage === 4) {
- return cachedPieces.push(data);
- }
- }
- });
- connection.on("end", function() {
- utils.debug("connection on end");
- if (remote) {
- return remote.end();
- }
- });
- connection.on("error", function(e) {
- utils.debug("connection on error");
- return utils.error("local error: " + e);
- });
- connection.on("close", function(had_error) {
- utils.debug("connection on close:" + had_error);
- if (had_error) {
- if (remote) {
- remote.destroy();
- }
- } else {
- if (remote) {
- remote.end();
- }
- }
- return clean();
- });
- connection.on("drain", function() {
- utils.debug("connection on drain");
- if (remote && stage === 5) {
- return remote.resume();
- }
- });
- return connection.setTimeout(timeout, function() {
- utils.debug("connection on timeout");
- if (remote) {
- remote.destroy();
- }
- if (connection) {
- return connection.destroy();
- }
- });
- });
- server.listen(port, function() {
- return utils.info("server listening at port " + port);
- });
- server.on("error", function(e) {
- if (e.code === "EADDRINUSE") {
- return utils.error("Address in use, aborting");
- } else {
- return utils.error(e);
- }
- });
- return server;
- };
- exports.createServer = createServer;
- exports.main = function() {
- var PORT, config, configContent, configFromArgs, configPath, k, s, timeout, v;
- console.log(utils.version);
- configFromArgs = utils.parseArgs();
- configPath = 'config.json';
- if (configFromArgs.config_file) {
- configPath = configFromArgs.config_file;
- }
- if (!fs.existsSync(configPath)) {
- configPath = path.resolve(__dirname, "config.json");
- if (!fs.existsSync(configPath)) {
- configPath = path.resolve(__dirname, "../../config.json");
- if (!fs.existsSync(configPath)) {
- configPath = null;
- }
- }
- }
- if (configPath) {
- utils.info('loading config from ' + configPath);
- configContent = fs.readFileSync(configPath);
- config = JSON.parse(configContent);
- } else {
- config = {};
- }
- for (k in configFromArgs) {
- v = configFromArgs[k];
- config[k] = v;
- }
- if (config.verbose) {
- utils.config(utils.DEBUG);
- }
- utils.checkConfig(config);
- PORT = config.local_port;
- timeout = Math.floor(config.timeout * 1000) || 600000;
- s = createServer(PORT, timeout);
- return s.on("error", function(e) {
- return process.stdout.on('drain', function() {
- return process.exit(1);
- });
- });
- };
- if (require.main === module) {
- exports.main();
- }
- }).call(this);