Created
August 25, 2013 03:02
-
-
Save kasuganosora/6331728 to your computer and use it in GitHub Desktop.
local SOCK5 proxy demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
net = require("net") | |
util = require("util") | |
AUTHENTICATION = | |
NOAUTH: 0x00 | |
GSSAOI: 0x01 | |
USERPASS: 0x02 | |
NONE:0xFF | |
ADDRTYPE = | |
IP_V4: 0x01 | |
DNS: 0x03 | |
IP_v6: 0x04 | |
REQUEST_CMD = | |
CONNECT: 0x01 | |
BIND: 0x02 | |
UDP_ASSOCIATE: 0x03 | |
REP_CMD_TYPE = | |
SUCCEEDED: 0x00 | |
GENERAL_SOCKS_SERVER_FAILURE: 0x01 | |
CONNECTION_NOT_ALLOWED_BY_RULESET: 0x02 | |
NETWORK_UNREACHABLE: 0x03 | |
HOST_UNREACHABLE: 0x04 | |
CONNECTION_REFUSED: 0x05 | |
TTL_EXPIRED: 0x06 | |
COMMAND_NOT_SUPPRTED: 0x07 | |
ADDRESS_TYPE_NOT_SUPPORTED: 0x08 | |
TO_XFF_UNASSIGNED: 0x09 | |
SOCKS_VER = 0x05 | |
inetNtoa = (buf)-> | |
buf[0] + "." + buf[1] + "." + buf[2] + "." + buf[3] | |
innetAton = (ipStr)-> | |
parts = ipStr.split(".") | |
unless parts.length is 4 | |
null | |
buf = new Buffer(4) | |
i = 0; | |
while i < 4 | |
buf[i] = +parts[i] | |
i++ | |
buf | |
server = net.createServer (connection)-> | |
stage =0 | |
headerLength = 0 | |
remote = 0 | |
cachedPiess = [] | |
connection.on "data",(data)-> | |
if stage is 5 | |
connection.pause() unless remote.write(data) | |
if stage is 0 | |
tempBuf = new Buffer(2) | |
tempBuf.writeUInt8 SOCKS_VER,0 | |
tempBuf.writeUInt8 REP_CMD_TYPE.SUCCEEDED,1 | |
connection.write tempBuf | |
stage = 1 | |
return | |
if stage is 1 | |
try | |
cmd = data[1] | |
addrType = data[3] | |
unless cmd is REQUEST_CMD.CONNECT | |
util.log("unsupported cmd: " + cmd) | |
reply = new Buffer(4) | |
reply.writeUInt8 SOCKS_VER,0 | |
reply.writeUInt8 REP_CMD_TYPE.COMMAND_NOT_SUPPRTED ,1 | |
reply.writeUInt8 0x00,2 | |
reply.writeUInt8 0x00,3 | |
reply.writeUInt8 0x01,3 | |
connection.end reply | |
return | |
if addrType is ADDRTYPE.DNS | |
addrLen = data[4] | |
else unless addrType is ADDRTYPE.IP_v4 | |
util.log("unsupported addrtype: " + addrtype) | |
connection.end() | |
return | |
if addrType is ADDRTYPE.IP_v4 | |
remoteAddr = inetNtoa(data.slice(4,8)) | |
remotePort = data.readUInt16BE(8) | |
headerLength = 10 | |
else | |
# DNS | |
remoteAddr = data.slice(5, 5 + addrLen).toString("binary") | |
remotePort = data.readUInt16BE(5 + addrLen) | |
headerLength = 5 + addrLen + 2 | |
buf = new Buffer(10) | |
# REP_CMD_TYPE.SUCCEEDED | |
buf.write("\u0005\u0000\u0000\u0001", 0, 4, "binary") | |
buf.write("\u0000\u0000\u0000\u0000", 4, 4, "binary") | |
buf.writeInt16BE(2222, 8) | |
connection.write(buf) | |
remote = net.connect(remotePort,remoteAddr,()-> | |
util.log("connecting " + remoteAddr + ":" + remotePort); | |
i = 0 | |
while i < cachedPiess.length | |
piece = cachedPiess[i] | |
remote.write piece | |
i++ | |
stage = 5 | |
) | |
remote.on "data",(data)-> | |
remote.pause unless connection.write(data) | |
remote.on "end",()-> | |
cachedPiess = null | |
connection.end() | |
remote.on "error",(e)-> | |
cachedPiess = null | |
util.log("remote " + remoteAddr + ":" + remotePort + " error: " + e); | |
if stage is 4 | |
connection.destroy() | |
else | |
connection.end() | |
remote.on "drain",()-> | |
connection.resume() | |
remote.setTimeout 3000,()=> | |
connection.end() | |
remote.destroy() | |
if data.length > headerLength | |
buf = new Buffer( data.length - headerLength) | |
data.copy(buf,0,headerLength) | |
cachedPiess.push buf | |
buf = null | |
stage = 4 | |
catch e | |
util.log e | |
connection.destroy() | |
remote.destroy() if remote | |
else | |
cachedPiess.push(data) if stage is 4 | |
connection.on "end",()-> | |
remote.destroy() if remote | |
connection.on "error",(e)-> | |
util.log("local error: " + e) | |
remote.destroy() if remote | |
connection.on "drain",()-> | |
remote.resume() if remote and stage is 5 | |
connection.setTimeout 3000,()=> | |
remote.destroy() if remote | |
connection.destroy() | |
server.on "error",(e)-> | |
util.log("Address in use, aborting") if e.code is "EADDRINUSE" | |
process.exit 1 | |
server.listen 1989 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment