From 43a6aaad4dda7bddaeda2cc25b4c5d4a3ff6201f Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 3 Nov 2012 03:48:17 -0700 Subject: [PATCH 01/59] use socks5.js in cluse --- socks.js | 382 ++++++++++++++++++++++++++++-------------------------- socks5.js | 92 +++++++++++++ 2 files changed, 287 insertions(+), 187 deletions(-) create mode 100644 socks5.js diff --git a/socks.js b/socks.js index 3daeb5e..8acda17 100644 --- a/socks.js +++ b/socks.js @@ -1,187 +1,195 @@ -var net = require('net'), - util = require('util'), - log = function(args) { - //console.log(args); - }, - info = console.info, - errorLog = console.error, - clients = [], - SOCKS_VERSION = 5, -/* - * Authentication methods - ************************ - * o X'00' NO AUTHENTICATION REQUIRED - * o X'01' GSSAPI - * o X'02' USERNAME/PASSWORD - * o X'03' to X'7F' IANA ASSIGNED - * o X'80' to X'FE' RESERVED FOR PRIVATE METHODS - * o X'FF' NO ACCEPTABLE METHODS - */ - AUTHENTICATION = { - NOAUTH: 0x00, - GSSAPI: 0x01, - USERPASS: 0x02, - NONE: 0xFF - }, -/* - * o CMD - * o CONNECT X'01' - * o BIND X'02' - * o UDP ASSOCIATE X'03' - */ - REQUEST_CMD = { - CONNECT: 0x01, - BIND: 0x02, - UDP_ASSOCIATE: 0x03 - }, -/* - * o ATYP address type of following address - * o IP V4 address: X'01' - * o DOMAINNAME: X'03' - * o IP V6 address: X'04' - */ - ATYP = { - IP_V4: 0x01, - DNS: 0x03, - IP_V6: 0x04 - }, - Address = { - read: function (buffer, offset) { - if (buffer[offset] == ATYP.IP_V4) { - return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); - } else if (buffer[offset] == ATYP.DNS) { - return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); - } else if (buffer[offset] == ATYP.IP_V6) { - return buffer.slice(buffer[offset+1], buffer[offset+1+16]); - } - }, - sizeOf: function(buffer, offset) { - if (buffer[offset] == ATYP.IP_V4) { - return 4; - } else if (buffer[offset] == ATYP.DNS) { - return buffer[offset+1]; - } else if (buffer[offset] == ATYP.IP_V6) { - return 16; - } - } - }; - -function createSocksServer(cb) { - var socksServer = net.createServer(); - socksServer.on('listening', function() { - var address = socksServer.address(); - info('LISTENING %s:%s', address.address, address.port); - }); - socksServer.on('connection', function(socket) { - info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); - initSocksConnection.bind(socket)(cb); - }); - return socksServer; -} -// -// socket is available as this -function initSocksConnection(on_accept) { - // keep log of connected clients - clients.push(this); - - // remove from clients on disconnect - this.on('end', function() { - var idx = clients.indexOf(this); - if (idx != -1) { - clients.splice(idx, 1); - } - }); - this.on('error', function(e) { - errorLog('%j', e); - }); - - // do a handshake - this.handshake = handshake.bind(this); - this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer - this.on('data', this.handshake); -} - -function handshake(chunk) { - this.removeListener('data', this.handshake); - - var method_count = 0; - - // SOCKS Version 5 is the only support version - if (chunk[0] != SOCKS_VERSION) { - errorLog('handshake: wrong socks version: %d', chunk[0]); - this.end(); - } - // Number of authentication methods - method_count = chunk[1]; - - this.auth_methods = []; - // i starts on 1, since we've read chunk 0 & 1 already - for (var i=2; i < method_count + 2; i++) { - this.auth_methods.push(chunk[i]); - } - log('Supported auth methods: %j', this.auth_methods); - - var resp = new Buffer(2); - resp[0] = 0x05; - if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { - log('Handing off to handleRequest'); - this.handleRequest = handleRequest.bind(this); - this.on('data', this.handleRequest); - resp[1] = AUTHENTICATION.NOAUTH; - this.write(resp); - } else { - errorLog('Unsuported authentication method -- disconnecting'); - resp[1] = 0xFF; - this.end(resp); - } -} - -function handleRequest(chunk) { - this.removeListener('data', this.handleRequest); - var cmd=chunk[1], - address, - port, - offset=3; - // Wrong version! - if (chunk[0] !== SOCKS_VERSION) { - this.end('%d%d', 0x05, 0x01); - errorLog('handleRequest: wrong socks version: %d', chunk[0]); - return; - } /* else if (chunk[2] == 0x00) { - this.end(util.format('%d%d', 0x05, 0x01)); - errorLog('handleRequest: Mangled request. Reserved field is not null: %d', chunk[offset]); - return; - } */ - address = Address.read(chunk, 3); - offset = 3 + Address.sizeOf(chunk, 3) + 2; - port = chunk.readUInt16BE(offset); - - log('Request: type: %d -- to: %s:%s', chunk[1], address, port); - - if (cmd == REQUEST_CMD.CONNECT) { - this.request = chunk; - this.on_accept(this, port, address, proxyReady.bind(this)); - } else { - this.end('%d%d', 0x05, 0x01); - return; - } -} - -function proxyReady() { - log('Indicating to the client that the proxy is ready'); - // creating response - var resp = new Buffer(this.request.length); - this.request.copy(resp); - // rewrite response header - resp[0] = SOCKS_VERSION; - resp[1] = 0x00; - resp[2] = 0x00; - this.write(resp); - log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); - - -} - -module.exports = { - createServer: createSocksServer -}; +var net = require('net'), + util = require('util'), + log = function(args) { + //console.log(args); + }, + info = console.info, + errorLog = console.error, + clients = [], + SOCKS_VERSION = 5, +/* + * Authentication methods + ************************ + * o X'00' NO AUTHENTICATION REQUIRED + * o X'01' GSSAPI + * o X'02' USERNAME/PASSWORD + * o X'03' to X'7F' IANA ASSIGNED + * o X'80' to X'FE' RESERVED FOR PRIVATE METHODS + * o X'FF' NO ACCEPTABLE METHODS + */ + AUTHENTICATION = { + NOAUTH: 0x00, + GSSAPI: 0x01, + USERPASS: 0x02, + NONE: 0xFF + }, +/* + * o CMD + * o CONNECT X'01' + * o BIND X'02' + * o UDP ASSOCIATE X'03' + */ + REQUEST_CMD = { + CONNECT: 0x01, + BIND: 0x02, + UDP_ASSOCIATE: 0x03 + }, +/* + * o ATYP address type of following address + * o IP V4 address: X'01' + * o DOMAINNAME: X'03' + * o IP V6 address: X'04' + */ + ATYP = { + IP_V4: 0x01, + DNS: 0x03, + IP_V6: 0x04 + }, + Address = { + read: function (buffer, offset) { + if (buffer[offset] == ATYP.IP_V4) { + return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); + } else if (buffer[offset] == ATYP.DNS) { + return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); + } else if (buffer[offset] == ATYP.IP_V6) { + return buffer.slice(buffer[offset+1], buffer[offset+1+16]); + } + }, + sizeOf: function(buffer, offset) { + if (buffer[offset] == ATYP.IP_V4) { + return 4; + } else if (buffer[offset] == ATYP.DNS) { + return buffer[offset+1]; + } else if (buffer[offset] == ATYP.IP_V6) { + return 16; + } + } + }; + +function createSocksServer(cb) { + var socksServer = net.createServer(); + socksServer.on('listening', function() { + var address = socksServer.address(); + info('LISTENING %s:%s', address.address, address.port); + }); + socksServer.on('connection', function(socket) { + info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); + initSocksConnection.bind(socket)(cb); + + socket.on('error', function(e) { + errorLog(timeout ,'%j', e); + this.end(); + }); + }); + return socksServer; +} +// +// socket is available as this +function initSocksConnection(on_accept) { + // keep log of connected clients + clients.push(this); + + // remove from clients on disconnect + this.on('end', function() { + var idx = clients.indexOf(this); + if (idx != -1) { + clients.splice(idx, 1); + } + }); + this.on('error', function(e) { + errorLog('%j', e); + }); + + // do a handshake + this.handshake = handshake.bind(this); + this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer + this.on('data', this.handshake); +} + +function handshake(chunk) { + this.removeListener('data', this.handshake); + + var method_count = 0; + + // SOCKS Version 5 is the only support version + if (chunk[0] != SOCKS_VERSION) { + errorLog('handshake: wrong socks version: %d', chunk[0]); + this.end(); + } + // Number of authentication methods + method_count = chunk[1]; + + this.auth_methods = []; + // i starts on 1, since we've read chunk 0 & 1 already + for (var i=2; i < method_count + 2; i++) { + this.auth_methods.push(chunk[i]); + } + log('Supported auth methods: %j', this.auth_methods); + + var resp = new Buffer(2); + resp[0] = 0x05; + if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { + log('Handing off to handleRequest'); + this.handleRequest = handleRequest.bind(this); + this.on('data', this.handleRequest); + resp[1] = AUTHENTICATION.NOAUTH; + this.write(resp); + } else { + errorLog('Unsuported authentication method -- disconnecting'); + resp[1] = 0xFF; + this.end(resp); + } +} + +function handleRequest(chunk) { + this.removeListener('data', this.handleRequest); + var cmd=chunk[1], + address, + port, + offset=3; + // Wrong version! + if (chunk[0] !== SOCKS_VERSION) { + this.end('%d%d', 0x05, 0x01); + errorLog('handleRequest: wrong socks version: %d', chunk[0]); + return; + } /* else if (chunk[2] == 0x00) { + this.end(util.format('%d%d', 0x05, 0x01)); + errorLog('handleRequest: Mangled request. Reserved field is not null: %d', chunk[offset]); + return; + } */ + address = Address.read(chunk, 3); + offset = 3 + Address.sizeOf(chunk, 3) + 2; + port = chunk.readUInt16BE(offset); + + log('Request: type: %d -- to: %s:%s', chunk[1], address, port); + + if (cmd == REQUEST_CMD.CONNECT) { + this.request = chunk; + this.on_accept(this, port, address, proxyReady.bind(this)); + } else { + this.end('%d%d', 0x05, 0x01); + return; + } +} + +function proxyReady() { + log('Indicating to the client that the proxy is ready'); + // creating response + var resp = new Buffer(this.request.length); + this.request.copy(resp); + // rewrite response header + resp[0] = SOCKS_VERSION; + resp[1] = 0x00; + resp[2] = 0x00; + this.write(resp); + log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); + this.on('timeout', function(e) { + errorLog('%j', e); + this.end(); + }); + +} + +module.exports = { + createServer: createSocksServer +}; diff --git a/socks5.js b/socks5.js new file mode 100644 index 0000000..2112aa5 --- /dev/null +++ b/socks5.js @@ -0,0 +1,92 @@ + +var net = require('net'), + socks = require('./socks.js'); + +var cluster = require('cluster'); + +var numCPUs = require('os').cpus().length; + +if (cluster.isMaster) { + + // Fork workers. + for (var i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + cluster.on('exit', function(worker, code, signal) { + var exitCode = worker.process.exitCode; + console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); + cluster.fork(); + }); +} else { + // Workers can share any TCP connection + // In this case its a proxy server + +// Create server +// The server accepts SOCKS connections. This particular server acts as a proxy. +var HOST='127.0.0.1', + PORT='8888', + server = socks.createServer(function(socket, port, address, proxy_ready) { + + // Implement your own proxy here! Do encryption, tunnelling, whatever! Go flippin' mental! + // I plan to tunnel everything including SSH over an HTTP tunnel. For now, though, here is the plain proxy: + + console.log('Got through the first part of the SOCKS protocol.') + var proxy = net.createConnection(port, address, proxy_ready); + + proxy.on('data', function(d) { + try { + console.log('receiving ' + d.length + ' bytes from proxy'); + socket.write(d); + } catch(err) { + } + }); + socket.on('data', function(d) { + // If the application tries to send data before the proxy is ready, then that is it's own problem. + try { + console.log('sending ' + d.length + ' bytes to proxy'); + proxy.write(d); + } catch(err) { + } + }); + + proxy.on('close', function(had_error) { + socket.end(); + console.error('The proxy closed'); + }.bind(this)); + socket.on('close', function(had_error) { + if (this.proxy !== undefined) { + proxy.removeAllListeners('data'); + proxy.end(); + } + console.error('The application closed'); + + }.bind(this)); + socket.on('error', function(had_error) { + if (this.proxy !== undefined) { + proxy.removeAllListeners('data'); + proxy.end(); + } + console.error('The application closed'); + + }.bind(this)); + + }); + +server.on('error', function (e) { + console.error('SERVER ERROR: %j', e); + if (e.code == 'EADDRINUSE') { + console.log('Address in use, retrying in 10 seconds...'); + setTimeout(function () { + console.log('Reconnecting to %s:%s', HOST, PORT); + server.close(); + server.listen(PORT, HOST); + }, 10000); + } +}); +server.listen(PORT, HOST); + + +} + + From ac764f9aea89c1d7cc0be3458d470b868e9457db Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 3 Nov 2012 03:57:59 -0700 Subject: [PATCH 02/59] use socks5.js instead of socks --- socks | 60 ----------------------------------------------------------- 1 file changed, 60 deletions(-) delete mode 100755 socks diff --git a/socks b/socks deleted file mode 100755 index 9c46f3a..0000000 --- a/socks +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env node -var net = require('net'), - socks = require('./socks.js'); - -// Create server -// The server accepts SOCKS connections. This particular server acts as a proxy. -var HOST='127.0.0.1', - PORT='8888', - server = socks.createServer(function(socket, port, address, proxy_ready) { - - // Implement your own proxy here! Do encryption, tunnelling, whatever! Go flippin' mental! - // I plan to tunnel everything including SSH over an HTTP tunnel. For now, though, here is the plain proxy: - - console.log('Got through the first part of the SOCKS protocol.') - var proxy = net.createConnection(port, address, proxy_ready); - - proxy.on('data', function(d) { - try { - console.log('receiving ' + d.length + ' bytes from proxy'); - socket.write(d); - } catch(err) { - } - }); - socket.on('data', function(d) { - // If the application tries to send data before the proxy is ready, then that is it's own problem. - try { - console.log('sending ' + d.length + ' bytes to proxy'); - proxy.write(d); - } catch(err) { - } - }); - - proxy.on('close', function(had_error) { - socket.end(); - console.error('The proxy closed'); - }.bind(this)); - socket.on('close', function(had_error) { - if (this.proxy !== undefined) { - proxy.removeAllListeners('data'); - proxy.end(); - } - console.error('The application closed'); - }.bind(this)); - - }); - -server.on('error', function (e) { - console.error('SERVER ERROR: %j', e); - if (e.code == 'EADDRINUSE') { - console.log('Address in use, retrying in 10 seconds...'); - setTimeout(function () { - console.log('Reconnecting to %s:%s', HOST, PORT); - server.close(); - server.listen(PORT, HOST); - }, 10000); - } -}); -server.listen(PORT, HOST); - -// vim: set filetype=javascript syntax=javascript : From 95d9fbd15b95b074aaa65e0bec1f471d09801440 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 3 Nov 2012 18:19:43 -0700 Subject: [PATCH 03/59] Ensure that more than two process --- socks5.js | 1 + 1 file changed, 1 insertion(+) diff --git a/socks5.js b/socks5.js index 2112aa5..db26d54 100644 --- a/socks5.js +++ b/socks5.js @@ -12,6 +12,7 @@ if (cluster.isMaster) { for (var i = 0; i < numCPUs; i++) { cluster.fork(); } +if(1==numCPUs) cluster.fork();//make sure it is more than 2 cluster.on('exit', function(worker, code, signal) { var exitCode = worker.process.exitCode; From 6cb545c4c828a92feb5e6687d15dc63d2161e1a4 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 3 Nov 2012 20:21:22 -0700 Subject: [PATCH 04/59] --- socks5.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/socks5.js b/socks5.js index db26d54..d8e754a 100644 --- a/socks5.js +++ b/socks5.js @@ -17,7 +17,10 @@ if(1==numCPUs) cluster.fork();//make sure it is more than 2 cluster.on('exit', function(worker, code, signal) { var exitCode = worker.process.exitCode; console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); - cluster.fork(); + + exec('taskkill /pid '+worker.process.pid +' /T /F'); +cluster.fork(); + }); } else { // Workers can share any TCP connection @@ -25,7 +28,7 @@ if(1==numCPUs) cluster.fork();//make sure it is more than 2 // Create server // The server accepts SOCKS connections. This particular server acts as a proxy. -var HOST='127.0.0.1', +var HOST='192.168.1.110', PORT='8888', server = socks.createServer(function(socket, port, address, proxy_ready) { From 5f80c6c306f27772e7b7c835334edb17b3c5f951 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 4 Nov 2012 04:00:05 -0800 Subject: [PATCH 05/59] =?UTF-8?q?add=20=E2=80=9C=20uncaughtException=20?= =?UTF-8?q?=E2=80=9D=20catch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- socks5.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/socks5.js b/socks5.js index d8e754a..c8cc463 100644 --- a/socks5.js +++ b/socks5.js @@ -93,4 +93,10 @@ server.listen(PORT, HOST); } +//处理各种错误 +process.on('uncaughtException', function(err) +{ + console.log("\nError!!!!"); + console.log(err); +}); From 85acb0b3bddaf471e98dedad980fd2385d26b962 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 4 Nov 2012 04:07:30 -0800 Subject: [PATCH 06/59] change server.listen(PORT, HOST) to server.listen(PORT); --- socks5.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/socks5.js b/socks5.js index c8cc463..42b216c 100644 --- a/socks5.js +++ b/socks5.js @@ -28,8 +28,7 @@ cluster.fork(); // Create server // The server accepts SOCKS connections. This particular server acts as a proxy. -var HOST='192.168.1.110', - PORT='8888', +var PORT='8888', server = socks.createServer(function(socket, port, address, proxy_ready) { // Implement your own proxy here! Do encryption, tunnelling, whatever! Go flippin' mental! @@ -82,13 +81,13 @@ server.on('error', function (e) { if (e.code == 'EADDRINUSE') { console.log('Address in use, retrying in 10 seconds...'); setTimeout(function () { - console.log('Reconnecting to %s:%s', HOST, PORT); + console.log('Reconnecting to %s',PORT); server.close(); - server.listen(PORT, HOST); + server.listen(PORT); }, 10000); } }); -server.listen(PORT, HOST); +server.listen(PORT); } From d01fd17ce4d1eca8aa2f08911565ee25a2b2cec4 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Mon, 5 Nov 2012 03:02:45 -0800 Subject: [PATCH 07/59] run in windows --- ...\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" | 1 + 1 file changed, 1 insertion(+) create mode 100644 "\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" diff --git "a/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" "b/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" new file mode 100644 index 0000000..af13da8 --- /dev/null +++ "b/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" @@ -0,0 +1 @@ +createobject("wscript.shell").run "cmd /c node socks5",0 From 95bc9aab0097017299d8fd79853157aa05cd88a1 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Mon, 5 Nov 2012 21:17:48 -0800 Subject: [PATCH 08/59] add domain --- socks5.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/socks5.js b/socks5.js index 42b216c..503f9bb 100644 --- a/socks5.js +++ b/socks5.js @@ -1,7 +1,7 @@ var net = require('net'), socks = require('./socks.js'); - +var d = require('domain').create(); var cluster = require('cluster'); var numCPUs = require('os').cpus().length; @@ -36,7 +36,7 @@ var PORT='8888', console.log('Got through the first part of the SOCKS protocol.') var proxy = net.createConnection(port, address, proxy_ready); - + d.add(proxy); proxy.on('data', function(d) { try { console.log('receiving ' + d.length + ' bytes from proxy'); @@ -92,10 +92,10 @@ server.listen(PORT); } -//处理各种错误 -process.on('uncaughtException', function(err) -{ - console.log("\nError!!!!"); - console.log(err); -}); +d.on('error', function(er) { + // an error occurred somewhere. + // if we throw it now, it will crash the program + // with the normal line number and stack message. + console.log('ERROR!: %s ',er); +}); From 3a5c8a869edb8ee3dfa2057ad9de1fde6d2bca37 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Tue, 6 Nov 2012 02:56:32 -0800 Subject: [PATCH 09/59] bug fix --- socks.js | 5 +---- socks5.js | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/socks.js b/socks.js index 8acda17..fe55ea8 100644 --- a/socks.js +++ b/socks.js @@ -183,10 +183,7 @@ function proxyReady() { resp[2] = 0x00; this.write(resp); log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); - this.on('timeout', function(e) { - errorLog('%j', e); - this.end(); - }); + } diff --git a/socks5.js b/socks5.js index 503f9bb..84472aa 100644 --- a/socks5.js +++ b/socks5.js @@ -18,7 +18,7 @@ if(1==numCPUs) cluster.fork();//make sure it is more than 2 var exitCode = worker.process.exitCode; console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); - exec('taskkill /pid '+worker.process.pid +' /T /F'); +// exec('taskkill /pid '+worker.process.pid +' /T /F'); cluster.fork(); }); From d2b77b9cd4d48c1d85c64528fee4ad2b00160a0a Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Tue, 6 Nov 2012 07:16:36 -0800 Subject: [PATCH 10/59] bug fix --- socks5.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/socks5.js b/socks5.js index 84472aa..969ea66 100644 --- a/socks5.js +++ b/socks5.js @@ -36,7 +36,7 @@ var PORT='8888', console.log('Got through the first part of the SOCKS protocol.') var proxy = net.createConnection(port, address, proxy_ready); - d.add(proxy); +// d.add(proxy); proxy.on('data', function(d) { try { console.log('receiving ' + d.length + ' bytes from proxy'); @@ -74,6 +74,11 @@ var PORT='8888', }.bind(this)); + proxy.on('error', function(had_error) { + socket.end(); + console.error('The proxy error'); + }.bind(this)); + }); server.on('error', function (e) { From 06de52a65247a42741d9adeccf76c5f108f183bd Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Wed, 7 Nov 2012 02:58:13 -0800 Subject: [PATCH 11/59] bug fix --- socks.js | 4 ++-- socks5.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/socks.js b/socks.js index fe55ea8..20c9aac 100644 --- a/socks.js +++ b/socks.js @@ -77,7 +77,7 @@ function createSocksServer(cb) { initSocksConnection.bind(socket)(cb); socket.on('error', function(e) { - errorLog(timeout ,'%j', e); + errorLog('error: %j', e); this.end(); }); }); @@ -96,7 +96,7 @@ function initSocksConnection(on_accept) { clients.splice(idx, 1); } }); - this.on('error', function(e) { + this.on('initSocksConnection error', function(e) { errorLog('%j', e); }); diff --git a/socks5.js b/socks5.js index 969ea66..364a305 100644 --- a/socks5.js +++ b/socks5.js @@ -39,7 +39,7 @@ var PORT='8888', // d.add(proxy); proxy.on('data', function(d) { try { - console.log('receiving ' + d.length + ' bytes from proxy'); + // console.log('receiving ' + d.length + ' bytes from proxy'); socket.write(d); } catch(err) { } @@ -47,7 +47,7 @@ var PORT='8888', socket.on('data', function(d) { // If the application tries to send data before the proxy is ready, then that is it's own problem. try { - console.log('sending ' + d.length + ' bytes to proxy'); + // console.log('sending ' + d.length + ' bytes to proxy'); proxy.write(d); } catch(err) { } @@ -70,7 +70,7 @@ var PORT='8888', proxy.removeAllListeners('data'); proxy.end(); } - console.error('The application closed'); + console.error('The application error'); }.bind(this)); From d8089659a12128734208083b59b3218bcdf41222 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 18 Nov 2012 08:31:25 +0800 Subject: [PATCH 12/59] Update README.rst --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index b3af383..f68e20a 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,8 @@ A simple SOCKS implementation and demo proxy in `node.js `_. You can run it easily as:: - ./socks + ./socks5.js +under windows you can run 鏂板缓鏂囨湰鏂囦欢.vbs This will create a proxy at ``127.0.0.1`` on port ``8888``. From 351e7d24358e065fba3e980686a2ae613031ed60 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 18 Nov 2012 08:34:10 +0800 Subject: [PATCH 13/59] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 89d6bec..cf163f9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,3 @@ Gert Van Gool John Cant +sunnyboy00 From d8e5c7d4d48e65f6e963b5bfefe792308d86f32e Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 24 Nov 2012 01:12:57 -0800 Subject: [PATCH 14/59] bug fix of domain --- socks5.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/socks5.js b/socks5.js index 364a305..25296c4 100644 --- a/socks5.js +++ b/socks5.js @@ -6,6 +6,8 @@ var cluster = require('cluster'); var numCPUs = require('os').cpus().length; +d.run(function() { + if (cluster.isMaster) { // Fork workers. @@ -96,6 +98,7 @@ server.listen(PORT); } + }); d.on('error', function(er) { // an error occurred somewhere. From 14af4afece597792a8ae4ba2cb868f7725fd72c3 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 20:05:37 +0800 Subject: [PATCH 15/59] Update socks.js suport socks VERSION 4 --- socks.js | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/socks.js b/socks.js index 20c9aac..76ae195 100644 --- a/socks.js +++ b/socks.js @@ -6,7 +6,8 @@ var net = require('net'), info = console.info, errorLog = console.error, clients = [], - SOCKS_VERSION = 5, + SOCKS_VERSION4 = 4, + SOCKS_VERSION 5= 5, /* * Authentication methods ************************ @@ -111,11 +112,10 @@ function handshake(chunk) { var method_count = 0; - // SOCKS Version 5 is the only support version - if (chunk[0] != SOCKS_VERSION) { - errorLog('handshake: wrong socks version: %d', chunk[0]); - this.end(); - } + // SOCKS Version 4,5 is the only support version + if (chunk[0] == SOCKS_VERSION5) { + + this.SOCKS_VERSION=5; // Number of authentication methods method_count = chunk[1]; @@ -139,6 +139,30 @@ function handshake(chunk) { resp[1] = 0xFF; this.end(resp); } + } + else if(chunk[0] == SOCKS_VERSION4){ + this.SOCKS_VERSION=4 + var cmd=chunk[1], + address, + port; + + + address = Address.read(chunk, 3); + port = chunk.readUInt16BE(2); + + log('Request: type: %d -- to: %s:%s', chunk[1], address, port); + + + this.request = chunk; + this.proxy = net.createConnection(port, address, initProxy.bind(this)); + + + } + else{//other version + errorLog('handshake: wrong socks version: %d', chunk[0]); + this.end(); + } + } function handleRequest(chunk) { @@ -148,7 +172,7 @@ function handleRequest(chunk) { port, offset=3; // Wrong version! - if (chunk[0] !== SOCKS_VERSION) { + if (chunk[0] !== SOCKS_VERSION5) { this.end('%d%d', 0x05, 0x01); errorLog('handleRequest: wrong socks version: %d', chunk[0]); return; @@ -175,16 +199,23 @@ function handleRequest(chunk) { function proxyReady() { log('Indicating to the client that the proxy is ready'); // creating response + if(this.SOCKS_VERSION==5){ var resp = new Buffer(this.request.length); this.request.copy(resp); // rewrite response header - resp[0] = SOCKS_VERSION; + resp[0] = SOCKS_VERSION5; resp[1] = 0x00; resp[2] = 0x00; this.write(resp); log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); - + } + else if(this.SOCKS_VERSION==4){ + var resp = new Buffer(2); + resp[0] = 0x00; + resp[1] = 90; + this.write(resp); + } } module.exports = { From dea278a63e3d922277143a53e6a74a90e91f1a64 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 20:08:39 +0800 Subject: [PATCH 16/59] Update README.rst --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f68e20a..601299f 100644 --- a/README.rst +++ b/README.rst @@ -2,7 +2,8 @@ SOCKS implementation in node.js =============================== A simple SOCKS implementation and demo proxy in `node.js `_. - + +It suports both socks5 and socks4. You can run it easily as:: ./socks5.js From b08ef13d9fddac2f9304281a4c349f5c132661c7 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 20:10:12 +0800 Subject: [PATCH 17/59] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 601299f..e563814 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,7 @@ SOCKS implementation in node.js A simple SOCKS implementation and demo proxy in `node.js `_. -It suports both socks5 and socks4. +It supports both socks5 and socks4. You can run it easily as:: ./socks5.js From 64f407925d954cd612a6deb3c40451b10b9a2b9b Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 20:15:38 +0800 Subject: [PATCH 18/59] Update socks.js --- socks.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/socks.js b/socks.js index 76ae195..20ddd1c 100644 --- a/socks.js +++ b/socks.js @@ -7,7 +7,7 @@ var net = require('net'), errorLog = console.error, clients = [], SOCKS_VERSION4 = 4, - SOCKS_VERSION 5= 5, + SOCKS_VERSION5= 5, /* * Authentication methods ************************ @@ -141,7 +141,7 @@ function handshake(chunk) { } } else if(chunk[0] == SOCKS_VERSION4){ - this.SOCKS_VERSION=4 + this.SOCKS_VERSION=4; var cmd=chunk[1], address, port; @@ -154,7 +154,7 @@ function handshake(chunk) { this.request = chunk; - this.proxy = net.createConnection(port, address, initProxy.bind(this)); + this.proxy = net.createConnection(port, address, proxyReady.bind(this)); } From 991e23f23778ac8ab410cf5e0068657a8f05aa1c Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 21:18:09 +0800 Subject: [PATCH 19/59] Update socks.js --- socks.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/socks.js b/socks.js index 20ddd1c..6a68262 100644 --- a/socks.js +++ b/socks.js @@ -153,10 +153,13 @@ function handshake(chunk) { log('Request: type: %d -- to: %s:%s', chunk[1], address, port); - this.request = chunk; + this.proxy = net.createConnection(port, address, proxyReady.bind(this)); - + this.proxy.on('error', function(had_error) { + this.end(); + console.error('The proxy error'); + }); } else{//other version errorLog('handshake: wrong socks version: %d', chunk[0]); @@ -212,7 +215,7 @@ function proxyReady() { } else if(this.SOCKS_VERSION==4){ var resp = new Buffer(2); - resp[0] = 0x00; + resp[0] = 0; resp[1] = 90; this.write(resp); } From 79377a6da0b2948629f9b6c4ccdd59217ed51b16 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 17:44:41 -0800 Subject: [PATCH 20/59] --- socks.js | 326 +++++++++++++++++++++++++------------------------------ 1 file changed, 146 insertions(+), 180 deletions(-) diff --git a/socks.js b/socks.js index 6a68262..44a5069 100644 --- a/socks.js +++ b/socks.js @@ -1,13 +1,12 @@ var net = require('net'), - util = require('util'), - log = function(args) { - //console.log(args); - }, - info = console.info, - errorLog = console.error, - clients = [], - SOCKS_VERSION4 = 4, - SOCKS_VERSION5= 5, +????util = require('util'), +????log = function(args) { +????????//console.log(args); +????}, +????info = console.info, +????errorLog = console.error, +????clients = [], +????SOCKS_VERSION = 5, /* * Authentication methods ************************ @@ -18,209 +17,176 @@ var net = require('net'), * o X'80' to X'FE' RESERVED FOR PRIVATE METHODS * o X'FF' NO ACCEPTABLE METHODS */ - AUTHENTICATION = { - NOAUTH: 0x00, - GSSAPI: 0x01, - USERPASS: 0x02, - NONE: 0xFF - }, +????AUTHENTICATION = { +????????NOAUTH: 0x00, +????????GSSAPI: 0x01, +????????USERPASS: 0x02, +????????NONE: 0xFF +????}, /* * o CMD * o CONNECT X'01' * o BIND X'02' * o UDP ASSOCIATE X'03' */ - REQUEST_CMD = { - CONNECT: 0x01, - BIND: 0x02, - UDP_ASSOCIATE: 0x03 - }, +????REQUEST_CMD = { +????????CONNECT: 0x01, +????????BIND: 0x02, +????????UDP_ASSOCIATE: 0x03 +????}, /* * o ATYP address type of following address * o IP V4 address: X'01' * o DOMAINNAME: X'03' * o IP V6 address: X'04' */ - ATYP = { - IP_V4: 0x01, - DNS: 0x03, - IP_V6: 0x04 - }, - Address = { - read: function (buffer, offset) { - if (buffer[offset] == ATYP.IP_V4) { - return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); - } else if (buffer[offset] == ATYP.DNS) { - return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); - } else if (buffer[offset] == ATYP.IP_V6) { - return buffer.slice(buffer[offset+1], buffer[offset+1+16]); - } - }, - sizeOf: function(buffer, offset) { - if (buffer[offset] == ATYP.IP_V4) { - return 4; - } else if (buffer[offset] == ATYP.DNS) { - return buffer[offset+1]; - } else if (buffer[offset] == ATYP.IP_V6) { - return 16; - } - } - }; +????ATYP = { +????????IP_V4: 0x01, +????????DNS: 0x03, +????????IP_V6: 0x04 +????}, +????Address = { +????????read: function (buffer, offset) { +??????????????????if (buffer[offset] == ATYP.IP_V4) { +??????????????????????return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); +??????????????????} else if (buffer[offset] == ATYP.DNS) { +??????????????????????return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); +??????????????????} else if (buffer[offset] == ATYP.IP_V6) { +??????????????????????return buffer.slice(buffer[offset+1], buffer[offset+1+16]); +??????????????????} +??????????????}, +????????sizeOf: function(buffer, offset) { +????????????????????if (buffer[offset] == ATYP.IP_V4) { +????????????????????????return 4; +????????????????????} else if (buffer[offset] == ATYP.DNS) { +????????????????????????return buffer[offset+1]; +????????????????????} else if (buffer[offset] == ATYP.IP_V6) { +????????????????????????return 16; +????????????????????} +????????????????} +????}; function createSocksServer(cb) { - var socksServer = net.createServer(); - socksServer.on('listening', function() { - var address = socksServer.address(); - info('LISTENING %s:%s', address.address, address.port); - }); - socksServer.on('connection', function(socket) { - info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); - initSocksConnection.bind(socket)(cb); - - socket.on('error', function(e) { - errorLog('error: %j', e); +????var socksServer = net.createServer(); +????socksServer.on('listening', function() { +????????var address = socksServer.address(); +????????info('LISTENING %s:%s', address.address, address.port); +????}); +????socksServer.on('connection', function(socket) { +????????info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); +????????initSocksConnection.bind(socket)(cb); + +????socket.on('error', function(e) { +????????errorLog('error: %j', e); this.end(); - }); - }); - return socksServer; +????}); +????}); +????return socksServer; } // // socket is available as this function initSocksConnection(on_accept) { - // keep log of connected clients - clients.push(this); - - // remove from clients on disconnect - this.on('end', function() { - var idx = clients.indexOf(this); - if (idx != -1) { - clients.splice(idx, 1); - } - }); - this.on('initSocksConnection error', function(e) { - errorLog('%j', e); - }); - - // do a handshake - this.handshake = handshake.bind(this); - this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer - this.on('data', this.handshake); +????// keep log of connected clients +????clients.push(this); + +????// remove from clients on disconnect +????this.on('end', function() { +????????var idx = clients.indexOf(this); +????????if (idx != -1) { +????????????clients.splice(idx, 1); +????????} +????}); +????this.on('initSocksConnection error', function(e) { +????????errorLog('%j', e); +????}); + +????// do a handshake +????this.handshake = handshake.bind(this); +????this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer +????this.on('data', this.handshake); } function handshake(chunk) { - this.removeListener('data', this.handshake); - - var method_count = 0; - - // SOCKS Version 4,5 is the only support version - if (chunk[0] == SOCKS_VERSION5) { - - this.SOCKS_VERSION=5; - // Number of authentication methods - method_count = chunk[1]; - - this.auth_methods = []; - // i starts on 1, since we've read chunk 0 & 1 already - for (var i=2; i < method_count + 2; i++) { - this.auth_methods.push(chunk[i]); - } - log('Supported auth methods: %j', this.auth_methods); - - var resp = new Buffer(2); - resp[0] = 0x05; - if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { - log('Handing off to handleRequest'); - this.handleRequest = handleRequest.bind(this); - this.on('data', this.handleRequest); - resp[1] = AUTHENTICATION.NOAUTH; - this.write(resp); - } else { - errorLog('Unsuported authentication method -- disconnecting'); - resp[1] = 0xFF; - this.end(resp); - } - } - else if(chunk[0] == SOCKS_VERSION4){ - this.SOCKS_VERSION=4; - var cmd=chunk[1], - address, - port; - - - address = Address.read(chunk, 3); - port = chunk.readUInt16BE(2); - - log('Request: type: %d -- to: %s:%s', chunk[1], address, port); - - - - this.proxy = net.createConnection(port, address, proxyReady.bind(this)); - - this.proxy.on('error', function(had_error) { - this.end(); - console.error('The proxy error'); - }); - } - else{//other version - errorLog('handshake: wrong socks version: %d', chunk[0]); - this.end(); - } - +????this.removeListener('data', this.handshake); + +????var method_count = 0; + +????// SOCKS Version 5 is the only support version +????if (chunk[0] != SOCKS_VERSION) { +????????errorLog('handshake: wrong socks version: %d', chunk[0]); +????????this.end(); +????} +????// Number of authentication methods +????method_count = chunk[1]; + +????this.auth_methods = []; +????// i starts on 1, since we've read chunk 0 & 1 already +????for (var i=2; i < method_count + 2; i++) { +????????this.auth_methods.push(chunk[i]); +????} +????log('Supported auth methods: %j', this.auth_methods); + +????var resp = new Buffer(2); +????resp[0] = 0x05; +????if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { +????????log('Handing off to handleRequest'); +????????this.handleRequest = handleRequest.bind(this); +????????this.on('data', this.handleRequest); +????????resp[1] = AUTHENTICATION.NOAUTH; +????????this.write(resp); +????} else { +????????errorLog('Unsuported authentication method -- disconnecting'); +????????resp[1] = 0xFF; +????????this.end(resp); +????} } function handleRequest(chunk) { - this.removeListener('data', this.handleRequest); - var cmd=chunk[1], - address, - port, - offset=3; - // Wrong version! - if (chunk[0] !== SOCKS_VERSION5) { - this.end('%d%d', 0x05, 0x01); - errorLog('handleRequest: wrong socks version: %d', chunk[0]); - return; - } /* else if (chunk[2] == 0x00) { +????this.removeListener('data', this.handleRequest); +????var cmd=chunk[1], +????????address, +????????port, +????????offset=3; +????// Wrong version! +????if (chunk[0] !== SOCKS_VERSION) { +????????this.end('%d%d', 0x05, 0x01); +????????errorLog('handleRequest: wrong socks version: %d', chunk[0]); +????????return; +????} /* else if (chunk[2] == 0x00) { this.end(util.format('%d%d', 0x05, 0x01)); errorLog('handleRequest: Mangled request. Reserved field is not null: %d', chunk[offset]); return; } */ - address = Address.read(chunk, 3); - offset = 3 + Address.sizeOf(chunk, 3) + 2; - port = chunk.readUInt16BE(offset); - - log('Request: type: %d -- to: %s:%s', chunk[1], address, port); - - if (cmd == REQUEST_CMD.CONNECT) { - this.request = chunk; - this.on_accept(this, port, address, proxyReady.bind(this)); - } else { - this.end('%d%d', 0x05, 0x01); - return; - } +????address = Address.read(chunk, 3); +????offset = 3 + Address.sizeOf(chunk, 3) + 2; +????port = chunk.readUInt16BE(offset); + +????log('Request: type: %d -- to: %s:%s', chunk[1], address, port); + +????if (cmd == REQUEST_CMD.CONNECT) { +????????this.request = chunk; +????????this.on_accept(this, port, address, proxyReady.bind(this)); +????} else { +????????this.end('%d%d', 0x05, 0x01); +????????return; +????} } function proxyReady() { - log('Indicating to the client that the proxy is ready'); - // creating response - if(this.SOCKS_VERSION==5){ - var resp = new Buffer(this.request.length); - this.request.copy(resp); - // rewrite response header - resp[0] = SOCKS_VERSION5; - resp[1] = 0x00; - resp[2] = 0x00; - this.write(resp); - log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); - - } - else if(this.SOCKS_VERSION==4){ - var resp = new Buffer(2); - resp[0] = 0; - resp[1] = 90; - this.write(resp); - } +????log('Indicating to the client that the proxy is ready'); +????// creating response +????var resp = new Buffer(this.request.length); +????this.request.copy(resp); +????// rewrite response header +????resp[0] = SOCKS_VERSION; +????resp[1] = 0x00; +????resp[2] = 0x00; +????this.write(resp); +????log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); +??? + } module.exports = { - createServer: createSocksServer -}; +????createServer: createSocksServer +}; \ No newline at end of file From b9dd286835957c61b4c17e4efd776fcb36833f6f Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 18:59:03 -0800 Subject: [PATCH 21/59] --- ...273\272\346\226\207\346\234\254\346\226\207\346\241\243.bat" | 2 ++ ...273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 "\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.bat" delete mode 100644 "\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" diff --git "a/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.bat" "b/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.bat" new file mode 100644 index 0000000..c514645 --- /dev/null +++ "b/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.bat" @@ -0,0 +1,2 @@ +node socksproxy5.js +pause diff --git "a/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" "b/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" deleted file mode 100644 index af13da8..0000000 --- "a/\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.vbs" +++ /dev/null @@ -1 +0,0 @@ -createobject("wscript.shell").run "cmd /c node socks5",0 From bca289bdcc43382ab62c12f27de2cc64686aa75a Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 19:04:45 -0800 Subject: [PATCH 22/59] rename socks.js socks5.js --- socks5.js | 296 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 187 insertions(+), 109 deletions(-) diff --git a/socks5.js b/socks5.js index 25296c4..3daeb5e 100644 --- a/socks5.js +++ b/socks5.js @@ -1,109 +1,187 @@ - -var net = require('net'), - socks = require('./socks.js'); -var d = require('domain').create(); -var cluster = require('cluster'); - -var numCPUs = require('os').cpus().length; - -d.run(function() { - -if (cluster.isMaster) { - - // Fork workers. - for (var i = 0; i < numCPUs; i++) { - cluster.fork(); - } -if(1==numCPUs) cluster.fork();//make sure it is more than 2 - - cluster.on('exit', function(worker, code, signal) { - var exitCode = worker.process.exitCode; - console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); - -// exec('taskkill /pid '+worker.process.pid +' /T /F'); -cluster.fork(); - - }); -} else { - // Workers can share any TCP connection - // In this case its a proxy server - -// Create server -// The server accepts SOCKS connections. This particular server acts as a proxy. -var PORT='8888', - server = socks.createServer(function(socket, port, address, proxy_ready) { - - // Implement your own proxy here! Do encryption, tunnelling, whatever! Go flippin' mental! - // I plan to tunnel everything including SSH over an HTTP tunnel. For now, though, here is the plain proxy: - - console.log('Got through the first part of the SOCKS protocol.') - var proxy = net.createConnection(port, address, proxy_ready); -// d.add(proxy); - proxy.on('data', function(d) { - try { - // console.log('receiving ' + d.length + ' bytes from proxy'); - socket.write(d); - } catch(err) { - } - }); - socket.on('data', function(d) { - // If the application tries to send data before the proxy is ready, then that is it's own problem. - try { - // console.log('sending ' + d.length + ' bytes to proxy'); - proxy.write(d); - } catch(err) { - } - }); - - proxy.on('close', function(had_error) { - socket.end(); - console.error('The proxy closed'); - }.bind(this)); - socket.on('close', function(had_error) { - if (this.proxy !== undefined) { - proxy.removeAllListeners('data'); - proxy.end(); - } - console.error('The application closed'); - - }.bind(this)); - socket.on('error', function(had_error) { - if (this.proxy !== undefined) { - proxy.removeAllListeners('data'); - proxy.end(); - } - console.error('The application error'); - - }.bind(this)); - - proxy.on('error', function(had_error) { - socket.end(); - console.error('The proxy error'); - }.bind(this)); - - }); - -server.on('error', function (e) { - console.error('SERVER ERROR: %j', e); - if (e.code == 'EADDRINUSE') { - console.log('Address in use, retrying in 10 seconds...'); - setTimeout(function () { - console.log('Reconnecting to %s',PORT); - server.close(); - server.listen(PORT); - }, 10000); - } -}); -server.listen(PORT); - - -} - }); - -d.on('error', function(er) { - // an error occurred somewhere. - // if we throw it now, it will crash the program - // with the normal line number and stack message. - console.log('ERROR!: %s ',er); - -}); +var net = require('net'), + util = require('util'), + log = function(args) { + //console.log(args); + }, + info = console.info, + errorLog = console.error, + clients = [], + SOCKS_VERSION = 5, +/* + * Authentication methods + ************************ + * o X'00' NO AUTHENTICATION REQUIRED + * o X'01' GSSAPI + * o X'02' USERNAME/PASSWORD + * o X'03' to X'7F' IANA ASSIGNED + * o X'80' to X'FE' RESERVED FOR PRIVATE METHODS + * o X'FF' NO ACCEPTABLE METHODS + */ + AUTHENTICATION = { + NOAUTH: 0x00, + GSSAPI: 0x01, + USERPASS: 0x02, + NONE: 0xFF + }, +/* + * o CMD + * o CONNECT X'01' + * o BIND X'02' + * o UDP ASSOCIATE X'03' + */ + REQUEST_CMD = { + CONNECT: 0x01, + BIND: 0x02, + UDP_ASSOCIATE: 0x03 + }, +/* + * o ATYP address type of following address + * o IP V4 address: X'01' + * o DOMAINNAME: X'03' + * o IP V6 address: X'04' + */ + ATYP = { + IP_V4: 0x01, + DNS: 0x03, + IP_V6: 0x04 + }, + Address = { + read: function (buffer, offset) { + if (buffer[offset] == ATYP.IP_V4) { + return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); + } else if (buffer[offset] == ATYP.DNS) { + return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); + } else if (buffer[offset] == ATYP.IP_V6) { + return buffer.slice(buffer[offset+1], buffer[offset+1+16]); + } + }, + sizeOf: function(buffer, offset) { + if (buffer[offset] == ATYP.IP_V4) { + return 4; + } else if (buffer[offset] == ATYP.DNS) { + return buffer[offset+1]; + } else if (buffer[offset] == ATYP.IP_V6) { + return 16; + } + } + }; + +function createSocksServer(cb) { + var socksServer = net.createServer(); + socksServer.on('listening', function() { + var address = socksServer.address(); + info('LISTENING %s:%s', address.address, address.port); + }); + socksServer.on('connection', function(socket) { + info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); + initSocksConnection.bind(socket)(cb); + }); + return socksServer; +} +// +// socket is available as this +function initSocksConnection(on_accept) { + // keep log of connected clients + clients.push(this); + + // remove from clients on disconnect + this.on('end', function() { + var idx = clients.indexOf(this); + if (idx != -1) { + clients.splice(idx, 1); + } + }); + this.on('error', function(e) { + errorLog('%j', e); + }); + + // do a handshake + this.handshake = handshake.bind(this); + this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer + this.on('data', this.handshake); +} + +function handshake(chunk) { + this.removeListener('data', this.handshake); + + var method_count = 0; + + // SOCKS Version 5 is the only support version + if (chunk[0] != SOCKS_VERSION) { + errorLog('handshake: wrong socks version: %d', chunk[0]); + this.end(); + } + // Number of authentication methods + method_count = chunk[1]; + + this.auth_methods = []; + // i starts on 1, since we've read chunk 0 & 1 already + for (var i=2; i < method_count + 2; i++) { + this.auth_methods.push(chunk[i]); + } + log('Supported auth methods: %j', this.auth_methods); + + var resp = new Buffer(2); + resp[0] = 0x05; + if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { + log('Handing off to handleRequest'); + this.handleRequest = handleRequest.bind(this); + this.on('data', this.handleRequest); + resp[1] = AUTHENTICATION.NOAUTH; + this.write(resp); + } else { + errorLog('Unsuported authentication method -- disconnecting'); + resp[1] = 0xFF; + this.end(resp); + } +} + +function handleRequest(chunk) { + this.removeListener('data', this.handleRequest); + var cmd=chunk[1], + address, + port, + offset=3; + // Wrong version! + if (chunk[0] !== SOCKS_VERSION) { + this.end('%d%d', 0x05, 0x01); + errorLog('handleRequest: wrong socks version: %d', chunk[0]); + return; + } /* else if (chunk[2] == 0x00) { + this.end(util.format('%d%d', 0x05, 0x01)); + errorLog('handleRequest: Mangled request. Reserved field is not null: %d', chunk[offset]); + return; + } */ + address = Address.read(chunk, 3); + offset = 3 + Address.sizeOf(chunk, 3) + 2; + port = chunk.readUInt16BE(offset); + + log('Request: type: %d -- to: %s:%s', chunk[1], address, port); + + if (cmd == REQUEST_CMD.CONNECT) { + this.request = chunk; + this.on_accept(this, port, address, proxyReady.bind(this)); + } else { + this.end('%d%d', 0x05, 0x01); + return; + } +} + +function proxyReady() { + log('Indicating to the client that the proxy is ready'); + // creating response + var resp = new Buffer(this.request.length); + this.request.copy(resp); + // rewrite response header + resp[0] = SOCKS_VERSION; + resp[1] = 0x00; + resp[2] = 0x00; + this.write(resp); + log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); + + +} + +module.exports = { + createServer: createSocksServer +}; From 50a88b0aa24e1ea06d47fbe9e0b17057742925f4 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 19:06:02 -0800 Subject: [PATCH 23/59] --- socksproxy4.js | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 socksproxy4.js diff --git a/socksproxy4.js b/socksproxy4.js new file mode 100644 index 0000000..16ba2ce --- /dev/null +++ b/socksproxy4.js @@ -0,0 +1,58 @@ + +var net = require('net'), + socks4 = require('./socks4.js'); + +var d = require('domain').create(); +var cluster = require('cluster'); + +var numCPUs = require('os').cpus().length; + +d.run(function() { + +if (cluster.isMaster) { + + // Fork workers. + for (var i = 0; i < numCPUs; i++) { + cluster.fork(); + } +if(1==numCPUs) cluster.fork();//make sure it is more than 2 + + cluster.on('exit', function(worker, code, signal) { + var exitCode = worker.process.exitCode; + console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); + +// exec('taskkill /pid '+worker.process.pid +' /T /F'); +cluster.fork(); + + }); +} else { + // Workers can share any TCP connection + // In this case its a proxy server + +// Create server +// The server accepts SOCKS connections. This particular server acts as a proxy. +var PORT4='9999', +server4 = socks4.createServer(); +server4.on('error', function (e) { + console.error('SERVER ERROR: %j', e); + if (e.code == 'EADDRINUSE') { + console.log('Address in use, retrying in 10 seconds...'); + setTimeout(function () { + console.log('Reconnecting to %s',PORT); + server.close(); + server.listen(PORT4); + }, 10000); + } +}); +server4.listen(PORT4); + +} + }); + +d.on('error', function(er) { + // an error occurred somewhere. + // if we throw it now, it will crash the program + // with the normal line number and stack message. + console.log('ERROR!: %s ',er); + +}); From 1159c6dd43a4d0bffed0b1a72d67ecffab240290 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 19:06:18 -0800 Subject: [PATCH 24/59] --- socksproxy5.js | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 socksproxy5.js diff --git a/socksproxy5.js b/socksproxy5.js new file mode 100644 index 0000000..de8848e --- /dev/null +++ b/socksproxy5.js @@ -0,0 +1,109 @@ + +var net = require('net'), + socks5 = require('./socks5.js'); + +var d = require('domain').create(); +var cluster = require('cluster'); + +var numCPUs = require('os').cpus().length; + +d.run(function() { + +if (cluster.isMaster) { + + // Fork workers. + for (var i = 0; i < numCPUs; i++) { + cluster.fork(); + } +if(1==numCPUs) cluster.fork();//make sure it is more than 2 + + cluster.on('exit', function(worker, code, signal) { + var exitCode = worker.process.exitCode; + console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); + +// exec('taskkill /pid '+worker.process.pid +' /T /F'); +cluster.fork(); + + }); +} else { + // Workers can share any TCP connection + // In this case its a proxy server + +// Create server +// The server accepts SOCKS connections. This particular server acts as a proxy. +var PORT5='8888', + server5 = socks5.createServer(function(socket, port, address, proxy_ready) { + + // Implement your own proxy here! Do encryption, tunnelling, whatever! Go flippin' mental! + // I plan to tunnel everything including SSH over an HTTP tunnel. For now, though, here is the plain proxy: + + console.log('Got through the first part of the SOCKS protocol.') + var proxy = net.createConnection(port, address, proxy_ready); +// d.add(proxy); + proxy.on('data', function(d) { + try { + // console.log('receiving ' + d.length + ' bytes from proxy'); + socket.write(d); + } catch(err) { + } + }); + socket.on('data', function(d) { + // If the application tries to send data before the proxy is ready, then that is it's own problem. + try { + // console.log('sending ' + d.length + ' bytes to proxy'); + proxy.write(d); + } catch(err) { + } + }); + + proxy.on('close', function(had_error) { + socket.end(); + console.error('The proxy closed'); + }.bind(this)); + socket.on('close', function(had_error) { + if (this.proxy !== undefined) { + proxy.removeAllListeners('data'); + proxy.end(); + } + console.error('The application closed'); + + }.bind(this)); + socket.on('error', function(had_error) { + if (this.proxy !== undefined) { + proxy.removeAllListeners('data'); + proxy.end(); + } + console.error('The application error'); + + }.bind(this)); + + proxy.on('error', function(had_error) { + socket.end(); + console.error('The proxy error'); + }.bind(this)); + + }); + +server5.on('error', function (e) { + console.error('SERVER ERROR: %j', e); + if (e.code == 'EADDRINUSE') { + console.log('Address in use, retrying in 10 seconds...'); + setTimeout(function () { + console.log('Reconnecting to %s',PORT); + server.close(); + server.listen(PORT5); + }, 10000); + } +}); +server5.listen(PORT5); + +} + }); + +d.on('error', function(er) { + // an error occurred somewhere. + // if we throw it now, it will crash the program + // with the normal line number and stack message. + console.log('ERROR!: %s ',er); + +}); From d9b780fdf30e9ce3064174f998915d340ac3b8c6 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 19:06:43 -0800 Subject: [PATCH 25/59] --- socks4.js | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 socks4.js diff --git a/socks4.js b/socks4.js new file mode 100644 index 0000000..908c06f --- /dev/null +++ b/socks4.js @@ -0,0 +1,137 @@ +var net = require('net'), + util = require('util'), + log = function(args) { + //console.log(args); + }, + info = console.info, + errorLog = console.error, + clients = [], + SOCKS_VERSION = 4; + +function createSocksServer() { + var socksServer = net.createServer(); + socksServer.on('listening', function() { + var address = socksServer.address(); + info('LISTENING %s:%s', address.address, address.port); + }); + socksServer.on('connection', function(socket) { + info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); + initSocksConnection.bind(socket)(); + }); + return socksServer; +} +// +// socket is available as this +function initSocksConnection() { + // keep log of connected clients + clients.push(this); + + // remove from clients on disconnect + this.on('end', function() { + var idx = clients.indexOf(this); + if (idx != -1) { + clients.splice(idx, 1); + } + }); + this.on('error', function(e) { + errorLog('%j', e); + var idx = clients.indexOf(this); + if (idx != -1) { + clients.splice(idx, 1); + } + }); + + // do a handshake + this.handshake = handshake.bind(this); + this.on('data', this.handshake); +} + +function handshake(chunk) { + this.removeListener('data', this.handshake); + + // SOCKS Version 5 is the only support version + if (chunk[0] != SOCKS_VERSION) { + errorLog('handshake: wrong socks version: %d', chunk[0]); + this.end(); + } + + var cmd=chunk[1], + address, + port, + offset=3; + + address = util.format('%s.%s.%s.%s', chunk[offset+1], chunk[offset+2], chunk[offset+3], chunk[offset+4]); + port = chunk.readUInt16BE(2); + + log('Request: type: %d -- to: %s:%s', chunk[1], address, port); + + + this.request = chunk; + this.proxy = net.createConnection(port, address, initProxy.bind(this)); +this.proxy.on('error', function(had_error) { +this.end(); +console.error('The proxy error'); +}.bind(this)); + +} + +function initProxy() { + log('Proxy connected'); + // creating response + var resp = new Buffer(8); + this.request.copy(resp,0,0,7); + // rewrite response header + resp[0] = 0x00; + resp[1] = 90; + this.write(resp); + + var from_proxy = function(data) { + try { + this.write(data); + } catch (err) { + } + }.bind(this); + var to_proxy = function(data) { + try { + this.proxy.write(data); + } catch (err) { + } + }.bind(this); + + this.proxy.on('data', from_proxy); + this.on('data', to_proxy); + + this.proxy.on('close', function(had_error) { + this.removeListener('data', to_proxy); + this.proxy = undefined; + this.end(); + errorLog('Proxy closed'); + }.bind(this)); + this.on('close', function(had_error) { + if (this.proxy !== undefined) { + this.proxy.removeListener('data', from_proxy); + this.proxy.end(); + } + errorLog('Socket closed'); + }.bind(this)); +this.on('error', function(had_error) { +if (this.proxy !== undefined) { +this.proxy.removeAllListeners('data'); +this.proxy.end(); +} +console.error('The application error'); + +}.bind(this)); + +this.proxy.on('error', function(had_error) { +this.end(); +console.error('The proxy error'); +}.bind(this)); + + + +} + +module.exports = { + createServer: createSocksServer +}; \ No newline at end of file From 22a55018d0942eb63bb0c46e5e80bbf3cd7cd6f5 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 19:25:44 -0800 Subject: [PATCH 26/59] --- socks.js | 192 ------------------------------------------------------- 1 file changed, 192 deletions(-) delete mode 100644 socks.js diff --git a/socks.js b/socks.js deleted file mode 100644 index 44a5069..0000000 --- a/socks.js +++ /dev/null @@ -1,192 +0,0 @@ -var net = require('net'), -????util = require('util'), -????log = function(args) { -????????//console.log(args); -????}, -????info = console.info, -????errorLog = console.error, -????clients = [], -????SOCKS_VERSION = 5, -/* - * Authentication methods - ************************ - * o X'00' NO AUTHENTICATION REQUIRED - * o X'01' GSSAPI - * o X'02' USERNAME/PASSWORD - * o X'03' to X'7F' IANA ASSIGNED - * o X'80' to X'FE' RESERVED FOR PRIVATE METHODS - * o X'FF' NO ACCEPTABLE METHODS - */ -????AUTHENTICATION = { -????????NOAUTH: 0x00, -????????GSSAPI: 0x01, -????????USERPASS: 0x02, -????????NONE: 0xFF -????}, -/* - * o CMD - * o CONNECT X'01' - * o BIND X'02' - * o UDP ASSOCIATE X'03' - */ -????REQUEST_CMD = { -????????CONNECT: 0x01, -????????BIND: 0x02, -????????UDP_ASSOCIATE: 0x03 -????}, -/* - * o ATYP address type of following address - * o IP V4 address: X'01' - * o DOMAINNAME: X'03' - * o IP V6 address: X'04' - */ -????ATYP = { -????????IP_V4: 0x01, -????????DNS: 0x03, -????????IP_V6: 0x04 -????}, -????Address = { -????????read: function (buffer, offset) { -??????????????????if (buffer[offset] == ATYP.IP_V4) { -??????????????????????return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); -??????????????????} else if (buffer[offset] == ATYP.DNS) { -??????????????????????return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); -??????????????????} else if (buffer[offset] == ATYP.IP_V6) { -??????????????????????return buffer.slice(buffer[offset+1], buffer[offset+1+16]); -??????????????????} -??????????????}, -????????sizeOf: function(buffer, offset) { -????????????????????if (buffer[offset] == ATYP.IP_V4) { -????????????????????????return 4; -????????????????????} else if (buffer[offset] == ATYP.DNS) { -????????????????????????return buffer[offset+1]; -????????????????????} else if (buffer[offset] == ATYP.IP_V6) { -????????????????????????return 16; -????????????????????} -????????????????} -????}; - -function createSocksServer(cb) { -????var socksServer = net.createServer(); -????socksServer.on('listening', function() { -????????var address = socksServer.address(); -????????info('LISTENING %s:%s', address.address, address.port); -????}); -????socksServer.on('connection', function(socket) { -????????info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); -????????initSocksConnection.bind(socket)(cb); - -????socket.on('error', function(e) { -????????errorLog('error: %j', e); - this.end(); -????}); -????}); -????return socksServer; -} -// -// socket is available as this -function initSocksConnection(on_accept) { -????// keep log of connected clients -????clients.push(this); - -????// remove from clients on disconnect -????this.on('end', function() { -????????var idx = clients.indexOf(this); -????????if (idx != -1) { -????????????clients.splice(idx, 1); -????????} -????}); -????this.on('initSocksConnection error', function(e) { -????????errorLog('%j', e); -????}); - -????// do a handshake -????this.handshake = handshake.bind(this); -????this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer -????this.on('data', this.handshake); -} - -function handshake(chunk) { -????this.removeListener('data', this.handshake); - -????var method_count = 0; - -????// SOCKS Version 5 is the only support version -????if (chunk[0] != SOCKS_VERSION) { -????????errorLog('handshake: wrong socks version: %d', chunk[0]); -????????this.end(); -????} -????// Number of authentication methods -????method_count = chunk[1]; - -????this.auth_methods = []; -????// i starts on 1, since we've read chunk 0 & 1 already -????for (var i=2; i < method_count + 2; i++) { -????????this.auth_methods.push(chunk[i]); -????} -????log('Supported auth methods: %j', this.auth_methods); - -????var resp = new Buffer(2); -????resp[0] = 0x05; -????if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { -????????log('Handing off to handleRequest'); -????????this.handleRequest = handleRequest.bind(this); -????????this.on('data', this.handleRequest); -????????resp[1] = AUTHENTICATION.NOAUTH; -????????this.write(resp); -????} else { -????????errorLog('Unsuported authentication method -- disconnecting'); -????????resp[1] = 0xFF; -????????this.end(resp); -????} -} - -function handleRequest(chunk) { -????this.removeListener('data', this.handleRequest); -????var cmd=chunk[1], -????????address, -????????port, -????????offset=3; -????// Wrong version! -????if (chunk[0] !== SOCKS_VERSION) { -????????this.end('%d%d', 0x05, 0x01); -????????errorLog('handleRequest: wrong socks version: %d', chunk[0]); -????????return; -????} /* else if (chunk[2] == 0x00) { - this.end(util.format('%d%d', 0x05, 0x01)); - errorLog('handleRequest: Mangled request. Reserved field is not null: %d', chunk[offset]); - return; - } */ -????address = Address.read(chunk, 3); -????offset = 3 + Address.sizeOf(chunk, 3) + 2; -????port = chunk.readUInt16BE(offset); - -????log('Request: type: %d -- to: %s:%s', chunk[1], address, port); - -????if (cmd == REQUEST_CMD.CONNECT) { -????????this.request = chunk; -????????this.on_accept(this, port, address, proxyReady.bind(this)); -????} else { -????????this.end('%d%d', 0x05, 0x01); -????????return; -????} -} - -function proxyReady() { -????log('Indicating to the client that the proxy is ready'); -????// creating response -????var resp = new Buffer(this.request.length); -????this.request.copy(resp); -????// rewrite response header -????resp[0] = SOCKS_VERSION; -????resp[1] = 0x00; -????resp[2] = 0x00; -????this.write(resp); -????log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); -??? - -} - -module.exports = { -????createServer: createSocksServer -}; \ No newline at end of file From 523b8ebbe4172199fe19b897b8704141e44b125f Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 16 Dec 2012 11:28:49 +0800 Subject: [PATCH 27/59] Update README.rst --- README.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index e563814..7246374 100644 --- a/README.rst +++ b/README.rst @@ -6,9 +6,10 @@ A simple SOCKS implementation and demo proxy in `node.js `_. It supports both socks5 and socks4. You can run it easily as:: - ./socks5.js -under windows you can run 鏂板缓鏂囨湰鏂囦欢.vbs + ./socksproxy5.js + ./socksproxy4.js -This will create a proxy at ``127.0.0.1`` on port ``8888``. +This will create a proxy socks5 at ``127.0.0.1`` on port ``8888``. +This will create a proxy socks4 at ``127.0.0.1`` on port ``9999``. You can use this as a good starting point for writing a proxy or a tunnel! From eec9985899b6d54e7d7746bbce966ed10854d695 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 22:21:41 -0800 Subject: [PATCH 28/59] bug fix --- socks5.js | 380 +++++++++++++++++++++++++++--------------------------- 1 file changed, 193 insertions(+), 187 deletions(-) diff --git a/socks5.js b/socks5.js index 3daeb5e..3d100c5 100644 --- a/socks5.js +++ b/socks5.js @@ -1,187 +1,193 @@ -var net = require('net'), - util = require('util'), - log = function(args) { - //console.log(args); - }, - info = console.info, - errorLog = console.error, - clients = [], - SOCKS_VERSION = 5, -/* - * Authentication methods - ************************ - * o X'00' NO AUTHENTICATION REQUIRED - * o X'01' GSSAPI - * o X'02' USERNAME/PASSWORD - * o X'03' to X'7F' IANA ASSIGNED - * o X'80' to X'FE' RESERVED FOR PRIVATE METHODS - * o X'FF' NO ACCEPTABLE METHODS - */ - AUTHENTICATION = { - NOAUTH: 0x00, - GSSAPI: 0x01, - USERPASS: 0x02, - NONE: 0xFF - }, -/* - * o CMD - * o CONNECT X'01' - * o BIND X'02' - * o UDP ASSOCIATE X'03' - */ - REQUEST_CMD = { - CONNECT: 0x01, - BIND: 0x02, - UDP_ASSOCIATE: 0x03 - }, -/* - * o ATYP address type of following address - * o IP V4 address: X'01' - * o DOMAINNAME: X'03' - * o IP V6 address: X'04' - */ - ATYP = { - IP_V4: 0x01, - DNS: 0x03, - IP_V6: 0x04 - }, - Address = { - read: function (buffer, offset) { - if (buffer[offset] == ATYP.IP_V4) { - return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); - } else if (buffer[offset] == ATYP.DNS) { - return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); - } else if (buffer[offset] == ATYP.IP_V6) { - return buffer.slice(buffer[offset+1], buffer[offset+1+16]); - } - }, - sizeOf: function(buffer, offset) { - if (buffer[offset] == ATYP.IP_V4) { - return 4; - } else if (buffer[offset] == ATYP.DNS) { - return buffer[offset+1]; - } else if (buffer[offset] == ATYP.IP_V6) { - return 16; - } - } - }; - -function createSocksServer(cb) { - var socksServer = net.createServer(); - socksServer.on('listening', function() { - var address = socksServer.address(); - info('LISTENING %s:%s', address.address, address.port); - }); - socksServer.on('connection', function(socket) { - info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); - initSocksConnection.bind(socket)(cb); - }); - return socksServer; -} -// -// socket is available as this -function initSocksConnection(on_accept) { - // keep log of connected clients - clients.push(this); - - // remove from clients on disconnect - this.on('end', function() { - var idx = clients.indexOf(this); - if (idx != -1) { - clients.splice(idx, 1); - } - }); - this.on('error', function(e) { - errorLog('%j', e); - }); - - // do a handshake - this.handshake = handshake.bind(this); - this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer - this.on('data', this.handshake); -} - -function handshake(chunk) { - this.removeListener('data', this.handshake); - - var method_count = 0; - - // SOCKS Version 5 is the only support version - if (chunk[0] != SOCKS_VERSION) { - errorLog('handshake: wrong socks version: %d', chunk[0]); - this.end(); - } - // Number of authentication methods - method_count = chunk[1]; - - this.auth_methods = []; - // i starts on 1, since we've read chunk 0 & 1 already - for (var i=2; i < method_count + 2; i++) { - this.auth_methods.push(chunk[i]); - } - log('Supported auth methods: %j', this.auth_methods); - - var resp = new Buffer(2); - resp[0] = 0x05; - if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { - log('Handing off to handleRequest'); - this.handleRequest = handleRequest.bind(this); - this.on('data', this.handleRequest); - resp[1] = AUTHENTICATION.NOAUTH; - this.write(resp); - } else { - errorLog('Unsuported authentication method -- disconnecting'); - resp[1] = 0xFF; - this.end(resp); - } -} - -function handleRequest(chunk) { - this.removeListener('data', this.handleRequest); - var cmd=chunk[1], - address, - port, - offset=3; - // Wrong version! - if (chunk[0] !== SOCKS_VERSION) { - this.end('%d%d', 0x05, 0x01); - errorLog('handleRequest: wrong socks version: %d', chunk[0]); - return; - } /* else if (chunk[2] == 0x00) { - this.end(util.format('%d%d', 0x05, 0x01)); - errorLog('handleRequest: Mangled request. Reserved field is not null: %d', chunk[offset]); - return; - } */ - address = Address.read(chunk, 3); - offset = 3 + Address.sizeOf(chunk, 3) + 2; - port = chunk.readUInt16BE(offset); - - log('Request: type: %d -- to: %s:%s', chunk[1], address, port); - - if (cmd == REQUEST_CMD.CONNECT) { - this.request = chunk; - this.on_accept(this, port, address, proxyReady.bind(this)); - } else { - this.end('%d%d', 0x05, 0x01); - return; - } -} - -function proxyReady() { - log('Indicating to the client that the proxy is ready'); - // creating response - var resp = new Buffer(this.request.length); - this.request.copy(resp); - // rewrite response header - resp[0] = SOCKS_VERSION; - resp[1] = 0x00; - resp[2] = 0x00; - this.write(resp); - log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); - - -} - -module.exports = { - createServer: createSocksServer -}; +var net = require('net'), + util = require('util'), + log = function(args) { + console.log(args); + }, + info = console.info, + errorLog = console.error, + clients = [], + SOCKS_VERSION = 5, +/* + * Authentication methods + ************************ + * o X'00' NO AUTHENTICATION REQUIRED + * o X'01' GSSAPI + * o X'02' USERNAME/PASSWORD + * o X'03' to X'7F' IANA ASSIGNED + * o X'80' to X'FE' RESERVED FOR PRIVATE METHODS + * o X'FF' NO ACCEPTABLE METHODS + */ + AUTHENTICATION = { + NOAUTH: 0x00, + GSSAPI: 0x01, + USERPASS: 0x02, + NONE: 0xFF + }, +/* + * o CMD + * o CONNECT X'01' + * o BIND X'02' + * o UDP ASSOCIATE X'03' + */ + REQUEST_CMD = { + CONNECT: 0x01, + BIND: 0x02, + UDP_ASSOCIATE: 0x03 + }, +/* + * o ATYP address type of following address + * o IP V4 address: X'01' + * o DOMAINNAME: X'03' + * o IP V6 address: X'04' + */ + ATYP = { + IP_V4: 0x01, + DNS: 0x03, + IP_V6: 0x04 + }, + Address = { + read: function (buffer, offset) { + if (buffer[offset] == ATYP.IP_V4) { + return util.format('%s.%s.%s.%s', buffer[offset+1], buffer[offset+2], buffer[offset+3], buffer[offset+4]); + } else if (buffer[offset] == ATYP.DNS) { + return buffer.toString('utf8', offset+2, offset+2+buffer[offset+1]); + } else if (buffer[offset] == ATYP.IP_V6) { + return buffer.slice(buffer[offset+1], buffer[offset+1+16]); + } + }, + sizeOf: function(buffer, offset) { + if (buffer[offset] == ATYP.IP_V4) { + return 4; + } else if (buffer[offset] == ATYP.DNS) { + return buffer[offset+1]+1; + } else if (buffer[offset] == ATYP.IP_V6) { + return 16; + } + } + }; + +function createSocksServer(cb) { + var socksServer = net.createServer(); + socksServer.on('listening', function() { + var address = socksServer.address(); + info('LISTENING %s:%s', address.address, address.port); + }); + socksServer.on('connection', function(socket) { + info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); + initSocksConnection.bind(socket)(cb); + + socket.on('error', function(e) { + errorLog('error: %j', e); + this.end(); + }); + }); + return socksServer; +} +// +// socket is available as this +function initSocksConnection(on_accept) { + // keep log of connected clients + clients.push(this); + + // remove from clients on disconnect + this.on('end', function() { + var idx = clients.indexOf(this); + if (idx != -1) { + clients.splice(idx, 1); + } + }); + this.on('initSocksConnection error', function(e) { + errorLog('%j', e); + }); + + // do a handshake + this.handshake = handshake.bind(this); + this.on_accept = on_accept; // No bind. We want 'this' to be the server, like it would be for net.createServer + this.on('data', this.handshake); +} + +function handshake(chunk) { + this.removeListener('data', this.handshake); + + var method_count = 0; + + // SOCKS Version 5 is the only support version + if (chunk[0] != SOCKS_VERSION) { + errorLog('handshake: wrong socks version: %d', chunk[0]); + this.end(); + } + // Number of authentication methods + method_count = chunk[1]; + + this.auth_methods = []; + // i starts on 1, since we've read chunk 0 & 1 already + for (var i=2; i < method_count + 2; i++) { + this.auth_methods.push(chunk[i]); + } + log('Supported auth methods: %j', this.auth_methods); + + var resp = new Buffer(2); + resp[0] = 0x05; + if (this.auth_methods.indexOf(AUTHENTICATION.NOAUTH) > -1) { + log('Handing off to handleRequest'); + this.handleRequest = handleRequest.bind(this); + this.on('data', this.handleRequest); + resp[1] = AUTHENTICATION.NOAUTH; + this.write(resp); + } else { + errorLog('Unsuported authentication method -- disconnecting'); + resp[1] = 0xFF; + this.end(resp); + } +} + +function handleRequest(chunk) { + this.removeListener('data', this.handleRequest); + var cmd=chunk[1], + address, + port, + offset=3; + // Wrong version! + if (chunk[0] !== SOCKS_VERSION) { + this.end('%d%d', 0x05, 0x01); + errorLog('handleRequest: wrong socks version: %d', chunk[0]); + log(chunk); + return; + } /* else if (chunk[2] == 0x00) { + this.end(util.format('%d%d', 0x05, 0x01)); + errorLog('handleRequest: Mangled request. Reserved field is not null: %d', chunk[offset]); + return; + } */ + address = Address.read(chunk, 3); + offset = 4 + Address.sizeOf(chunk, 3); + port = chunk.readUInt16BE(offset); + + log('Request: type: %d -- to: %s:%s', chunk[1], address, port); + + if (cmd == REQUEST_CMD.CONNECT) { + this.request = chunk; + this.on_accept(this, port, address, proxyReady.bind(this)); + } else { + this.end('%d%d', 0x05, 0x01); + return; + } +} + +function proxyReady() { + log('Indicating to the client that the proxy is ready'); + // creating response + var resp = new Buffer(this.request.length); + this.request.copy(resp); + // rewrite response header + resp[0] = SOCKS_VERSION; + resp[1] = 0x00; + resp[2] = 0x00; + this.write(resp); + log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); + + +} + +module.exports = { + createServer: createSocksServer +}; From da78c10ce5fc067d3223f9e260d9f98a3af16d10 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 15 Dec 2012 22:25:00 -0800 Subject: [PATCH 29/59] --- run.vbs | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 run.vbs diff --git a/run.vbs b/run.vbs new file mode 100644 index 0000000..28d7947 --- /dev/null +++ b/run.vbs @@ -0,0 +1,2 @@ +createobject("wscript.shell").run "cmd /c node socksproxy5",0 +createobject("wscript.shell").run "cmd /c node socksproxy4",0 From 95b67a5692135d8c6dd4a16e79731172638c28d5 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 16 Dec 2012 14:34:13 +0800 Subject: [PATCH 30/59] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 7246374..6635656 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ You can run it easily as:: ./socksproxy5.js ./socksproxy4.js - +under聽windows聽you聽can聽run聽run.vbs This will create a proxy socks5 at ``127.0.0.1`` on port ``8888``. This will create a proxy socks4 at ``127.0.0.1`` on port ``9999``. From e51ffd9d34b9999a8dafe396dd51787a0afb2a4f Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 16 Dec 2012 04:24:16 -0800 Subject: [PATCH 31/59] add socks5 udp support --- socks5.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/socks5.js b/socks5.js index 3d100c5..ad3f891 100644 --- a/socks5.js +++ b/socks5.js @@ -1,4 +1,5 @@ var net = require('net'), + dgram = require('dgram'), util = require('util'), log = function(args) { console.log(args); @@ -167,7 +168,31 @@ function handleRequest(chunk) { if (cmd == REQUEST_CMD.CONNECT) { this.request = chunk; this.on_accept(this, port, address, proxyReady.bind(this)); - } else { + } else if(cmd == REQUEST_CMD.UDP_ASSOCIATE){ + this.request = chunk; + this.udpclient = dgram.createSocket("udp4"); + this.udpclient.bind(0); + var udpaddress = this.udpclient.address(); +//应答 + var resp = new Buffer(chunk.length); + chunk.copy(resp); + // rewrite response header + resp[0] = SOCKS_VERSION; + resp[1] = 0x00; + resp[2] = 0x00; + var ad = udpaddress.address.split("."); + resp[4]=Number(ad[0]); + resp[5]=Number(ad[1]); + resp[6]=Number(ad[2]); + resp[7]=Number(ad[3]); + resp.writeUInt16BE(udpaddress.port,8); + this.write(resp); + this.clientaddress=address; + this.clientport=port; + this.udphandshake = udphandshake.bind(this); + this.udpclient.on('message', this.udphandshake); + } + else { this.end('%d%d', 0x05, 0x01); return; } @@ -186,6 +211,41 @@ function proxyReady() { log('Connected to: %s:%d', resp.toString('utf8', 4, resp.length - 2), resp.readUInt16BE(resp.length - 2)); +} +function udphandshake(msg, rinfo) { + this.removeListener('message', this.udphandshake); +//get the udp head +if(rinfo.address==this.clientaddress){//转发 +var address=Address.read(msg, 3), + offset = 4 + Address.sizeOf(msg, 3), + port = chunk.readUInt16BE(offset); + this.udpclient.send(msg,offset+2,msg.length-offset-2,port,address); +}else {//收到其它信息 +var resp = new Buffer(10+msg.length); + msg.copy(resp,10); + // rewrite response header + resp[0] = 0x00; + resp[1] = 0x00; + resp[2] = 0x00; + resp[3] = 0x01; + var ad = rinfo.address.split("."); + resp[4]=Number(ad[0]); + resp[5]=Number(ad[1]); + resp[6]=Number(ad[2]); + resp[7]=Number(ad[3]); + resp.writeUInt16BE(rinfo.port,8); + this.udpclient.send(resp,0,resp.length,this.clientport,this.clientaddress); +} +this.udpclient.on('error',function(){}); +this.on('close',function(had_error){ +this.end(); +this.udpclient.close(); +}.bind(this)); +this.on('error',function(had_error){ +this.end(); +this.udpclient.close(); +}.bind(this)); + } module.exports = { From 90e7f0b70f3ca4e75495e0a4b84687114173f067 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 16 Dec 2012 04:25:09 -0800 Subject: [PATCH 32/59] cluster bug fix --- socksproxy4.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/socksproxy4.js b/socksproxy4.js index 16ba2ce..0b248d0 100644 --- a/socksproxy4.js +++ b/socksproxy4.js @@ -1,7 +1,7 @@ var net = require('net'), socks4 = require('./socks4.js'); - +var exec = require('child_process').exec; var d = require('domain').create(); var cluster = require('cluster'); @@ -18,10 +18,12 @@ if (cluster.isMaster) { if(1==numCPUs) cluster.fork();//make sure it is more than 2 cluster.on('exit', function(worker, code, signal) { + if (worker.suicide !== true) { + exec('taskkill /pid '+worker.process.pid +' /T /F'); + } var exitCode = worker.process.exitCode; console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); -// exec('taskkill /pid '+worker.process.pid +' /T /F'); cluster.fork(); }); From 487abf142fa5e4b6f7ee452bfe256829300baf5d Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 16 Dec 2012 04:25:31 -0800 Subject: [PATCH 33/59] cluster bug fix --- socksproxy5.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/socksproxy5.js b/socksproxy5.js index de8848e..1dfa237 100644 --- a/socksproxy5.js +++ b/socksproxy5.js @@ -1,7 +1,7 @@ var net = require('net'), socks5 = require('./socks5.js'); - +var exec = require('child_process').exec; var d = require('domain').create(); var cluster = require('cluster'); @@ -18,10 +18,13 @@ if (cluster.isMaster) { if(1==numCPUs) cluster.fork();//make sure it is more than 2 cluster.on('exit', function(worker, code, signal) { - var exitCode = worker.process.exitCode; - console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); + if (worker.suicide !== true) { + exec('taskkill /pid '+worker.process.pid +' /T /F'); + } +var exitCode = worker.process.exitCode; + console.log('worker ' + worker.process.pid + ' died ('+exitCode+'). restarting...'); -// exec('taskkill /pid '+worker.process.pid +' /T /F'); +// cluster.fork(); }); From 6e28ada4d442129f8386431e43b67b4149f7c0ae Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Fri, 21 Dec 2012 03:04:34 -0800 Subject: [PATCH 34/59] use for proxy chains --- chains.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 chains.js diff --git a/chains.js b/chains.js new file mode 100644 index 0000000..18781f0 --- /dev/null +++ b/chains.js @@ -0,0 +1,38 @@ +var net = require('net'); +var proxyhost="127.0.0.1";//被代理的服务的IP +var proxyport=8888;//被代理的端口 +var listenport=8124;//代理端口 +net.createServer(function (socket) { +socket.on("connect",function(){ +console.log('connected'); +try{ +var db=net.createConnection(proxyport,proxyhost); +db.on("connect",function(){ +console.log("server connected"); +socket.on("data", function (data) { +db.write(data); +}); +db.on("data",function(data){ +//console.log(data.toString('utf8',0,data.legnth)); +//console.log(data); +socket.write(data); +}); +socket.on("close",function(){ +console.log("server closed"); +db.end(); +}); +}); +db.on("error",function(data){ +console.log("error:\r\n"+data); +db.end(); +socket.end(); +}); +db.on("end",function(){ +console.log("server closed"); +socket.end(); +}); +}catch(err){ +console.log(err); +} +}); +}).listen(listenport, "0.0.0.0"); \ No newline at end of file From eb8b45673399c67f1ff8dacd200a4c5743a863b7 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 22 Dec 2012 21:35:56 -0800 Subject: [PATCH 35/59] add socks4a support --- socks4.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/socks4.js b/socks4.js index 908c06f..4a7156d 100644 --- a/socks4.js +++ b/socks4.js @@ -1,7 +1,7 @@ var net = require('net'), util = require('util'), log = function(args) { - //console.log(args); + console.log(args); }, info = console.info, errorLog = console.error, @@ -15,7 +15,7 @@ function createSocksServer() { info('LISTENING %s:%s', address.address, address.port); }); socksServer.on('connection', function(socket) { - info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); + info('CONNECTED from %s:%s', socket.remoteAddress, socket.remotePort); initSocksConnection.bind(socket)(); }); return socksServer; @@ -49,7 +49,7 @@ function initSocksConnection() { function handshake(chunk) { this.removeListener('data', this.handshake); - // SOCKS Version 5 is the only support version + // SOCKS Version 4 is the only support version if (chunk[0] != SOCKS_VERSION) { errorLog('handshake: wrong socks version: %d', chunk[0]); this.end(); @@ -60,17 +60,25 @@ function handshake(chunk) { port, offset=3; - address = util.format('%s.%s.%s.%s', chunk[offset+1], chunk[offset+2], chunk[offset+3], chunk[offset+4]); + port = chunk.readUInt16BE(2); +//////////////////socks4a support + if(chunk[4]==0&&chunk[5]==0&&chunk[6]==0&&chunk[7]!=0){ + offset=chunk[8]+1; + address=chunk.toString('utf8', offset+8, offset+8+chunk[offset+8]); + // log(chunk.toString()); +} else{ +address = util.format('%s.%s.%s.%s', chunk[offset+1], chunk[offset+2], chunk[offset+3], chunk[offset+4]); - log('Request: type: %d -- to: %s:%s', chunk[1], address, port); - - - this.request = chunk; +} + log(chunk.toString()); + log(address); + this.request = chunk; this.proxy = net.createConnection(port, address, initProxy.bind(this)); this.proxy.on('error', function(had_error) { this.end(); -console.error('The proxy error'); +console.error('The Connection proxy error'); + }.bind(this)); } From 941d685ba0da53fc59c274846af7230dea6cfef5 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 23 Dec 2012 13:39:11 +0800 Subject: [PATCH 36/59] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 6635656..69a5ff0 100644 --- a/README.rst +++ b/README.rst @@ -10,6 +10,6 @@ You can run it easily as:: ./socksproxy4.js under聽windows聽you聽can聽run聽run.vbs This will create a proxy socks5 at ``127.0.0.1`` on port ``8888``. -This will create a proxy socks4 at ``127.0.0.1`` on port ``9999``. +This will create a proxy socks4 socks4a at ``127.0.0.1`` on port ``9999``. You can use this as a good starting point for writing a proxy or a tunnel! From 9aa0c5a365c4582ddb16092755c16cc33fbc1016 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 22 Dec 2012 23:54:27 -0800 Subject: [PATCH 37/59] socks4a bug fix --- socks4.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/socks4.js b/socks4.js index 4a7156d..1e0d8b7 100644 --- a/socks4.js +++ b/socks4.js @@ -64,15 +64,15 @@ function handshake(chunk) { port = chunk.readUInt16BE(2); //////////////////socks4a support if(chunk[4]==0&&chunk[5]==0&&chunk[6]==0&&chunk[7]!=0){ - offset=chunk[8]+1; - address=chunk.toString('utf8', offset+8, offset+8+chunk[offset+8]); - // log(chunk.toString()); +var ad = chunk.toString('utf8',8,chunk.length-1).split("\0"); +var userid=ad[0]; +address=ad[1]; + log(userid+"--userid--"); + log(address+"--address--"); } else{ address = util.format('%s.%s.%s.%s', chunk[offset+1], chunk[offset+2], chunk[offset+3], chunk[offset+4]); } - log(chunk.toString()); - log(address); this.request = chunk; this.proxy = net.createConnection(port, address, initProxy.bind(this)); this.proxy.on('error', function(had_error) { From 305a2fb84a63ba880c53d99ef4884d375fcf7257 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Tue, 1 Jan 2013 21:47:06 -0800 Subject: [PATCH 38/59] iplist used for ip authentication --- ip.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 ip.txt diff --git a/ip.txt b/ip.txt new file mode 100644 index 0000000..5ac6dca --- /dev/null +++ b/ip.txt @@ -0,0 +1 @@ +192.168.0.101;127.0.0.1; \ No newline at end of file From 25cc235e16742d85027bb620c003a704e06d720f Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Tue, 1 Jan 2013 21:48:57 -0800 Subject: [PATCH 39/59] add ip authentication --- socks4.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/socks4.js b/socks4.js index 1e0d8b7..fad7e56 100644 --- a/socks4.js +++ b/socks4.js @@ -6,8 +6,9 @@ var net = require('net'), info = console.info, errorLog = console.error, clients = [], + ips=[], SOCKS_VERSION = 4; - +var fs = require("fs"); function createSocksServer() { var socksServer = net.createServer(); socksServer.on('listening', function() { @@ -16,11 +17,27 @@ function createSocksServer() { }); socksServer.on('connection', function(socket) { info('CONNECTED from %s:%s', socket.remoteAddress, socket.remotePort); + initIplist(); + var idx = ips.indexOf( socket.remoteAddress); + if (idx == -1) { + socket.end(); + log('ip pass failed '); + + }else{ + initSocksConnection.bind(socket)(); + } }); return socksServer; } -// +//iplist +function initIplist() { + fs.readFile('./ip.txt',function(err,data){ + if(err) throw err; +ips = data.toString('utf8',0,data.length).split(";"); +}); +} + // socket is available as this function initSocksConnection() { // keep log of connected clients From a7ebb4e1ea505c04f268d319888920f22cf5b465 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Tue, 1 Jan 2013 21:49:25 -0800 Subject: [PATCH 40/59] add ip authentication --- socks5.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/socks5.js b/socks5.js index ad3f891..20ac0e2 100644 --- a/socks5.js +++ b/socks5.js @@ -7,6 +7,7 @@ var net = require('net'), info = console.info, errorLog = console.error, clients = [], + ips=[], SOCKS_VERSION = 5, /* * Authentication methods @@ -66,6 +67,7 @@ var net = require('net'), } } }; +var fs = require("fs"); function createSocksServer(cb) { var socksServer = net.createServer(); @@ -75,7 +77,15 @@ function createSocksServer(cb) { }); socksServer.on('connection', function(socket) { info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); + initIplist(); + var idx = ips.indexOf( socket.remoteAddress); + if (idx == -1) { + socket.end(); + log('ip pass failed '); + }else { + initSocksConnection.bind(socket)(cb); + } socket.on('error', function(e) { errorLog('error: %j', e); @@ -85,6 +95,14 @@ function createSocksServer(cb) { return socksServer; } // +//iplist +function initIplist() { + fs.readFile('./ip.txt',function(err,data){ + if(err) throw err; +ips = data.toString('utf8',0,data.length).split(";"); +}); +} + // socket is available as this function initSocksConnection(on_accept) { // keep log of connected clients From 28f9ec06eda5d498319999da0d57e9b045b5564e Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Fri, 11 Jan 2013 03:14:20 -0800 Subject: [PATCH 41/59] add 'ip.txt' file watch --- socks4.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/socks4.js b/socks4.js index fad7e56..ccf23a7 100644 --- a/socks4.js +++ b/socks4.js @@ -11,13 +11,21 @@ var net = require('net'), var fs = require("fs"); function createSocksServer() { var socksServer = net.createServer(); + initIplist(); + fs.watch('./ip.txt',function(event,filename){ + + if(event=="change") //如果文件变动了 + { + initIplist(); + } +}); socksServer.on('listening', function() { var address = socksServer.address(); info('LISTENING %s:%s', address.address, address.port); }); socksServer.on('connection', function(socket) { info('CONNECTED from %s:%s', socket.remoteAddress, socket.remotePort); - initIplist(); + var idx = ips.indexOf( socket.remoteAddress); if (idx == -1) { socket.end(); From f59fcfb5ef911e1a53fa2cb57e6fe3081bf9a48d Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Fri, 11 Jan 2013 03:14:47 -0800 Subject: [PATCH 42/59] add 'ip.txt' file watch --- socks5.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/socks5.js b/socks5.js index 20ac0e2..d2bc995 100644 --- a/socks5.js +++ b/socks5.js @@ -71,13 +71,22 @@ var fs = require("fs"); function createSocksServer(cb) { var socksServer = net.createServer(); + + initIplist(); + fs.watch('./ip.txt',function(event,filename){ + if(event=="change") //如果文件变动了 + { + initIplist(); + } +}); + socksServer.on('listening', function() { var address = socksServer.address(); info('LISTENING %s:%s', address.address, address.port); }); socksServer.on('connection', function(socket) { info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); - initIplist(); + var idx = ips.indexOf( socket.remoteAddress); if (idx == -1) { socket.end(); From b0605b78721486f131056f899355a87bd038de5a Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Mon, 14 Jan 2013 03:22:59 -0800 Subject: [PATCH 43/59] --- chains.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains.js b/chains.js index 18781f0..286e0a2 100644 --- a/chains.js +++ b/chains.js @@ -1,6 +1,6 @@ var net = require('net'); var proxyhost="127.0.0.1";//被代理的服务的IP -var proxyport=8888;//被代理的端口 +var proxyport=9999;//被代理的端口 var listenport=8124;//代理端口 net.createServer(function (socket) { socket.on("connect",function(){ From a940afe5146b5a59ce923f21a525cbc60ecdfabf Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Mon, 14 Jan 2013 03:39:06 -0800 Subject: [PATCH 44/59] add timeout --- socks4.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/socks4.js b/socks4.js index ccf23a7..b29169b 100644 --- a/socks4.js +++ b/socks4.js @@ -161,6 +161,15 @@ this.end(); console.error('The proxy error'); }.bind(this)); +this.setTimeout(60000, function(error){ +if (this.proxy !== undefined) { +this.proxy.removeAllListeners('data'); +this.proxy.end(); +this.end(); +} +console.error('socket timeout 60000ms'); + +}); } From b29c2fe39a9e86163fe0e047cd027a5f987a4061 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 19 Jan 2013 23:50:54 -0800 Subject: [PATCH 45/59] timeout bug fix --- socks4.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/socks4.js b/socks4.js index b29169b..77e8d56 100644 --- a/socks4.js +++ b/socks4.js @@ -58,13 +58,7 @@ function initSocksConnection() { clients.splice(idx, 1); } }); - this.on('error', function(e) { - errorLog('%j', e); - var idx = clients.indexOf(this); - if (idx != -1) { - clients.splice(idx, 1); - } - }); + // do a handshake this.handshake = handshake.bind(this); @@ -92,8 +86,8 @@ function handshake(chunk) { var ad = chunk.toString('utf8',8,chunk.length-1).split("\0"); var userid=ad[0]; address=ad[1]; - log(userid+"--userid--"); - log(address+"--address--"); + // log(userid+"--userid--"); + // log(address+"--address--"); } else{ address = util.format('%s.%s.%s.%s', chunk[offset+1], chunk[offset+2], chunk[offset+3], chunk[offset+4]); @@ -138,39 +132,48 @@ function initProxy() { this.removeListener('data', to_proxy); this.proxy = undefined; this.end(); - errorLog('Proxy closed'); + // errorLog('Proxy closed'); }.bind(this)); this.on('close', function(had_error) { if (this.proxy !== undefined) { this.proxy.removeListener('data', from_proxy); this.proxy.end(); } - errorLog('Socket closed'); + // errorLog('Socket closed'); }.bind(this)); this.on('error', function(had_error) { if (this.proxy !== undefined) { this.proxy.removeAllListeners('data'); this.proxy.end(); + } -console.error('The application error'); +//console.error('The application error'); }.bind(this)); this.proxy.on('error', function(had_error) { this.end(); -console.error('The proxy error'); +//console.error('The proxy error'); }.bind(this)); this.setTimeout(60000, function(error){ if (this.proxy !== undefined) { this.proxy.removeAllListeners('data'); this.proxy.end(); -this.end(); + } +this.end(); console.error('socket timeout 60000ms'); -}); +}.bind(this)); + +this.proxy.setTimeout(60000, function(error){ +this.proxy.removeAllListeners('data'); +this.proxy.end(); +this.end(); +console.error(' proxy socket timeout 60000ms'); +}.bind(this)); } From 189e13a8a0b5d4fc7bb0bcbdcf046a60754d0aa3 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 19 Jan 2013 23:51:15 -0800 Subject: [PATCH 46/59] timeout bug fix --- socks5.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/socks5.js b/socks5.js index d2bc995..318d1fe 100644 --- a/socks5.js +++ b/socks5.js @@ -125,7 +125,7 @@ function initSocksConnection(on_accept) { } }); this.on('initSocksConnection error', function(e) { - errorLog('%j', e); + errorLog('initSocksConnection error'); }); // do a handshake @@ -152,7 +152,7 @@ function handshake(chunk) { for (var i=2; i < method_count + 2; i++) { this.auth_methods.push(chunk[i]); } - log('Supported auth methods: %j', this.auth_methods); + // log('Supported auth methods: %j', this.auth_methods); var resp = new Buffer(2); resp[0] = 0x05; From d3a5ea8ab7bab6fb098571fe28e74def76b8de66 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 19 Jan 2013 23:51:32 -0800 Subject: [PATCH 47/59] timeout bug fix --- socksproxy5.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/socksproxy5.js b/socksproxy5.js index 1dfa237..9e275f8 100644 --- a/socksproxy5.js +++ b/socksproxy5.js @@ -53,7 +53,8 @@ var PORT5='8888', socket.on('data', function(d) { // If the application tries to send data before the proxy is ready, then that is it's own problem. try { - // console.log('sending ' + d.length + ' bytes to proxy'); + + // console.log('sending ' + d.length + ' bytes to proxy'); proxy.write(d); } catch(err) { } @@ -85,8 +86,28 @@ var PORT5='8888', console.error('The proxy error'); }.bind(this)); +socket.setTimeout(60000, function(error){ +if (this.proxy !== undefined) { +proxy.removeAllListeners('data'); +proxy.end(); + +} +this.end(); +console.error('socket timeout 60000ms'); + +}.bind(this)); + +proxy.setTimeout(60000, function(error){ +proxy.removeAllListeners('data'); +proxy.end(); +this.end(); +console.error('proxy socket timeout 60000ms'); + +}.bind(this)); + }); + server5.on('error', function (e) { console.error('SERVER ERROR: %j', e); if (e.code == 'EADDRINUSE') { From bdd34731d49109e14620079623999e96c7702c6a Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 30 Mar 2013 03:25:44 -0700 Subject: [PATCH 48/59] add http https proxy support --- http.js | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 http.js diff --git a/http.js b/http.js new file mode 100644 index 0000000..cd0702e --- /dev/null +++ b/http.js @@ -0,0 +1,183 @@ +var net=require('net'); +var local_port=8080; + +//在本地创建一个server监听本地local_port端口 +var sockserver=net.createServer(function (client) +{ + +//首先监听浏览器的数据发送事件,直到收到的数据包含完整的http请求头 +var buffer=new Buffer(0); +client.on('data',function (data) +{ +buffer=buffer_add(buffer,data); +if(buffer_find_body(buffer)==-1)return ; +var req=parse_request(buffer); +if(req===false)return ; +client.removeAllListeners('data'); +relay_connection(req); +}); + +//从http请求头部取得请求信息后,继续监听浏览器发送数据,同时连接目标服务器,并把目标服务器的数据传给浏览器 +function relay_connection(req) +{ +console.log(req.method+' '+req.host+':'+req.port); + +//如果请求不是CONNECT方法(GET, POST),那么替换掉头部的一些东西 +if(req.method!='CONNECT') +{ +//先从buffer中取出头部 +var _body_pos=buffer_find_body(buffer); +if(_body_pos<0)_body_pos=buffer.length; +var header=buffer.slice(0,_body_pos).toString('utf8'); +//替换connection头 +header=header.replace(/(proxy\-)connection\:.+\r\n/ig,'') +.replace(/Keep\-Alive\:.+\r\n/i,'') +.replace("\r\n",'\r\nConnection: close\r\n'); +//替换网址格式(去掉域名部分) +if(req.httpVersion=='1.1') +{ +var url=req.path.replace(/http\:\/\/[^\/]+/,''); +if(url.path!=url)header=header.replace(req.path,url); +} +buffer=buffer_add(new Buffer(header,'utf8'),buffer.slice(_body_pos)); +} + +//建立到目标服务器的连接 +var server=net.createConnection(req.port,req.host); +//交换服务器与浏览器的数据 +client.on("data",function (data){ +try +{server.write(data);} +catch (e) +{ } +}); +server.on("data",function (data){ +try +{client.write(data);} +catch (e) +{ } +}); +server.on("close",function (e){ +console.log("server close"); +console.log(e); +try +{client.end();} +catch (e) +{ } + +}); +client.on("close",function (e){ +try +{server.end();} +catch (e) +{ } +}); +if(req.method=='CONNECT') +client.write(new Buffer("HTTP/1.1 200 Connection established\r\nConnection: close\r\n\r\n")); +else +server.write(buffer); +} +}); + +//处理各种错误 +process.on('uncaughtException',function (err) +{ +console.log("\nError!!!!"); +console.log(err); +}); + +sockserver.on('listening', function() { + var address = sockserver.address(); + console.log('LISTENING %s:%s', address.address, address.port); + }); + + +/** +* 从请求头部取得请求详细信息 +* 如果是 CONNECT 方法,那么会返回 { method,host,port,httpVersion} +* 如果是 GET/POST 方法,那么返回 { metod,host,port,path,httpVersion} +*/ +function parse_request(buffer) +{ +var s=buffer.toString('utf8'); +var method=s.split('\n')[0].match(/^([A-Z]+)\s/)[1]; +if(method=='CONNECT') +{ +var arr=s.match(/^([A-Z]+)\s([^\:\s]+)\:(\d+)\sHTTP\/(\d\.\d)/); +if(arr&&arr[1]&&arr[2]&&arr[3]&&arr[4]) +return {method:arr[1],host:arr[2],port:arr[3],httpVersion:arr[4]}; +} +else +{ +var arr=s.match(/^([A-Z]+)\s([^\s]+)\sHTTP\/(\d\.\d)/); +if(arr&&arr[1]&&arr[2]&&arr[3]) +{ +var host=s.match(/Host\:\s+([^\n\s\r]+)/)[1]; +if(host) +{ +var _p=host.split(':',2); +return {method:arr[1],host:_p[0],port:_p[1] ? _p[1]:80,path:arr[2],httpVersion:arr[3]}; +} +} +} +return false; +} + + + + +/** +* 两个buffer对象加起来 +*/ +function buffer_add(buf1,buf2) +{ +var re=new Buffer(buf1.length+buf2.length); +buf1.copy(re); +buf2.copy(re,buf1.length); +return re; +} + +/** +* 从缓存中找到头部结束标记("\r\n\r\n")的位置 +*/ +function buffer_find_body(b) +{ +for(var i=0,len=b.length-3;i Date: Sat, 30 Mar 2013 18:34:10 -0700 Subject: [PATCH 49/59] bug fix --- http.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/http.js b/http.js index cd0702e..140b85c 100644 --- a/http.js +++ b/http.js @@ -64,14 +64,28 @@ try {client.end();} catch (e) { } - }); +server.on("error",function (e){ +console.log("server close"); +console.log(e); +try +{client.end();} +catch (e) +{ } +}); + client.on("close",function (e){ try {server.end();} catch (e) { } }); +client.on("error",function (e){ +try +{server.end();} +catch (e) +{ } +}); if(req.method=='CONNECT') client.write(new Buffer("HTTP/1.1 200 Connection established\r\nConnection: close\r\n\r\n")); else @@ -176,7 +190,7 @@ cluster.fork(); }); } else { -sockserver.listen(local_port); +sockserver.listen(8080); } From 235030267123220b056c45acceaf2411b02ed951 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 31 Mar 2013 09:42:06 +0800 Subject: [PATCH 50/59] Update run.vbs add http support --- run.vbs | 1 + 1 file changed, 1 insertion(+) diff --git a/run.vbs b/run.vbs index 28d7947..295fae7 100644 --- a/run.vbs +++ b/run.vbs @@ -1,2 +1,3 @@ createobject("wscript.shell").run "cmd /c node socksproxy5",0 createobject("wscript.shell").run "cmd /c node socksproxy4",0 +createobject("wscript.shell").run "cmd /c node http",0 From b240d3174e88f33daa4a1a43c10fd16d8a4329ab Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sun, 31 Mar 2013 09:44:26 +0800 Subject: [PATCH 51/59] Update README.rst --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index 69a5ff0..f91fbff 100644 --- a/README.rst +++ b/README.rst @@ -8,8 +8,10 @@ You can run it easily as:: ./socksproxy5.js ./socksproxy4.js + ./http.js under聽windows聽you聽can聽run聽run.vbs This will create a proxy socks5 at ``127.0.0.1`` on port ``8888``. This will create a proxy socks4 socks4a at ``127.0.0.1`` on port ``9999``. +This will create a proxy http https at ``127.0.0.1`` on port ``8080``. You can use this as a good starting point for writing a proxy or a tunnel! From 1d7c7b812b8b7f7075d2d9dcfece955d26873aee Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 22 Jun 2013 09:14:03 +0800 Subject: [PATCH 52/59] Update http.js change Event "close " to "end" if there is an error , use destroy() --- http.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/http.js b/http.js index 140b85c..329354d 100644 --- a/http.js +++ b/http.js @@ -1,11 +1,11 @@ var net=require('net'); var local_port=8080; -//在本地创建一个server监听本地local_port端口 +//锟节憋拷锟截达拷锟斤拷一锟斤拷server锟斤拷锟斤拷锟斤拷锟斤拷local_port锟剿匡拷 var sockserver=net.createServer(function (client) { -//首先监听浏览器的数据发送事件,直到收到的数据包含完整的http请求头 +//锟斤拷锟饺硷拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟捷凤拷锟斤拷锟铰硷拷锟斤拷直锟斤拷锟秸碉拷锟斤拷锟斤拷锟捷帮拷锟斤拷锟斤拷锟斤拷锟斤拷http锟斤拷锟斤拷头 var buffer=new Buffer(0); client.on('data',function (data) { @@ -17,23 +17,23 @@ client.removeAllListeners('data'); relay_connection(req); }); -//从http请求头部取得请求信息后,继续监听浏览器发送数据,同时连接目标服务器,并把目标服务器的数据传给浏览器 +//锟斤拷http锟斤拷锟斤拷头锟斤拷取锟斤拷锟斤拷锟斤拷锟斤拷息锟襟,硷拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟捷o拷同时锟斤拷锟斤拷目锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷目锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟捷达拷锟斤拷锟斤拷锟斤拷锟斤拷 function relay_connection(req) { console.log(req.method+' '+req.host+':'+req.port); -//如果请求不是CONNECT方法(GET, POST),那么替换掉头部的一些东西 +//锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷CONNECT锟斤拷锟斤拷锟斤拷GET, POST锟斤拷锟斤拷锟斤拷么锟芥换锟斤拷头锟斤拷锟斤拷一些锟斤拷锟斤拷 if(req.method!='CONNECT') { -//先从buffer中取出头部 +//锟饺达拷buffer锟斤拷取锟斤拷头锟斤拷 var _body_pos=buffer_find_body(buffer); if(_body_pos<0)_body_pos=buffer.length; var header=buffer.slice(0,_body_pos).toString('utf8'); -//替换connection头 +//锟芥换connection头 header=header.replace(/(proxy\-)connection\:.+\r\n/ig,'') .replace(/Keep\-Alive\:.+\r\n/i,'') .replace("\r\n",'\r\nConnection: close\r\n'); -//替换网址格式(去掉域名部分) +//锟芥换锟斤拷址锟斤拷式(去锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷) if(req.httpVersion=='1.1') { var url=req.path.replace(/http\:\/\/[^\/]+/,''); @@ -42,9 +42,9 @@ if(url.path!=url)header=header.replace(req.path,url); buffer=buffer_add(new Buffer(header,'utf8'),buffer.slice(_body_pos)); } -//建立到目标服务器的连接 +//锟斤拷锟斤拷锟斤拷目锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷 var server=net.createConnection(req.port,req.host); -//交换服务器与浏览器的数据 +//锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷 client.on("data",function (data){ try {server.write(data);} @@ -57,7 +57,7 @@ try catch (e) { } }); -server.on("close",function (e){ +server.on("end",function (e){ console.log("server close"); console.log(e); try @@ -69,12 +69,12 @@ server.on("error",function (e){ console.log("server close"); console.log(e); try -{client.end();} +{client.destroy();} catch (e) { } }); -client.on("close",function (e){ +client.on("end",function (e){ try {server.end();} catch (e) @@ -82,7 +82,7 @@ catch (e) }); client.on("error",function (e){ try -{server.end();} +{server.destroy();} catch (e) { } }); @@ -93,7 +93,7 @@ server.write(buffer); } }); -//处理各种错误 +//锟斤拷锟斤拷锟斤拷锟街达拷锟斤拷 process.on('uncaughtException',function (err) { console.log("\nError!!!!"); @@ -107,9 +107,9 @@ sockserver.on('listening', function() { /** -* 从请求头部取得请求详细信息 -* 如果是 CONNECT 方法,那么会返回 { method,host,port,httpVersion} -* 如果是 GET/POST 方法,那么返回 { metod,host,port,path,httpVersion} +* 锟斤拷锟斤拷锟斤拷头锟斤拷取锟斤拷锟斤拷锟斤拷锟斤拷细锟斤拷息 +* 锟斤拷锟斤拷锟斤拷 CONNECT 锟斤拷锟斤拷锟斤拷锟斤拷么锟结返锟斤拷 { method,host,port,httpVersion} +* 锟斤拷锟斤拷锟斤拷 GET/POST 锟斤拷锟斤拷锟斤拷锟斤拷么锟斤拷锟斤拷 { metod,host,port,path,httpVersion} */ function parse_request(buffer) { @@ -141,7 +141,7 @@ return false; /** -* 两个buffer对象加起来 +* 锟斤拷锟斤拷buffer锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷 */ function buffer_add(buf1,buf2) { @@ -152,7 +152,7 @@ return re; } /** -* 从缓存中找到头部结束标记("\r\n\r\n")的位置 +* 锟接伙拷锟斤拷锟斤拷锟揭碉拷头锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷("\r\n\r\n")锟斤拷位锟斤拷 */ function buffer_find_body(b) { From 69c39dcb3149d9d990c31dd3042ec662438904fa Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 22 Jun 2013 09:17:30 +0800 Subject: [PATCH 53/59] Update socks4.js --- socks4.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/socks4.js b/socks4.js index 77e8d56..bd084c0 100644 --- a/socks4.js +++ b/socks4.js @@ -14,7 +14,7 @@ function createSocksServer() { initIplist(); fs.watch('./ip.txt',function(event,filename){ - if(event=="change") //如果文件变动了 + if(event=="change") //锟斤拷锟斤拷锟侥硷拷锟戒动锟斤拷 { initIplist(); } @@ -128,13 +128,13 @@ function initProxy() { this.proxy.on('data', from_proxy); this.on('data', to_proxy); - this.proxy.on('close', function(had_error) { + this.proxy.on('end', function(had_error) { this.removeListener('data', to_proxy); this.proxy = undefined; this.end(); // errorLog('Proxy closed'); }.bind(this)); - this.on('close', function(had_error) { + this.on('end', function(had_error) { if (this.proxy !== undefined) { this.proxy.removeListener('data', from_proxy); this.proxy.end(); @@ -144,7 +144,7 @@ function initProxy() { this.on('error', function(had_error) { if (this.proxy !== undefined) { this.proxy.removeAllListeners('data'); -this.proxy.end(); +this.proxy.destroy(); } //console.error('The application error'); @@ -152,7 +152,7 @@ this.proxy.end(); }.bind(this)); this.proxy.on('error', function(had_error) { -this.end(); +this.destroy(); //console.error('The proxy error'); }.bind(this)); @@ -179,4 +179,4 @@ console.error(' proxy socket timeout 60000ms'); module.exports = { createServer: createSocksServer -}; \ No newline at end of file +}; From 39e1361095fb2dc26871eec722a302dd63f3bad5 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 22 Jun 2013 09:19:36 +0800 Subject: [PATCH 54/59] Update socksproxy5.js --- socksproxy5.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/socksproxy5.js b/socksproxy5.js index 9e275f8..f6ac222 100644 --- a/socksproxy5.js +++ b/socksproxy5.js @@ -1,4 +1,3 @@ - var net = require('net'), socks5 = require('./socks5.js'); var exec = require('child_process').exec; @@ -60,11 +59,11 @@ var PORT5='8888', } }); - proxy.on('close', function(had_error) { + proxy.on('end', function(had_error) { socket.end(); console.error('The proxy closed'); }.bind(this)); - socket.on('close', function(had_error) { + socket.on('end', function(had_error) { if (this.proxy !== undefined) { proxy.removeAllListeners('data'); proxy.end(); @@ -75,14 +74,14 @@ var PORT5='8888', socket.on('error', function(had_error) { if (this.proxy !== undefined) { proxy.removeAllListeners('data'); - proxy.end(); + proxy.destroy(); } console.error('The application error'); }.bind(this)); proxy.on('error', function(had_error) { - socket.end(); + socket.destroy(); console.error('The proxy error'); }.bind(this)); From 8a35082f61c6c7b1936c79129c83538db8c5f22d Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 24 Aug 2013 15:44:37 +0800 Subject: [PATCH 55/59] use blacklist for ip.txt use blacklist for ip.txt --- socks5.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/socks5.js b/socks5.js index 318d1fe..f3f0a3a 100644 --- a/socks5.js +++ b/socks5.js @@ -74,7 +74,7 @@ function createSocksServer(cb) { initIplist(); fs.watch('./ip.txt',function(event,filename){ - if(event=="change") //如果文件变动了 + if(event=="change") //濡傛灉鏂囦欢鍙樺姩浜 { initIplist(); } @@ -200,7 +200,7 @@ function handleRequest(chunk) { this.udpclient = dgram.createSocket("udp4"); this.udpclient.bind(0); var udpaddress = this.udpclient.address(); -//应答 +//搴旂瓟 var resp = new Buffer(chunk.length); chunk.copy(resp); // rewrite response header @@ -242,12 +242,12 @@ function proxyReady() { function udphandshake(msg, rinfo) { this.removeListener('message', this.udphandshake); //get the udp head -if(rinfo.address==this.clientaddress){//转发 +if(rinfo.address==this.clientaddress){//杞彂 var address=Address.read(msg, 3), offset = 4 + Address.sizeOf(msg, 3), port = chunk.readUInt16BE(offset); this.udpclient.send(msg,offset+2,msg.length-offset-2,port,address); -}else {//收到其它信息 +}else {//鏀跺埌鍏跺畠淇℃伅 var resp = new Buffer(10+msg.length); msg.copy(resp,10); // rewrite response header From 01842c32606736c9245fa8a734c805062a0f5b25 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 24 Aug 2013 15:47:05 +0800 Subject: [PATCH 56/59] use for blacklist use for blacklist --- ip.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ip.txt b/ip.txt index 5ac6dca..092bc2b 100644 --- a/ip.txt +++ b/ip.txt @@ -1 +1 @@ -192.168.0.101;127.0.0.1; \ No newline at end of file +; From 99c26fadbeebf6d1ecbe261f28e916816d142929 Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 24 Aug 2013 15:48:47 +0800 Subject: [PATCH 57/59] use blacklist for ip.txt use blacklist for ip.txt --- socks4.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/socks4.js b/socks4.js index bd084c0..0bfdaf8 100644 --- a/socks4.js +++ b/socks4.js @@ -27,7 +27,7 @@ function createSocksServer() { info('CONNECTED from %s:%s', socket.remoteAddress, socket.remotePort); var idx = ips.indexOf( socket.remoteAddress); - if (idx == -1) { + if (idx != -1) { socket.end(); log('ip pass failed '); From 4cd8e2aed9c2652877b078f462c23628cae3af6d Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 24 Aug 2013 15:57:37 +0800 Subject: [PATCH 58/59] use blacklist for ip.txt use blacklist for ip.txt --- socks5.js | 58 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/socks5.js b/socks5.js index f3f0a3a..b238571 100644 --- a/socks5.js +++ b/socks5.js @@ -74,10 +74,10 @@ function createSocksServer(cb) { initIplist(); fs.watch('./ip.txt',function(event,filename){ - if(event=="change") //濡傛灉鏂囦欢鍙樺姩浜 - { - initIplist(); - } +if(event=="change") //濡傛灉鏂囦欢鍙樺姩浜 +{ + initIplist(); +} }); socksServer.on('listening', function() { @@ -86,11 +86,11 @@ function createSocksServer(cb) { }); socksServer.on('connection', function(socket) { info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); - + var idx = ips.indexOf( socket.remoteAddress); - if (idx == -1) { + if (idx != -1) { socket.end(); - log('ip pass failed '); + log('ip pass failed '); }else { initSocksConnection.bind(socket)(cb); @@ -197,27 +197,31 @@ function handleRequest(chunk) { this.on_accept(this, port, address, proxyReady.bind(this)); } else if(cmd == REQUEST_CMD.UDP_ASSOCIATE){ this.request = chunk; - this.udpclient = dgram.createSocket("udp4"); - this.udpclient.bind(0); - var udpaddress = this.udpclient.address(); + var client = this; + this.udpclient = dgram.createSocket("udp4"); + this.udpclient.bind(0,function(){ + var udpaddress = client.udpclient.address(); + var resp = new Buffer(chunk.length); + chunk.copy(resp); + // rewrite response header + resp[0] = SOCKS_VERSION; + resp[1] = 0x00; + resp[2] = 0x00; + var ad = udpaddress.address.split("."); + resp[4]=Number(ad[0]); + resp[5]=Number(ad[1]); + resp[6]=Number(ad[2]); + resp[7]=Number(ad[3]); + resp.writeUInt16BE(udpaddress.port,8); + client.write(resp); + client.clientaddress=address; + client.clientport=port; + client.udphandshake = udphandshake.bind(client); + client.udpclient.on('message', client.udphandshake); + }); + //搴旂瓟 - var resp = new Buffer(chunk.length); - chunk.copy(resp); - // rewrite response header - resp[0] = SOCKS_VERSION; - resp[1] = 0x00; - resp[2] = 0x00; - var ad = udpaddress.address.split("."); - resp[4]=Number(ad[0]); - resp[5]=Number(ad[1]); - resp[6]=Number(ad[2]); - resp[7]=Number(ad[3]); - resp.writeUInt16BE(udpaddress.port,8); - this.write(resp); - this.clientaddress=address; - this.clientport=port; - this.udphandshake = udphandshake.bind(this); - this.udpclient.on('message', this.udphandshake); + } else { this.end('%d%d', 0x05, 0x01); From 9b720176e98df6dcf4fb1cb828fdff66c110c56d Mon Sep 17 00:00:00 2001 From: sunnyboy00 Date: Sat, 24 Aug 2013 21:27:56 +0800 Subject: [PATCH 59/59] bug fix for udp bug fix for udp --- socks5.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/socks5.js b/socks5.js index b238571..7acb0ba 100644 --- a/socks5.js +++ b/socks5.js @@ -1,5 +1,6 @@ var net = require('net'), dgram = require('dgram'), + dns = require('dns'), util = require('util'), log = function(args) { console.log(args); @@ -86,7 +87,7 @@ if(event=="change") //濡傛灉鏂囦欢鍙樺姩浜 }); socksServer.on('connection', function(socket) { info('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort); - + var idx = ips.indexOf( socket.remoteAddress); if (idx != -1) { socket.end(); @@ -247,10 +248,23 @@ function udphandshake(msg, rinfo) { this.removeListener('message', this.udphandshake); //get the udp head if(rinfo.address==this.clientaddress){//杞彂 +if(msg[3]==1){ var address=Address.read(msg, 3), offset = 4 + Address.sizeOf(msg, 3), port = chunk.readUInt16BE(offset); this.udpclient.send(msg,offset+2,msg.length-offset-2,port,address); +} +else if(msg[3]==3){ +var dnsaddress=Address.read(msg, 3), + offset = 4 + Address.sizeOf(msg, 3), + port = chunk.readUInt16BE(offset); + dns.lookup(dnsaddress,4,function(err, address, family){ +if (err) throw err; +dnsaddress=address; +this.udpclient.send(msg,offset+2,msg.length-offset-2,port,dnsaddress);}); + + +} }else {//鏀跺埌鍏跺畠淇℃伅 var resp = new Buffer(10+msg.length); msg.copy(resp,10);