Commit d1c75d99 authored by Max Lv's avatar Max Lv

use nodejs instead

parent 7f73b7b7
// Generated by CoffeeScript 1.3.3
(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);
};
var crypto, int32Max, merge_sort;
crypto = require("crypto");
int32Max = Math.pow(2, 32);
getTable = function(key) {
var ah, al, decrypt_table, hash, i, md5sum, table;
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;
}
return [table, decrypt_table];
};
encrypt = function(table, buf) {
var i;
i = 0;
while (i < buf.length) {
buf[i] = table[buf[i]];
i++;
}
return buf;
};
parseArgs = function() {
var defination, lastKey, nextIsValue, oneArg, result, _, _ref;
defination = {
'-l': 'local_port',
'-p': 'server_port',
'-s': 'server',
'-k': 'password'
};
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;
}
}
return result;
};
var KEY, PORT, REMOTE_PORT, SERVER, config, configContent, configFromArgs, decryptTable, encrypt, encryptTable, fs, getServer, inetAton, inetNtoa, k, net, path, server, tables, timeout, v;
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;
}
};
fs = require("fs");
path = require("path");
configFromArgs = parseArgs();
config = {
"server": "127.0.0.1",
"server_port": 8388,
"local_prot": 1080,
"password": "test",
"timeout": 60
}
for (k in configFromArgs) {
v = configFromArgs[k];
config[k] = v;
}
SERVER = config.server;
REMOTE_PORT = config.server_port;
PORT = config.local_port;
KEY = config.password;
timeout = Math.floor(config.timeout * 1000);
getServer = function() {
if (SERVER instanceof Array) {
return SERVER[Math.floor(Math.random() * SERVER.length)];
} else {
return SERVER;
}
};
net = require("net");
console.log("calculating ciphers");
tables = getTable(KEY);
encryptTable = tables[0];
decryptTable = tables[1];
server = net.createServer(function(connection) {
var addrLen, addrToSend, cachedPieces, headerLength, remote, remoteAddr, remotePort, stage;
console.log("server connected");
console.log("concurrent connections: " + server.connections);
stage = 0;
headerLength = 0;
remote = null;
cachedPieces = [];
addrLen = 0;
remoteAddr = null;
remotePort = null;
addrToSend = "";
connection.on("data", function(data) {
var aServer, addrtype, buf, cmd, reply, tempBuf;
if (stage === 5) {
encrypt(encryptTable, 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;
return;
}
if (stage === 1) {
try {
cmd = data[1];
addrtype = data[3];
if (cmd !== 1) {
console.warn("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) {
console.warn("unsupported addrtype: " + addrtype);
connection.end();
return;
}
addrToSend = data.slice(3, 4).toString("binary");
if (addrtype === 1) {
remoteAddr = inetNtoa(data.slice(4, 8));
addrToSend += data.slice(4, 10).toString("binary");
remotePort = data.readUInt16BE(8);
headerLength = 10;
} 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;
}
buf = new Buffer(10);
buf.write("\u0005\u0000\u0000\u0001", 0, 4, "binary");
buf.write("\u0000\u0000\u0000\u0000", 4, 4, "binary");
buf.writeInt16BE(remotePort, 8);
connection.write(buf);
aServer = getServer();
remote = net.connect(REMOTE_PORT, aServer, function() {
var addrToSendBuf, i, piece;
console.log("connecting " + remoteAddr + " via " + aServer);
addrToSendBuf = new Buffer(addrToSend, "binary");
encrypt(encryptTable, addrToSendBuf);
remote.write(addrToSendBuf);
i = 0;
while (i < cachedPieces.length) {
piece = cachedPieces[i];
encrypt(encryptTable, piece);
remote.write(piece);
i++;
}
cachedPieces = null;
return stage = 5;
});
remote.on("data", function(data) {
encrypt(decryptTable, data);
if (!connection.write(data)) {
return remote.pause();
}
});
remote.on("end", function() {
console.log("remote disconnected");
connection.end();
return console.log("concurrent connections: " + server.connections);
});
remote.on("error", function() {
if (stage === 4) {
console.warn("remote connection refused");
connection.destroy();
return;
}
console.warn("remote error");
connection.end();
return console.log("concurrent connections: " + server.connections);
});
remote.on("drain", function() {
return connection.resume();
});
remote.setTimeout(timeout, function() {
connection.end();
return remote.destroy();
});
if (data.length > headerLength) {
buf = new Buffer(data.length - headerLength);
data.copy(buf, 0, headerLength);
cachedPieces.push(buf);
buf = null;
}
return stage = 4;
} catch (e) {
console.warn(e);
connection.destroy();
if (remote) {
return remote.destroy();
}
}
} else {
if (stage === 4) {
return cachedPieces.push(data);
}
}
});
connection.on("end", function() {
console.log("server disconnected");
if (remote) {
remote.destroy();
}
return console.log("concurrent connections: " + server.connections);
});
connection.on("error", function() {
console.warn("server error");
if (remote) {
remote.destroy();
}
return console.log("concurrent connections: " + server.connections);
});
connection.on("drain", function() {
if (remote && stage === 5) {
return remote.resume();
}
});
return connection.setTimeout(timeout, function() {
if (remote) {
remote.destroy();
}
return connection.destroy();
});
});
var pid = ""+process.pid; // need to turn into a string
fs.writeFile('/data/data/com.github.shadowsocks/shadowsocks.pid', pid, function (err) {
// Ignore
});
server.listen(PORT, function() {
return console.log("server listening at port " + PORT);
});
server.on("error", function(e) {
if (e.code === "EADDRINUSE") {
return console.warn("Address in use, aborting");
}
});
}).call(this);
File added
...@@ -504,9 +504,9 @@ public class Shadowsocks extends PreferenceActivity implements ...@@ -504,9 +504,9 @@ public class Shadowsocks extends PreferenceActivity implements
sb.append("kill -9 `cat /data/data/com.github.shadowsocks/pdnsd.pid`").append("\n"); sb.append("kill -9 `cat /data/data/com.github.shadowsocks/pdnsd.pid`").append("\n");
sb.append("kill -9 `cat /data/data/com.github.shadowsocks/redsocks.pid`").append("\n"); sb.append("kill -9 `cat /data/data/com.github.shadowsocks/redsocks.pid`").append("\n");
sb.append("kill -9 `cat /data/data/com.github.shadowsocks/shadowsocks.pid`").append("\n"); sb.append("kill -9 `cat /data/data/com.github.shadowsocks/shadowsocks.pid`").append("\n");
sb.append("killall pdnsd").append("\n"); sb.append("killall -9 pdnsd").append("\n");
sb.append("killall redsocks").append("\n"); sb.append("killall -9 redsocks").append("\n");
sb.append("killall shadowsocks").append("\n"); sb.append("killall -9 node").append("\n");
Utils.runRootCommand(sb.toString()); Utils.runRootCommand(sb.toString());
copyAssets(""); copyAssets("");
...@@ -514,7 +514,7 @@ public class Shadowsocks extends PreferenceActivity implements ...@@ -514,7 +514,7 @@ public class Shadowsocks extends PreferenceActivity implements
Utils.runCommand("chmod 755 /data/data/com.github.shadowsocks/iptables\n" Utils.runCommand("chmod 755 /data/data/com.github.shadowsocks/iptables\n"
+ "chmod 755 /data/data/com.github.shadowsocks/redsocks\n" + "chmod 755 /data/data/com.github.shadowsocks/redsocks\n"
+ "chmod 755 /data/data/com.github.shadowsocks/pdnsd\n" + "chmod 755 /data/data/com.github.shadowsocks/pdnsd\n"
+ "chmod 755 /data/data/com.github.shadowsocks/shadowsocks\n" + "chmod 755 /data/data/com.github.shadowsocks/node\n"
); );
} }
......
...@@ -79,15 +79,13 @@ public class ShadowsocksService extends Service { ...@@ -79,15 +79,13 @@ public class ShadowsocksService extends Service {
" port = %d;" + " port = %d;" +
" type = socks5;" + " type = socks5;" +
"}"; "}";
final static String SHADOWSOCKS_CONF =
"{\"server\": [%s], \"server_port\": %d, \"local_port\": %d, \"password\": %s, \"timeout\": %d}";
final static String CMD_IPTABLES_RETURN = " -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN\n"; final static String CMD_IPTABLES_RETURN = " -t nat -A OUTPUT -p tcp -d 0.0.0.0 -j RETURN\n";
final static String CMD_IPTABLES_REDIRECT_ADD_HTTP = " -t nat -A OUTPUT -p tcp " final static String CMD_IPTABLES_REDIRECT_ADD_SOCKS = " -t nat -A OUTPUT -p tcp "
+ "--dport 80 -j REDIRECT --to 8123\n"; + "-j REDIRECT --to 8123\n";
final static String CMD_IPTABLES_REDIRECT_ADD_HTTPS = " -t nat -A OUTPUT -p tcp " final static String CMD_IPTABLES_DNAT_ADD_SOCKS = " -t nat -A OUTPUT -p tcp "
+ "--dport 443 -j REDIRECT --to 8124\n"; + "-j DNAT --to-destination 127.0.0.1:8123\n";
final static String CMD_IPTABLES_DNAT_ADD_HTTP = " -t nat -A OUTPUT -p tcp "
+ "--dport 80 -j DNAT --to-destination 127.0.0.1:8123\n";
final static String CMD_IPTABLES_DNAT_ADD_HTTPS = " -t nat -A OUTPUT -p tcp "
+ "--dport 443 -j DNAT --to-destination 127.0.0.1:8124\n";
private static final int MSG_CONNECT_START = 0; private static final int MSG_CONNECT_START = 0;
private static final int MSG_CONNECT_FINISH = 1; private static final int MSG_CONNECT_FINISH = 1;
private static final int MSG_CONNECT_SUCCESS = 2; private static final int MSG_CONNECT_SUCCESS = 2;
...@@ -185,8 +183,8 @@ public class ShadowsocksService extends Service { ...@@ -185,8 +183,8 @@ public class ShadowsocksService extends Service {
} }
public void startShadowsocksDaemon() { public void startShadowsocksDaemon() {
final String cmd = String.format(BASE final String cmd = String.format("nohup " + BASE
+ "shadowsocks \"%s\" \"%d\" \"%d\" \"%s\"", + "node " + BASE + "local.js -s \"%s\" -p \"%d\" -l \"%d\" -k \"%s\" &",
appHost, remotePort, port, sitekey); appHost, remotePort, port, sitekey);
Utils.runRootCommand(cmd); Utils.runRootCommand(cmd);
} }
...@@ -475,6 +473,9 @@ public class ShadowsocksService extends Service { ...@@ -475,6 +473,9 @@ public class ShadowsocksService extends Service {
String cmd_bypass = Utils.getIptables() + CMD_IPTABLES_RETURN; String cmd_bypass = Utils.getIptables() + CMD_IPTABLES_RETURN;
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport " + remotePort)); init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport " + remotePort));
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport " + 53));
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport " + 8153));
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "--dport " + port));
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner "
+ getApplicationInfo().uid)); + getApplicationInfo().uid));
...@@ -488,11 +489,8 @@ public class ShadowsocksService extends Service { ...@@ -488,11 +489,8 @@ public class ShadowsocksService extends Service {
} }
if (isGlobalProxy || isBypassApps) { if (isGlobalProxy || isBypassApps) {
http_sb.append(hasRedirectSupport ? Utils.getIptables() http_sb.append(hasRedirectSupport ? Utils.getIptables()
+ CMD_IPTABLES_REDIRECT_ADD_HTTP : Utils.getIptables() + CMD_IPTABLES_REDIRECT_ADD_SOCKS : Utils.getIptables()
+ CMD_IPTABLES_DNAT_ADD_HTTP); + CMD_IPTABLES_DNAT_ADD_SOCKS);
https_sb.append(hasRedirectSupport ? Utils.getIptables()
+ CMD_IPTABLES_REDIRECT_ADD_HTTPS : Utils.getIptables()
+ CMD_IPTABLES_DNAT_ADD_HTTPS);
} }
if (!isGlobalProxy) { if (!isGlobalProxy) {
// for proxy specified apps // for proxy specified apps
...@@ -508,12 +506,8 @@ public class ShadowsocksService extends Service { ...@@ -508,12 +506,8 @@ public class ShadowsocksService extends Service {
for (int uid : uidSet) { for (int uid : uidSet) {
if (!isBypassApps) { if (!isBypassApps) {
http_sb.append((hasRedirectSupport ? Utils.getIptables() http_sb.append((hasRedirectSupport ? Utils.getIptables()
+ CMD_IPTABLES_REDIRECT_ADD_HTTP : Utils.getIptables() + CMD_IPTABLES_REDIRECT_ADD_SOCKS : Utils.getIptables()
+ CMD_IPTABLES_DNAT_ADD_HTTP).replace("-t nat", + CMD_IPTABLES_DNAT_ADD_SOCKS).replace("-t nat",
"-t nat -m owner --uid-owner " + uid));
https_sb.append((hasRedirectSupport ? Utils.getIptables()
+ CMD_IPTABLES_REDIRECT_ADD_HTTPS : Utils.getIptables()
+ CMD_IPTABLES_DNAT_ADD_HTTPS).replace("-t nat",
"-t nat -m owner --uid-owner " + uid)); "-t nat -m owner --uid-owner " + uid));
} else { } else {
init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + uid)); init_sb.append(cmd_bypass.replace("-d 0.0.0.0", "-m owner --uid-owner " + uid));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment