From 41e2f2a458fba17c69be449f3a5ad220b8734c85 Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 12:14:34 +0800 Subject: [PATCH 01/10] standardize format --- package.json | 68 ++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index ae15960..80ffd04 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,40 @@ { - "name": "shadowsocks", - "description": "a tunnel proxy that help you get through firewalls", - "keywords": ["shadowsocks", "proxy", "socks5"], - "author": "clowwindy", - "version": "1.4.13", - "licenses": [{ - "type": "MIT", - "url": "https://raw.github.com/clowwindy/shadowsocks-nodejs/master/LICENSE" - }], - "engines": { - "node": ">=0.10.0" - }, - "directories": { - "lib": "./lib/shadowsocks" - }, - "main": "./lib/shadowsocks/local", - "bin": { - "sslocal": "./bin/sslocal", - "ssserver": "./bin/ssserver" - }, - "scripts": { - "test": "cake test" - }, - "homepage": "https://github.com/clowwindy/shadowsocks-nodejs", - "bugs": "https://github.com/clowwindy/shadowsocks-nodejs/issues", - "repository": { - "type": "git", - "url": "https://github.com/clowwindy/shadowsocks-nodejs.git" - }, - "devDependencies": { - "coffee-script": ">=1.6.2" + "name": "shadowsocks", + "description": "a tunnel proxy that help you get through firewalls", + "keywords": [ + "shadowsocks", + "proxy", + "socks5" + ], + "author": "clowwindy", + "version": "1.4.13", + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/clowwindy/shadowsocks-nodejs/master/LICENSE" } + ], + "engines": { + "node": ">=0.10.0" + }, + "directories": { + "lib": "./lib/shadowsocks" + }, + "main": "./lib/shadowsocks/local", + "bin": { + "sslocal": "./bin/sslocal", + "ssserver": "./bin/ssserver" + }, + "scripts": { + "test": "cake test" + }, + "homepage": "https://github.com/clowwindy/shadowsocks-nodejs", + "bugs": "https://github.com/clowwindy/shadowsocks-nodejs/issues", + "repository": { + "type": "git", + "url": "https://github.com/clowwindy/shadowsocks-nodejs.git" + }, + "devDependencies": { + "coffee-script": ">=1.6.2" + } } From d1869034314b3123e7ac594d071a4a7c5dcf79d9 Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 12:19:36 +0800 Subject: [PATCH 02/10] Simplify the dev dependencies. Make the cake code more clean. --- Cakefile | 47 +++++++++++++++++------------------------------ package.json | 2 +- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/Cakefile b/Cakefile index b74381b..983388f 100644 --- a/Cakefile +++ b/Cakefile @@ -1,35 +1,22 @@ -{print} = require 'util' -{spawn} = require 'child_process' +spawn = require 'win-spawn' -build = () -> - os = require 'os' - if os.platform() == 'win32' - coffeeCmd = 'coffee.cmd' - else - coffeeCmd = 'coffee' - coffee = spawn coffeeCmd, ['-c', '-o', 'lib/shadowsocks', 'src'] - coffee.stderr.on 'data', (data) -> - process.stderr.write data.toString() - coffee.stdout.on 'data', (data) -> - print data.toString() - coffee.on 'exit', (code) -> - if code != 0 - process.exit code +build = -> + coffee = spawn( + 'coffee' + ['-c', '-o', 'lib/shadowsocks', 'src'] + { stdio: 'inherit' } + ) + coffee.on 'exit', process.exit -test = () -> - os = require 'os' - coffee = spawn 'node', ['lib/shadowsocks/test.js'] - coffee.stderr.on 'data', (data) -> - process.stderr.write data.toString() - coffee.stdout.on 'data', (data) -> - print data.toString() - coffee.on 'exit', (code) -> - if code != 0 - process.exit code +test = -> + coffee = spawn( + 'node' + ['lib/shadowsocks/test.js'] + { stdio: 'inherit' } + ) + coffee.on 'exit', process.exit -task 'build', 'Build ./ from src/', -> - build() +task 'build', 'Build ./ from src/', build -task 'test', 'Run unit test', -> - test() +task 'test', 'Run unit test', test diff --git a/package.json b/package.json index 80ffd04..6135ed4 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,6 @@ "url": "https://github.com/clowwindy/shadowsocks-nodejs.git" }, "devDependencies": { - "coffee-script": ">=1.6.2" + "win-spawn": "~2.0.0" } } From 1b1b169a3379bf88c39d30585ce4d7b73c47ac5a Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 12:27:13 +0800 Subject: [PATCH 03/10] The compiled files shouldn't be tracked by git. --- .gitignore | 2 + lib/shadowsocks/encrypt.js | 252 ---------------------- lib/shadowsocks/inet.js | 103 --------- lib/shadowsocks/local.js | 395 ---------------------------------- lib/shadowsocks/merge_sort.js | 58 ----- lib/shadowsocks/server.js | 352 ------------------------------ lib/shadowsocks/test.js | 100 --------- lib/shadowsocks/udprelay.js | 271 ----------------------- lib/shadowsocks/utils.js | 179 --------------- 9 files changed, 2 insertions(+), 1710 deletions(-) create mode 100644 .gitignore delete mode 100644 lib/shadowsocks/encrypt.js delete mode 100644 lib/shadowsocks/inet.js delete mode 100644 lib/shadowsocks/local.js delete mode 100644 lib/shadowsocks/merge_sort.js delete mode 100644 lib/shadowsocks/server.js delete mode 100644 lib/shadowsocks/test.js delete mode 100644 lib/shadowsocks/udprelay.js delete mode 100644 lib/shadowsocks/utils.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b26ed0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +lib \ No newline at end of file diff --git a/lib/shadowsocks/encrypt.js b/lib/shadowsocks/encrypt.js deleted file mode 100644 index 0447e87..0000000 --- a/lib/shadowsocks/encrypt.js +++ /dev/null @@ -1,252 +0,0 @@ -// Generated by CoffeeScript 1.7.1 - -/* - Copyright (c) 2014 clowwindy - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -(function() { - var EVP_BytesToKey, Encryptor, bytes_to_key_results, cachedTables, crypto, encryptAll, getTable, int32Max, merge_sort, method_supported, substitute, util; - - crypto = require("crypto"); - - util = require("util"); - - merge_sort = require("./merge_sort").merge_sort; - - int32Max = Math.pow(2, 32); - - cachedTables = {}; - - getTable = function(key) { - var ah, al, decrypt_table, hash, i, md5sum, result, table; - if (cachedTables[key]) { - return cachedTables[key]; - } - util.log("calculating ciphers"); - table = new Array(256); - decrypt_table = new Array(256); - md5sum = crypto.createHash("md5"); - md5sum.update(key); - hash = new Buffer(md5sum.digest(), "binary"); - al = hash.readUInt32LE(0); - ah = hash.readUInt32LE(4); - i = 0; - while (i < 256) { - table[i] = i; - i++; - } - i = 1; - while (i < 1024) { - table = merge_sort(table, function(x, y) { - return ((ah % (x + i)) * int32Max + al) % (x + i) - ((ah % (y + i)) * int32Max + al) % (y + i); - }); - i++; - } - i = 0; - while (i < 256) { - decrypt_table[table[i]] = i; - ++i; - } - result = [table, decrypt_table]; - cachedTables[key] = result; - return result; - }; - - substitute = function(table, buf) { - var i; - i = 0; - while (i < buf.length) { - buf[i] = table[buf[i]]; - i++; - } - return buf; - }; - - bytes_to_key_results = {}; - - EVP_BytesToKey = function(password, key_len, iv_len) { - var count, d, data, i, iv, key, m, md5, ms; - if (bytes_to_key_results[password]) { - return bytes_to_key_results[password]; - } - m = []; - i = 0; - count = 0; - while (count < key_len + iv_len) { - md5 = crypto.createHash('md5'); - data = password; - if (i > 0) { - data = Buffer.concat([m[i - 1], password]); - } - md5.update(data); - d = md5.digest(); - m.push(d); - count += d.length; - i += 1; - } - ms = Buffer.concat(m); - key = ms.slice(0, key_len); - iv = ms.slice(key_len, key_len + iv_len); - bytes_to_key_results[password] = [key, iv]; - return [key, iv]; - }; - - method_supported = { - 'aes-128-cfb': [16, 16], - 'aes-192-cfb': [24, 16], - 'aes-256-cfb': [32, 16], - 'bf-cfb': [16, 8], - 'camellia-128-cfb': [16, 16], - 'camellia-192-cfb': [24, 16], - 'camellia-256-cfb': [32, 16], - 'cast5-cfb': [16, 8], - 'des-cfb': [8, 8], - 'idea-cfb': [16, 8], - 'rc2-cfb': [16, 8], - 'rc4': [16, 0], - 'seed-cfb': [16, 16] - }; - - Encryptor = (function() { - function Encryptor(key, method) { - var _ref; - this.key = key; - this.method = method; - this.iv_sent = false; - if (this.method === 'table') { - this.method = null; - } - if (this.method != null) { - this.cipher = this.get_cipher(this.key, this.method, 1, crypto.randomBytes(32)); - } else { - _ref = getTable(this.key), this.encryptTable = _ref[0], this.decryptTable = _ref[1]; - } - } - - Encryptor.prototype.get_cipher_len = function(method) { - var m; - method = method.toLowerCase(); - m = method_supported[method]; - return m; - }; - - Encryptor.prototype.get_cipher = function(password, method, op, iv) { - var iv_, key, m, _ref; - method = method.toLowerCase(); - password = new Buffer(password, 'binary'); - m = this.get_cipher_len(method); - if (m != null) { - _ref = EVP_BytesToKey(password, m[0], m[1]), key = _ref[0], iv_ = _ref[1]; - if (iv == null) { - iv = iv_; - } - if (op === 1) { - this.cipher_iv = iv.slice(0, m[1]); - } - iv = iv.slice(0, m[1]); - if (op === 1) { - return crypto.createCipheriv(method, key, iv); - } else { - return crypto.createDecipheriv(method, key, iv); - } - } - }; - - Encryptor.prototype.encrypt = function(buf) { - var result; - if (this.method != null) { - result = this.cipher.update(buf); - if (this.iv_sent) { - return result; - } else { - this.iv_sent = true; - return Buffer.concat([this.cipher_iv, result]); - } - } else { - return substitute(this.encryptTable, buf); - } - }; - - Encryptor.prototype.decrypt = function(buf) { - var decipher_iv, decipher_iv_len, result; - if (this.method != null) { - if (this.decipher == null) { - decipher_iv_len = this.get_cipher_len(this.method)[1]; - decipher_iv = buf.slice(0, decipher_iv_len); - this.decipher = this.get_cipher(this.key, this.method, 0, decipher_iv); - result = this.decipher.update(buf.slice(decipher_iv_len)); - return result; - } else { - result = this.decipher.update(buf); - return result; - } - } else { - return substitute(this.decryptTable, buf); - } - }; - - return Encryptor; - - })(); - - encryptAll = function(password, method, op, data) { - var cipher, decryptTable, encryptTable, iv, ivLen, iv_, key, keyLen, result, _ref, _ref1, _ref2; - if (method === 'table') { - method = null; - } - if (method == null) { - _ref = getTable(password), encryptTable = _ref[0], decryptTable = _ref[1]; - if (op === 0) { - return substitute(decryptTable, data); - } else { - return substitute(encryptTable, data); - } - } else { - result = []; - method = method.toLowerCase(); - _ref1 = method_supported[method], keyLen = _ref1[0], ivLen = _ref1[1]; - password = Buffer(password, 'binary'); - _ref2 = EVP_BytesToKey(password, keyLen, ivLen), key = _ref2[0], iv_ = _ref2[1]; - if (op === 1) { - iv = crypto.randomBytes(ivLen); - result.push(iv); - } else { - iv = data.slice(0, ivLen); - data = data.slice(ivLen); - } - if (op === 1) { - cipher = crypto.createCipheriv(method, key, iv); - } else { - cipher = crypto.createDecipheriv(method, key, iv); - } - result.push(cipher.update(data)); - result.push(cipher.final()); - return Buffer.concat(result); - } - }; - - exports.Encryptor = Encryptor; - - exports.getTable = getTable; - - exports.encryptAll = encryptAll; - -}).call(this); diff --git a/lib/shadowsocks/inet.js b/lib/shadowsocks/inet.js deleted file mode 100644 index df912e6..0000000 --- a/lib/shadowsocks/inet.js +++ /dev/null @@ -1,103 +0,0 @@ -// The functions in source file is from phpjs -// https://github.com/kvz/phpjs -// See license below -// -// Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io) -// and Contributors (http://phpjs.org/authors) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - - -function inet_pton (a) { - // http://kevin.vanzonneveld.net - // + original by: Theriault - // * example 1: inet_pton('::'); - // * returns 1: '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' (binary) - // * example 2: inet_pton('127.0.0.1'); - // * returns 2: '\x7F\x00\x00\x01' (binary) - var r, m, x, i, j, f = String.fromCharCode; - m = a.match(/^(?:\d{1,3}(?:\.|$)){4}/); // IPv4 - if (m) { - m = m[0].split('.'); - m = f(m[0]) + f(m[1]) + f(m[2]) + f(m[3]); - // Return if 4 bytes, otherwise false. - return m.length === 4 ? m : false; - } - r = /^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})$/; - m = a.match(r); // IPv6 - if (m) { - // Translate each hexadecimal value. - for (j = 1; j < 4; j++) { - // Indice 2 is :: and if no length, continue. - if (j === 2 || m[j].length === 0) { - continue; - } - m[j] = m[j].split(':'); - for (i = 0; i < m[j].length; i++) { - m[j][i] = parseInt(m[j][i], 16); - // Would be NaN if it was blank, return false. - if (isNaN(m[j][i])) { - return false; // Invalid IP. - } - m[j][i] = f(m[j][i] >> 8) + f(m[j][i] & 0xFF); - } - m[j] = m[j].join(''); - } - x = m[1].length + m[3].length; - if (x === 16) { - return m[1] + m[3]; - } else if (x < 16 && m[2].length > 0) { - return m[1] + (new Array(16 - x + 1)).join('\x00') + m[3]; - } - } - return false; // Invalid IP. -} - -function inet_ntop (a) { - // http://kevin.vanzonneveld.net - // + original by: Theriault - // * example 1: inet_ntop('\x7F\x00\x00\x01'); - // * returns 1: '127.0.0.1' - // * example 2: inet_ntop('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1'); - // * returns 2: '::1' - var i = 0, - m = '', - c = []; - if (a.length === 4) { // IPv4 - a += ''; - return [ - a.charCodeAt(0), a.charCodeAt(1), a.charCodeAt(2), a.charCodeAt(3)].join('.'); - } else if (a.length === 16) { // IPv6 - for (i = 0; i < 16; i += 2) { - var group = (a.slice(i, i + 2)).toString("hex"); - //replace 00b1 => b1 0000=>0 - while(group.length > 1 && group.slice(0,1) == '0') - group = group.slice(1); - c.push(group); - } - return c.join(':').replace(/((^|:)0(?=:|$))+:?/g, function (t) { - m = (t.length > m.length) ? t : m; - return t; - }).replace(m || ' ', '::'); - } else { // Invalid length - return false; - } -} -exports.inet_pton = inet_pton; -exports.inet_ntop = inet_ntop; diff --git a/lib/shadowsocks/local.js b/lib/shadowsocks/local.js deleted file mode 100644 index a18c019..0000000 --- a/lib/shadowsocks/local.js +++ /dev/null @@ -1,395 +0,0 @@ -// Generated by CoffeeScript 1.7.1 - -/* - Copyright (c) 2014 clowwindy - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -(function() { - var Encryptor, connections, createServer, fs, inet, net, path, udpRelay, utils; - - net = require("net"); - - fs = require("fs"); - - path = require("path"); - - udpRelay = require("./udprelay"); - - utils = require('./utils'); - - inet = require('./inet'); - - Encryptor = require("./encrypt").Encryptor; - - connections = 0; - - createServer = function(serverAddr, serverPort, port, key, method, timeout, local_address) { - var getServer, server, udpServer; - if (local_address == null) { - local_address = '127.0.0.1'; - } - udpServer = udpRelay.createServer(local_address, port, serverAddr, serverPort, key, method, timeout, true); - getServer = function() { - var aPort, aServer, r; - aPort = serverPort; - aServer = serverAddr; - if (serverPort instanceof Array) { - aPort = serverPort[Math.floor(Math.random() * serverPort.length)]; - } - if (serverAddr instanceof Array) { - aServer = serverAddr[Math.floor(Math.random() * serverAddr.length)]; - } - r = /^(.*)\:(\d+)$/.exec(aServer); - if (r != null) { - aServer = r[1]; - aPort = +r[2]; - } - return [aServer, aPort]; - }; - server = net.createServer(function(connection) { - var addrLen, addrToSend, clean, connected, encryptor, headerLength, remote, remoteAddr, remotePort, stage; - connections += 1; - connected = true; - encryptor = new Encryptor(key, method); - stage = 0; - headerLength = 0; - remote = null; - addrLen = 0; - remoteAddr = null; - remotePort = null; - addrToSend = ""; - utils.debug("connections: " + connections); - clean = function() { - utils.debug("clean"); - connections -= 1; - remote = null; - connection = null; - encryptor = null; - return utils.debug("connections: " + connections); - }; - connection.on("data", function(data) { - var aPort, aServer, addrToSendBuf, addrtype, buf, cmd, e, piece, reply, tempBuf, _ref; - utils.log(utils.EVERYTHING, "connection on data"); - if (stage === 5) { - data = encryptor.encrypt(data); - if (!remote.write(data)) { - connection.pause(); - } - return; - } - if (stage === 0) { - tempBuf = new Buffer(2); - tempBuf.write("\u0005\u0000", 0); - 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); - utils.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; - } - addrToSend = data.slice(3, 4).toString("binary"); - if (addrtype === 1) { - remoteAddr = utils.inetNtoa(data.slice(4, 8)); - addrToSend += data.slice(4, 10).toString("binary"); - remotePort = data.readUInt16BE(8); - headerLength = 10; - } else if (addrtype === 4) { - remoteAddr = inet.inet_ntop(data.slice(4, 20)); - addrToSend += data.slice(4, 22).toString("binary"); - remotePort = data.readUInt16BE(20); - headerLength = 22; - } else { - remoteAddr = data.slice(5, 5 + addrLen).toString("binary"); - addrToSend += data.slice(4, 5 + addrLen + 2).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); - _ref = getServer(), aServer = _ref[0], aPort = _ref[1]; - utils.info("connecting " + aServer + ":" + aPort); - remote = net.connect(aPort, aServer, function() { - if (remote) { - remote.setNoDelay(true); - } - stage = 5; - return utils.debug("stage = 5"); - }); - remote.on("data", function(data) { - var e; - if (!connected) { - return; - } - utils.log(utils.EVERYTHING, "remote on data"); - try { - if (encryptor) { - data = encryptor.decrypt(data); - if (!connection.write(data)) { - return remote.pause(); - } - } else { - return remote.destroy(); - } - } 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"); - if (connection) { - return connection.resume(); - } - }); - remote.setTimeout(timeout, function() { - utils.debug("remote on timeout"); - if (remote) { - remote.destroy(); - } - if (connection) { - return connection.destroy(); - } - }); - addrToSendBuf = new Buffer(addrToSend, "binary"); - addrToSendBuf = encryptor.encrypt(addrToSendBuf); - remote.setNoDelay(false); - remote.write(addrToSendBuf); - if (data.length > headerLength) { - buf = new Buffer(data.length - headerLength); - data.copy(buf, 0, headerLength); - piece = encryptor.encrypt(buf); - remote.write(piece); - } - stage = 4; - return utils.debug("stage = 4"); - } catch (_error) { - e = _error; - utils.error(e); - if (connection) { - connection.destroy(); - } - if (remote) { - remote.destroy(); - } - return clean(); - } - } else if (stage === 4) { - if (remote == null) { - if (connection) { - connection.destroy(); - } - return; - } - data = encryptor.encrypt(data); - remote.setNoDelay(true); - if (!remote.write(data)) { - return connection.pause(); - } - } - }); - connection.on("end", function() { - connected = false; - 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) { - connected = false; - 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(); - } - }); - }); - if (local_address != null) { - server.listen(port, local_address, function() { - return utils.info("local listening at " + (server.address().address) + ":" + port); - }); - } else { - server.listen(port, function() { - return utils.info("local listening at 0.0.0.0:" + port); - }); - } - server.on("error", function(e) { - if (e.code === "EADDRINUSE") { - return utils.error("Address in use, aborting"); - } else { - return utils.error(e); - } - }); - server.on("close", function() { - return udpServer.close(); - }); - return server; - }; - - exports.createServer = createServer; - - exports.main = function() { - var KEY, METHOD, PORT, REMOTE_PORT, SERVER, config, configContent, configFromArgs, configPath, e, k, local_address, 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); - try { - config = JSON.parse(configContent); - } catch (_error) { - e = _error; - utils.error('found an error in config.json: ' + e.message); - process.exit(1); - } - } else { - config = {}; - } - for (k in configFromArgs) { - v = configFromArgs[k]; - config[k] = v; - } - if (config.verbose) { - utils.config(utils.DEBUG); - } - utils.checkConfig(config); - SERVER = config.server; - REMOTE_PORT = config.server_port; - PORT = config.local_port; - KEY = config.password; - METHOD = config.method; - local_address = config.local_address; - if (!(SERVER && REMOTE_PORT && PORT && KEY)) { - utils.warn('config.json not found, you have to specify all config in commandline'); - process.exit(1); - } - timeout = Math.floor(config.timeout * 1000) || 600000; - s = createServer(SERVER, REMOTE_PORT, PORT, KEY, METHOD, timeout, local_address); - return s.on("error", function(e) { - return process.stdout.on('drain', function() { - return process.exit(1); - }); - }); - }; - - if (require.main === module) { - exports.main(); - } - -}).call(this); diff --git a/lib/shadowsocks/merge_sort.js b/lib/shadowsocks/merge_sort.js deleted file mode 100644 index 87149e5..0000000 --- a/lib/shadowsocks/merge_sort.js +++ /dev/null @@ -1,58 +0,0 @@ -// Generated by CoffeeScript 1.7.1 - -/* - Copyright (c) 2014 clowwindy - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -(function() { - var merge, merge_sort; - - merge = function(left, right, comparison) { - var result; - result = new Array(); - while ((left.length > 0) && (right.length > 0)) { - if (comparison(left[0], right[0]) <= 0) { - result.push(left.shift()); - } else { - result.push(right.shift()); - } - } - while (left.length > 0) { - result.push(left.shift()); - } - while (right.length > 0) { - result.push(right.shift()); - } - return result; - }; - - merge_sort = function(array, comparison) { - var middle; - if (array.length < 2) { - return array; - } - middle = Math.ceil(array.length / 2); - return merge(merge_sort(array.slice(0, middle), comparison), merge_sort(array.slice(middle), comparison), comparison); - }; - - exports.merge_sort = merge_sort; - -}).call(this); diff --git a/lib/shadowsocks/server.js b/lib/shadowsocks/server.js deleted file mode 100644 index d66cff3..0000000 --- a/lib/shadowsocks/server.js +++ /dev/null @@ -1,352 +0,0 @@ -// Generated by CoffeeScript 1.7.1 - -/* - Copyright (c) 2014 clowwindy - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -(function() { - var Encryptor, fs, inet, net, path, udpRelay, utils; - - net = require("net"); - - fs = require("fs"); - - path = require("path"); - - udpRelay = require("./udprelay"); - - utils = require("./utils"); - - inet = require("./inet"); - - Encryptor = require("./encrypt").Encryptor; - - exports.main = function() { - var METHOD, SERVER, a_server_ip, config, configContent, configFromArgs, configPath, connections, e, k, key, port, portPassword, servers, timeout, v, _results; - console.log(utils.version); - configFromArgs = utils.parseArgs(true); - 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); - try { - config = JSON.parse(configContent); - } catch (_error) { - e = _error; - utils.error('found an error in config.json: ' + e.message); - process.exit(1); - } - } else { - config = {}; - } - for (k in configFromArgs) { - v = configFromArgs[k]; - config[k] = v; - } - if (config.verbose) { - utils.config(utils.DEBUG); - } - utils.checkConfig(config); - timeout = Math.floor(config.timeout * 1000) || 300000; - portPassword = config.port_password; - port = config.server_port; - key = config.password; - METHOD = config.method; - SERVER = config.server; - if (!(SERVER && (port || portPassword) && key)) { - utils.warn('config.json not found, you have to specify all config in commandline'); - process.exit(1); - } - connections = 0; - if (portPassword) { - if (port || key) { - utils.warn('warning: port_password should not be used with server_port and password. server_port and password will be ignored'); - } - } else { - portPassword = {}; - portPassword[port.toString()] = key; - } - _results = []; - for (port in portPassword) { - key = portPassword[port]; - servers = SERVER; - if (!(servers instanceof Array)) { - servers = [servers]; - } - _results.push((function() { - var _i, _len, _results1; - _results1 = []; - for (_i = 0, _len = servers.length; _i < _len; _i++) { - a_server_ip = servers[_i]; - _results1.push((function() { - var KEY, PORT, server, server_ip; - PORT = port; - KEY = key; - server_ip = a_server_ip; - utils.info("calculating ciphers for port " + PORT); - server = net.createServer(function(connection) { - var addrLen, cachedPieces, clean, encryptor, headerLength, remote, remoteAddr, remotePort, stage; - connections += 1; - encryptor = new Encryptor(KEY, METHOD); - 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; - encryptor = null; - return utils.debug("connections: " + connections); - }; - connection.on("data", function(data) { - var addrtype, buf; - utils.log(utils.EVERYTHING, "connection on data"); - try { - data = encryptor.decrypt(data); - } catch (_error) { - e = _error; - utils.error(e); - if (remote) { - remote.destroy(); - } - if (connection) { - connection.destroy(); - } - return; - } - if (stage === 5) { - if (!remote.write(data)) { - connection.pause(); - } - return; - } - if (stage === 0) { - try { - addrtype = data[0]; - if (addrtype === void 0) { - return; - } - if (addrtype === 3) { - addrLen = data[1]; - } else if (addrtype !== 1 && addrtype !== 4) { - utils.error("unsupported addrtype: " + addrtype + " maybe wrong password"); - connection.destroy(); - return; - } - if (addrtype === 1) { - remoteAddr = utils.inetNtoa(data.slice(1, 5)); - remotePort = data.readUInt16BE(5); - headerLength = 7; - } else if (addrtype === 4) { - remoteAddr = inet.inet_ntop(data.slice(1, 17)); - remotePort = data.readUInt16BE(17); - headerLength = 19; - } else { - remoteAddr = data.slice(2, 2 + addrLen).toString("binary"); - remotePort = data.readUInt16BE(2 + addrLen); - headerLength = 2 + addrLen + 2; - } - connection.pause(); - remote = net.connect(remotePort, remoteAddr, function() { - var i, piece; - utils.info("connecting " + remoteAddr + ":" + remotePort); - if (!encryptor || !remote || !connection) { - if (remote) { - remote.destroy(); - } - return; - } - i = 0; - connection.resume(); - while (i < cachedPieces.length) { - piece = cachedPieces[i]; - remote.write(piece); - i++; - } - cachedPieces = null; - remote.setTimeout(timeout, function() { - utils.debug("remote on timeout during connect()"); - if (remote) { - remote.destroy(); - } - if (connection) { - return connection.destroy(); - } - }); - stage = 5; - return utils.debug("stage = 5"); - }); - remote.on("data", function(data) { - utils.log(utils.EVERYTHING, "remote on data"); - if (!encryptor) { - if (remote) { - remote.destroy(); - } - return; - } - data = encryptor.encrypt(data); - if (!connection.write(data)) { - return remote.pause(); - } - }); - 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"); - if (connection) { - return connection.resume(); - } - }); - remote.setTimeout(15 * 1000, function() { - utils.debug("remote on timeout during connect()"); - 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); - 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) { - 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, server_ip, function() { - return utils.info("server listening at " + server_ip + ":" + PORT + " "); - }); - udpRelay.createServer(server_ip, PORT, null, null, key, METHOD, timeout, false); - return server.on("error", function(e) { - if (e.code === "EADDRINUSE") { - utils.error("Address in use, aborting"); - } else { - utils.error(e); - } - return process.stdout.on('drain', function() { - return process.exit(1); - }); - }); - })()); - } - return _results1; - })()); - } - return _results; - }; - - if (require.main === module) { - exports.main(); - } - -}).call(this); diff --git a/lib/shadowsocks/test.js b/lib/shadowsocks/test.js deleted file mode 100644 index 346d6ab..0000000 --- a/lib/shadowsocks/test.js +++ /dev/null @@ -1,100 +0,0 @@ -// Generated by CoffeeScript 1.7.1 -(function() { - var child_process, curlRunning, encrypt, i, local, localReady, runCurl, server, serverReady, tables, target; - - encrypt = require("./encrypt"); - - target = [[60, 53, 84, 138, 217, 94, 88, 23, 39, 242, 219, 35, 12, 157, 165, 181, 255, 143, 83, 247, 162, 16, 31, 209, 190, 171, 115, 65, 38, 41, 21, 245, 236, 46, 121, 62, 166, 233, 44, 154, 153, 145, 230, 49, 128, 216, 173, 29, 241, 119, 64, 229, 194, 103, 131, 110, 26, 197, 218, 59, 204, 56, 27, 34, 141, 221, 149, 239, 192, 195, 24, 155, 170, 183, 11, 254, 213, 37, 137, 226, 75, 203, 55, 19, 72, 248, 22, 129, 33, 175, 178, 10, 198, 71, 77, 36, 113, 167, 48, 2, 117, 140, 142, 66, 199, 232, 243, 32, 123, 54, 51, 82, 57, 177, 87, 251, 150, 196, 133, 5, 253, 130, 8, 184, 14, 152, 231, 3, 186, 159, 76, 89, 228, 205, 156, 96, 163, 146, 18, 91, 132, 85, 80, 109, 172, 176, 105, 13, 50, 235, 127, 0, 189, 95, 98, 136, 250, 200, 108, 179, 211, 214, 106, 168, 78, 79, 74, 210, 30, 73, 201, 151, 208, 114, 101, 174, 92, 52, 120, 240, 15, 169, 220, 182, 81, 224, 43, 185, 40, 99, 180, 17, 212, 158, 42, 90, 9, 191, 45, 6, 25, 4, 222, 67, 126, 1, 116, 124, 206, 69, 61, 7, 68, 97, 202, 63, 244, 20, 28, 58, 93, 134, 104, 144, 227, 147, 102, 118, 135, 148, 47, 238, 86, 112, 122, 70, 107, 215, 100, 139, 223, 225, 164, 237, 111, 125, 207, 160, 187, 246, 234, 161, 188, 193, 249, 252], [151, 205, 99, 127, 201, 119, 199, 211, 122, 196, 91, 74, 12, 147, 124, 180, 21, 191, 138, 83, 217, 30, 86, 7, 70, 200, 56, 62, 218, 47, 168, 22, 107, 88, 63, 11, 95, 77, 28, 8, 188, 29, 194, 186, 38, 198, 33, 230, 98, 43, 148, 110, 177, 1, 109, 82, 61, 112, 219, 59, 0, 210, 35, 215, 50, 27, 103, 203, 212, 209, 235, 93, 84, 169, 166, 80, 130, 94, 164, 165, 142, 184, 111, 18, 2, 141, 232, 114, 6, 131, 195, 139, 176, 220, 5, 153, 135, 213, 154, 189, 238, 174, 226, 53, 222, 146, 162, 236, 158, 143, 55, 244, 233, 96, 173, 26, 206, 100, 227, 49, 178, 34, 234, 108, 207, 245, 204, 150, 44, 87, 121, 54, 140, 118, 221, 228, 155, 78, 3, 239, 101, 64, 102, 17, 223, 41, 137, 225, 229, 66, 116, 171, 125, 40, 39, 71, 134, 13, 193, 129, 247, 251, 20, 136, 242, 14, 36, 97, 163, 181, 72, 25, 144, 46, 175, 89, 145, 113, 90, 159, 190, 15, 183, 73, 123, 187, 128, 248, 252, 152, 24, 197, 68, 253, 52, 69, 117, 57, 92, 104, 157, 170, 214, 81, 60, 133, 208, 246, 172, 23, 167, 160, 192, 76, 161, 237, 45, 4, 58, 10, 182, 65, 202, 240, 185, 241, 79, 224, 132, 51, 42, 126, 105, 37, 250, 149, 32, 243, 231, 67, 179, 48, 9, 106, 216, 31, 249, 19, 85, 254, 156, 115, 255, 120, 75, 16]]; - - tables = encrypt.getTable("foobar!"); - - console.log(JSON.stringify(tables)); - - i = 0; - - while (i < 256) { - console.assert(tables[0][i] === target[0][i]); - console.assert(tables[1][i] === target[1][i]); - i++; - } - - child_process = require('child_process'); - - local = child_process.spawn('bin/sslocal', []); - - server = child_process.spawn('bin/ssserver', []); - - curlRunning = false; - - local.on('exit', function(code) { - server.kill(); - if (!curlRunning) { - return process.exit(code); - } - }); - - server.on('exit', function(code) { - local.kill(); - if (!curlRunning) { - return process.exit(code); - } - }); - - localReady = false; - - serverReady = false; - - curlRunning = false; - - runCurl = function() { - var curl; - curlRunning = true; - curl = child_process.spawn('curl', ['-v', 'http://www.example.com/', '-L', '--socks5-hostname', '127.0.0.1:1080']); - curl.on('exit', function(code) { - local.kill(); - server.kill(); - if (code === 0) { - console.log('Test passed'); - return process.exit(0); - } else { - console.error('Test failed'); - return process.exit(code); - } - }); - curl.stdout.on('data', function(data) { - return process.stdout.write(data); - }); - return curl.stderr.on('data', function(data) { - return process.stderr.write(data); - }); - }; - - local.stderr.on('data', function(data) { - return process.stderr.write(data); - }); - - server.stderr.on('data', function(data) { - return process.stderr.write(data); - }); - - local.stdout.on('data', function(data) { - process.stdout.write(data); - if (data.toString().indexOf('listening at') >= 0) { - localReady = true; - if (localReady && serverReady && !curlRunning) { - return runCurl(); - } - } - }); - - server.stdout.on('data', function(data) { - process.stdout.write(data); - if (data.toString().indexOf('listening at') >= 0) { - serverReady = true; - if (localReady && serverReady && !curlRunning) { - return runCurl(); - } - } - }); - -}).call(this); diff --git a/lib/shadowsocks/udprelay.js b/lib/shadowsocks/udprelay.js deleted file mode 100644 index 180bd20..0000000 --- a/lib/shadowsocks/udprelay.js +++ /dev/null @@ -1,271 +0,0 @@ -// Generated by CoffeeScript 1.7.1 - -/* - Copyright (c) 2014 clowwindy - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -(function() { - var LRUCache, decrypt, dgram, encrypt, encryptor, inet, net, parseHeader, utils; - - utils = require('./utils'); - - inet = require('./inet'); - - encryptor = require('./encrypt'); - - dgram = require('dgram'); - - net = require('net'); - - LRUCache = (function() { - function LRUCache(timeout, sweepInterval) { - var sweepFun, that; - this.timeout = timeout; - that = this; - sweepFun = function() { - return that.sweep(); - }; - this.interval = setInterval(sweepFun, sweepInterval); - this.dict = {}; - } - - LRUCache.prototype.setItem = function(key, value) { - var cur; - cur = process.hrtime(); - return this.dict[key] = [value, cur]; - }; - - LRUCache.prototype.getItem = function(key) { - var v; - v = this.dict[key]; - if (v) { - v[1] = process.hrtime(); - return v[0]; - } - return null; - }; - - LRUCache.prototype.delItem = function(key) { - return delete this.dict[key]; - }; - - LRUCache.prototype.destroy = function() { - return clearInterval(this.interval); - }; - - LRUCache.prototype.sweep = function() { - var dict, diff, k, keys, swept, v, v0, _i, _len; - utils.debug("sweeping"); - dict = this.dict; - keys = Object.keys(dict); - swept = 0; - for (_i = 0, _len = keys.length; _i < _len; _i++) { - k = keys[_i]; - v = dict[k]; - diff = process.hrtime(v[1]); - if (diff[0] > this.timeout * 0.001) { - swept += 1; - v0 = v[0]; - v0.close(); - delete dict[k]; - } - } - return utils.debug("" + swept + " keys swept"); - }; - - return LRUCache; - - })(); - - encrypt = function(password, method, data) { - var e; - try { - return encryptor.encryptAll(password, method, 1, data); - } catch (_error) { - e = _error; - utils.error(e); - return null; - } - }; - - decrypt = function(password, method, data) { - var e; - try { - return encryptor.encryptAll(password, method, 0, data); - } catch (_error) { - e = _error; - utils.error(e); - return null; - } - }; - - parseHeader = function(data, requestHeaderOffset) { - var addrLen, addrtype, destAddr, destPort, headerLength; - addrtype = data[requestHeaderOffset]; - if (addrtype === 3) { - addrLen = data[requestHeaderOffset + 1]; - } else if (addrtype !== 1 && addrtype !== 4) { - utils.warn("unsupported addrtype: " + addrtype); - return null; - } - if (addrtype === 1) { - destAddr = utils.inetNtoa(data.slice(requestHeaderOffset + 1, requestHeaderOffset + 5)); - destPort = data.readUInt16BE(requestHeaderOffset + 5); - headerLength = requestHeaderOffset + 7; - } else if (addrtype === 4) { - destAddr = inet.inet_ntop(data.slice(requestHeaderOffset + 1, requestHeaderOffset + 17)); - destPort = data.readUInt16BE(requestHeaderOffset + 17); - headerLength = requestHeaderOffset + 19; - } else { - destAddr = data.slice(requestHeaderOffset + 2, requestHeaderOffset + 2 + addrLen).toString("binary"); - destPort = data.readUInt16BE(requestHeaderOffset + 2 + addrLen); - headerLength = requestHeaderOffset + 2 + addrLen + 2; - } - return [addrtype, destAddr, destPort, headerLength]; - }; - - exports.createServer = function(listenAddr, listenPort, remoteAddr, remotePort, password, method, timeout, isLocal) { - var clientKey, clients, listenIPType, server, udpTypeToListen, udpTypesToListen, _i, _len; - udpTypesToListen = []; - if (listenAddr == null) { - udpTypesToListen = ['udp4', 'udp6']; - } else { - listenIPType = net.isIP(listenAddr); - if (listenIPType === 6) { - udpTypesToListen.push('udp6'); - } else { - udpTypesToListen.push('udp4'); - } - } - for (_i = 0, _len = udpTypesToListen.length; _i < _len; _i++) { - udpTypeToListen = udpTypesToListen[_i]; - server = dgram.createSocket(udpTypeToListen); - clients = new LRUCache(timeout, 10 * 1000); - clientKey = function(localAddr, localPort, destAddr, destPort) { - return "" + localAddr + ":" + localPort + ":" + destAddr + ":" + destPort; - }; - server.on("message", function(data, rinfo) { - var addrtype, client, clientUdpType, dataToSend, destAddr, destPort, frag, headerLength, headerResult, key, requestHeaderOffset, sendDataOffset, serverAddr, serverPort, _ref, _ref1; - requestHeaderOffset = 0; - if (isLocal) { - requestHeaderOffset = 3; - frag = data[2]; - if (frag !== 0) { - utils.debug("frag:" + frag); - utils.warn("drop a message since frag is not 0"); - return; - } - } else { - data = decrypt(password, method, data); - if (data == null) { - return; - } - } - headerResult = parseHeader(data, requestHeaderOffset); - if (headerResult === null) { - return; - } - addrtype = headerResult[0], destAddr = headerResult[1], destPort = headerResult[2], headerLength = headerResult[3]; - if (isLocal) { - sendDataOffset = requestHeaderOffset; - _ref = [remoteAddr, remotePort], serverAddr = _ref[0], serverPort = _ref[1]; - } else { - sendDataOffset = headerLength; - _ref1 = [destAddr, destPort], serverAddr = _ref1[0], serverPort = _ref1[1]; - } - key = clientKey(rinfo.address, rinfo.port, destAddr, destPort); - client = clients.getItem(key); - if (client == null) { - clientUdpType = net.isIP(serverAddr); - if (clientUdpType === 6) { - client = dgram.createSocket("udp6"); - } else { - client = dgram.createSocket("udp4"); - } - clients.setItem(key, client); - client.on("message", function(data1, rinfo1) { - var data2, responseHeader, serverIPBuf, _ref2; - if (!isLocal) { - utils.debug("UDP recv from " + rinfo1.address + ":" + rinfo1.port); - serverIPBuf = utils.inetAton(rinfo1.address); - responseHeader = new Buffer(7); - responseHeader.write('\x01', 0); - serverIPBuf.copy(responseHeader, 1, 0, 4); - responseHeader.writeUInt16BE(rinfo1.port, 5); - data2 = Buffer.concat([responseHeader, data1]); - data2 = encrypt(password, method, data2); - if (data2 == null) { - return; - } - } else { - responseHeader = new Buffer("\x00\x00\x00"); - data1 = decrypt(password, method, data1); - if (data1 == null) { - return; - } - _ref2 = parseHeader(data1, 0), addrtype = _ref2[0], destAddr = _ref2[1], destPort = _ref2[2], headerLength = _ref2[3]; - utils.debug("UDP recv from " + destAddr + ":" + destPort); - data2 = Buffer.concat([responseHeader, data1]); - } - return server.send(data2, 0, data2.length, rinfo.port, rinfo.address, function(err, bytes) { - return utils.debug("remote to local sent"); - }); - }); - client.on("error", function(err) { - return utils.error("UDP client error: " + err); - }); - client.on("close", function() { - utils.debug("UDP client close"); - return clients.delItem(key); - }); - } - utils.debug("pairs: " + (Object.keys(clients.dict).length)); - dataToSend = data.slice(sendDataOffset, data.length); - if (isLocal) { - dataToSend = encrypt(password, method, dataToSend); - if (dataToSend == null) { - return; - } - } - utils.debug("UDP send to " + destAddr + ":" + destPort); - return client.send(dataToSend, 0, dataToSend.length, serverPort, serverAddr, function(err, bytes) { - return utils.debug("local to remote sent"); - }); - }); - server.on("listening", function() { - var address; - address = server.address(); - return utils.info("UDP server listening " + address.address + ":" + address.port); - }); - server.on("close", function() { - utils.info("UDP server closing"); - return clients.destroy(); - }); - if (listenAddr != null) { - server.bind(listenPort, listenAddr); - } else { - server.bind(listenPort); - } - return server; - } - }; - -}).call(this); diff --git a/lib/shadowsocks/utils.js b/lib/shadowsocks/utils.js deleted file mode 100644 index 3cfae44..0000000 --- a/lib/shadowsocks/utils.js +++ /dev/null @@ -1,179 +0,0 @@ -// Generated by CoffeeScript 1.7.1 - -/* - Copyright (c) 2014 clowwindy - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -(function() { - var pack, printLocalHelp, printServerHelp, util, _logging_level; - - util = require('util'); - - pack = require('../../package.json'); - - printLocalHelp = function() { - return console.log("usage: sslocal [-h] -s SERVER_ADDR -p SERVER_PORT [-b LOCAL_ADDR] -l LOCAL_PORT -k PASSWORD -m METHOD [-t TIMEOUT] [-c config]\n\noptional arguments:\n -h, --help show this help message and exit\n -s SERVER_ADDR server address\n -p SERVER_PORT server port\n -b LOCAL_ADDR local binding address, default is 127.0.0.1\n -l LOCAL_PORT local port\n -k PASSWORD password\n -m METHOD encryption method, for example, aes-256-cfb\n -t TIMEOUT timeout in seconds\n -c CONFIG path to config file"); - }; - - printServerHelp = function() { - return console.log("usage: ssserver [-h] -s SERVER_ADDR -p SERVER_PORT -k PASSWORD -m METHOD [-t TIMEOUT] [-c config]\n\noptional arguments:\n -h, --help show this help message and exit\n -s SERVER_ADDR server address\n -p SERVER_PORT server port\n -k PASSWORD password\n -m METHOD encryption method, for example, aes-256-cfb\n -t TIMEOUT timeout in seconds\n -c CONFIG path to config file"); - }; - - exports.parseArgs = function(isServer) { - var defination, lastKey, nextIsValue, oneArg, result, _, _ref; - if (isServer == null) { - isServer = false; - } - defination = { - '-l': 'local_port', - '-p': 'server_port', - '-s': 'server', - '-k': 'password', - '-c': 'config_file', - '-m': 'method', - '-b': 'local_address', - '-t': 'timeout' - }; - result = {}; - nextIsValue = false; - lastKey = null; - _ref = process.argv; - for (_ in _ref) { - oneArg = _ref[_]; - if (nextIsValue) { - result[lastKey] = oneArg; - nextIsValue = false; - } else if (oneArg in defination) { - lastKey = defination[oneArg]; - nextIsValue = true; - } else if ('-v' === oneArg) { - result['verbose'] = true; - } else if (oneArg.indexOf('-') === 0) { - if (isServer) { - printServerHelp(); - } else { - printLocalHelp(); - } - process.exit(2); - } - } - return result; - }; - - exports.checkConfig = function(config) { - var _ref; - if ((_ref = config.server) === '127.0.0.1' || _ref === 'localhost') { - exports.warn("Server is set to " + config.server + ", maybe it's not correct"); - exports.warn("Notice server will listen at " + config.server + ":" + config.server_port); - } - if ((config.method || '').toLowerCase() === 'rc4') { - return exports.warn('RC4 is not safe; please use a safer cipher, like AES-256-CFB'); - } - }; - - exports.version = "" + pack.name + " v" + pack.version; - - exports.EVERYTHING = 0; - - exports.DEBUG = 1; - - exports.INFO = 2; - - exports.WARN = 3; - - exports.ERROR = 4; - - _logging_level = exports.INFO; - - exports.config = function(level) { - return _logging_level = level; - }; - - exports.log = function(level, msg) { - if (level >= _logging_level) { - if (level >= exports.DEBUG) { - return util.log(new Date().getMilliseconds() + 'ms ' + msg); - } else { - return util.log(msg); - } - } - }; - - exports.debug = function(msg) { - return exports.log(exports.DEBUG, msg); - }; - - exports.info = function(msg) { - return exports.log(exports.INFO, msg); - }; - - exports.warn = function(msg) { - return exports.log(exports.WARN, msg); - }; - - exports.error = function(msg) { - return exports.log(exports.ERROR, (msg != null ? msg.stack : void 0) || msg); - }; - - exports.inetNtoa = function(buf) { - return buf[0] + "." + buf[1] + "." + buf[2] + "." + buf[3]; - }; - - exports.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; - } - }; - - setInterval(function() { - var cwd, e, heapdump; - if (_logging_level <= exports.DEBUG) { - exports.debug(JSON.stringify(process.memoryUsage(), ' ', 2)); - if (global.gc) { - exports.debug('GC'); - gc(); - exports.debug(JSON.stringify(process.memoryUsage(), ' ', 2)); - cwd = process.cwd(); - if (_logging_level === exports.DEBUG) { - try { - heapdump = require('heapdump'); - process.chdir('/tmp'); - return process.chdir(cwd); - } catch (_error) { - e = _error; - return exports.debug(e); - } - } - } - } - }, 1000); - -}).call(this); From 2415e6d5fd548683581f283ed4b17cdc5bfa5c11 Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 13:22:04 +0800 Subject: [PATCH 04/10] Convert the inet.js to coffeescript --- src/inet.coffee | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/inet.coffee diff --git a/src/inet.coffee b/src/inet.coffee new file mode 100644 index 0000000..5664b52 --- /dev/null +++ b/src/inet.coffee @@ -0,0 +1,110 @@ +### +// The functions in source file is from phpjs +// https://github.com/kvz/phpjs +// See license below +// +// Copyright (c) 2013 Kevin van Zonneveld (http://kvz.io) +// and Contributors (http://phpjs.org/authors) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +### + +inet_pton = (a) -> + + # http://kevin.vanzonneveld.net + # + original by: Theriault + # * example 1: inet_pton('::'); + # * returns 1: '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' (binary) + # * example 2: inet_pton('127.0.0.1'); + # * returns 2: '\x7F\x00\x00\x01' (binary) + r = undefined + m = undefined + x = undefined + i = undefined + j = undefined + f = String.fromCharCode + m = a.match(/^(?:\d{1,3}(?:\.|$)){4}/) # IPv4 + if m + m = m[0].split(".") + m = f(m[0]) + f(m[1]) + f(m[2]) + f(m[3]) + + # Return if 4 bytes, otherwise false. + return (if m.length is 4 then m else false) + r = /^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})$/ + m = a.match(r) # IPv6 + if m + + # Translate each hexadecimal value. + j = 1 + while j < 4 + + # Indice 2 is :: and if no length, continue. + continue if j is 2 or m[j].length is 0 + m[j] = m[j].split(":") + i = 0 + while i < m[j].length + m[j][i] = parseInt(m[j][i], 16) + + # Would be NaN if it was blank, return false. + return false if isNaN(m[j][i]) # Invalid IP. + m[j][i] = f(m[j][i] >> 8) + f(m[j][i] & 0xFF) + i++ + m[j] = m[j].join("") + j++ + x = m[1].length + m[3].length + if x is 16 + return m[1] + m[3] + else return m[1] + (new Array(16 - x + 1)).join("\u0000") + m[3] if x < 16 and m[2].length > 0 + false # Invalid IP. +inet_ntop = (a) -> + + # http://kevin.vanzonneveld.net + # + original by: Theriault + # * example 1: inet_ntop('\x7F\x00\x00\x01'); + # * returns 1: '127.0.0.1' + # * example 2: inet_ntop('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1'); + # * returns 2: '::1' + i = 0 + m = "" + c = [] + if a.length is 4 # IPv4 + a += "" + [ + a.charCodeAt(0) + a.charCodeAt(1) + a.charCodeAt(2) + a.charCodeAt(3) + ].join "." + else if a.length is 16 # IPv6 + i = 0 + while i < 16 + group = (a.slice(i, i + 2)).toString("hex") + + #replace 00b1 => b1 0000=>0 + group = group.slice(1) while group.length > 1 and group.slice(0, 1) is "0" + c.push group + i += 2 + c.join(":").replace(/((^|:)0(?=:|$))+:?/g, (t) -> + m = (if (t.length > m.length) then t else m) + t + ).replace m or " ", "::" + else # Invalid length + false +exports.inet_pton = inet_pton +exports.inet_ntop = inet_ntop \ No newline at end of file From d7169ce468a197f67b011b0d6fe7cad54ff4e614 Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 13:26:15 +0800 Subject: [PATCH 05/10] Add node 0.8 test. Other configs are not recommended. --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5d7304b..6aeacac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,5 @@ language: node_js node_js: + - "0.8" - "0.10" - "0.11" -before_install: - - npm install coffee-script -script: - - cake build - - cake test From 001a6a39642e1c3003cfcba830d0387910910834 Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 13:26:46 +0800 Subject: [PATCH 06/10] Add windows system test config. --- appveyor.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..5ddaaf5 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,15 @@ +build: false + +environment: + matrix: + - nodejs_version: "0.10" + - nodejs_version: "0.8" + - nodejs_version: "0.11" + +install: + - npm install + +test_script: + - node --version + - npm --version + - npm test From 2f43d3c2177a3ba72320f6436d40cdfbcd8d507b Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 13:30:27 +0800 Subject: [PATCH 07/10] Support automatically `cake build` before `npm publish`, which means you don't have to execute `cake build` any more. --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 6135ed4..d4a3901 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "ssserver": "./bin/ssserver" }, "scripts": { + "preinstall": "npm install -g coffee-script", + "prepublish": "cake build", "test": "cake test" }, "homepage": "https://github.com/clowwindy/shadowsocks-nodejs", From 859b9da347a60417d502a007b7e6d6668cc02586 Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 13:42:34 +0800 Subject: [PATCH 08/10] Use `child_process.spawn` will fail on windows. --- src/test.coffee | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test.coffee b/src/test.coffee index 055841b..4dbfb7d 100644 --- a/src/test.coffee +++ b/src/test.coffee @@ -1,5 +1,7 @@ # test encryption encrypt = require("./encrypt") +spawn = require 'win-spawn' + target = [ [ 60, 53, 84, 138, 217, 94, 88, 23, 39, 242, 219, 35, 12, 157, 165, 181, 255, 143, 83, 247, 162, 16, 31, 209, 190, 171, 115, 65, 38, 41, 21, 245, 236, 46, 121, 62, 166, 233, 44, 154, 153, 145, 230, 49, 128, 216, 173, 29, 241, 119, 64, 229, 194, 103, 131, 110, 26, 197, 218, 59, 204, 56, 27, 34, 141, 221, 149, 239, 192, 195, 24, 155, 170, 183, 11, 254, 213, 37, 137, 226, 75, 203, 55, 19, 72, 248, 22, 129, 33, 175, 178, 10, 198, 71, 77, 36, 113, 167, 48, 2, 117, 140, 142, 66, 199, 232, 243, 32, 123, 54, 51, 82, 57, 177, 87, 251, 150, 196, 133, 5, 253, 130, 8, 184, 14, 152, 231, 3, 186, 159, 76, 89, 228, 205, 156, 96, 163, 146, 18, 91, 132, 85, 80, 109, 172, 176, 105, 13, 50, 235, 127, 0, 189, 95, 98, 136, 250, 200, 108, 179, 211, 214, 106, 168, 78, 79, 74, 210, 30, 73, 201, 151, 208, 114, 101, 174, 92, 52, 120, 240, 15, 169, 220, 182, 81, 224, 43, 185, 40, 99, 180, 17, 212, 158, 42, 90, 9, 191, 45, 6, 25, 4, 222, 67, 126, 1, 116, 124, 206, 69, 61, 7, 68, 97, 202, 63, 244, 20, 28, 58, 93, 134, 104, 144, 227, 147, 102, 118, 135, 148, 47, 238, 86, 112, 122, 70, 107, 215, 100, 139, 223, 225, 164, 237, 111, 125, 207, 160, 187, 246, 234, 161, 188, 193, 249, 252 ], [ 151, 205, 99, 127, 201, 119, 199, 211, 122, 196, 91, 74, 12, 147, 124, 180, 21, 191, 138, 83, 217, 30, 86, 7, 70, 200, 56, 62, 218, 47, 168, 22, 107, 88, 63, 11, 95, 77, 28, 8, 188, 29, 194, 186, 38, 198, 33, 230, 98, 43, 148, 110, 177, 1, 109, 82, 61, 112, 219, 59, 0, 210, 35, 215, 50, 27, 103, 203, 212, 209, 235, 93, 84, 169, 166, 80, 130, 94, 164, 165, 142, 184, 111, 18, 2, 141, 232, 114, 6, 131, 195, 139, 176, 220, 5, 153, 135, 213, 154, 189, 238, 174, 226, 53, 222, 146, 162, 236, 158, 143, 55, 244, 233, 96, 173, 26, 206, 100, 227, 49, 178, 34, 234, 108, 207, 245, 204, 150, 44, 87, 121, 54, 140, 118, 221, 228, 155, 78, 3, 239, 101, 64, 102, 17, 223, 41, 137, 225, 229, 66, 116, 171, 125, 40, 39, 71, 134, 13, 193, 129, 247, 251, 20, 136, 242, 14, 36, 97, 163, 181, 72, 25, 144, 46, 175, 89, 145, 113, 90, 159, 190, 15, 183, 73, 123, 187, 128, 248, 252, 152, 24, 197, 68, 253, 52, 69, 117, 57, 92, 104, 157, 170, 214, 81, 60, 133, 208, 246, 172, 23, 167, 160, 192, 76, 161, 237, 45, 4, 58, 10, 182, 65, 202, 240, 185, 241, 79, 224, 132, 51, 42, 126, 105, 37, 250, 149, 32, 243, 231, 67, 179, 48, 9, 106, 216, 31, 249, 19, 85, 254, 156, 115, 255, 120, 75, 16 ] @@ -15,9 +17,8 @@ while i < 256 # test proxy -child_process = require('child_process') -local = child_process.spawn('bin/sslocal', []) -server = child_process.spawn('bin/ssserver', []) +local = spawn 'bin/sslocal' +server = spawn 'bin/ssserver' curlRunning = false @@ -37,7 +38,7 @@ curlRunning = false runCurl = -> curlRunning = true - curl = child_process.spawn 'curl', ['-v', 'http://www.example.com/', '-L', '--socks5-hostname', '127.0.0.1:1080'] + curl = spawn 'curl', ['-v', 'http://www.example.com/', '-L', '--socks5-hostname', '127.0.0.1:1080'] curl.on 'exit', (code)-> local.kill() server.kill() From a26b5e424461f8441490c60aadc9026f96de23fc Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 17:57:32 +0800 Subject: [PATCH 09/10] The buffer issue of node v0.8 hurts. --- .travis.yml | 1 - appveyor.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6aeacac..0e47d2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: node_js node_js: - - "0.8" - "0.10" - "0.11" diff --git a/appveyor.yml b/appveyor.yml index 5ddaaf5..4212dab 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,6 @@ build: false environment: matrix: - nodejs_version: "0.10" - - nodejs_version: "0.8" - nodejs_version: "0.11" install: From 590732c9d279440a9d16435d83e97d66f451eb1b Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 19 Jun 2014 18:09:05 +0800 Subject: [PATCH 10/10] Do not publish all the files of the project. --- .npmignore | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..7bc4055 --- /dev/null +++ b/.npmignore @@ -0,0 +1,6 @@ +src +test +Cakefile +CONTRIBUTING.md +appveyor.yml +.*