From: Jack Allnutt Date: Thu, 21 Mar 2013 06:29:40 +0000 (+0000) Subject: Tweaking SocksConnection internals/API X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=bf6d219be77fc4427f76e0b223f8c5b84d28ad00;p=KiwiIRC.git Tweaking SocksConnection internals/API SocksConnection's signature is now: SocksConnection({host, port, ssl}, {host, port, user, pass}). SocksConnection now emits 'connect' rather than 'socksConnect'. SocksConnection.destination replaced with SocksConnection.remoteAddress and .remotePort. SocksConnection.socks removed, data is now passed by fn.bind() internally. socksSocket errors are now emitted by SocksConnection rather than logged to the console. The socksSocket error handler is removed once a successful connection has been established through the SOCKS proxy. SocksConnection is now exported. --- diff --git a/server/socks.js b/server/socks.js index 2a4853f..c1b0047 100755 --- a/server/socks.js +++ b/server/socks.js @@ -5,22 +5,45 @@ var net = require('net'), crypto = require('crypto'), ipaddr = require('ipaddr.js'); +/* + * API: + * var s = new SocksConnection({host: irc.example.com, port: 6667, ssl: false}, {host: socks.example.net, port: 1080, user: null, pass: null}); + * s.on('connect', function (socket) { + * // send data to socket + * }); + */ + var SocksConnection = function (destination, socks) { var that = this; EventEmitter.call(this); - this.socks = socks; - this.destination = destination; + this.remoteAddress = destination.host; + this.remotePort = destination.port; + this.ssl = destination.ssl; + + this.socksAddress = null; + this.socksPort = null; - this.socksSocket = net.connect({host: socks.host, port: socks.port}, socksConnected.bind(this)); - this.socksSocket.once('data', socksAuth.bind(this)); - this.socksSocket.on('error', socksError); + this.socksSocket = net.connect({host: socks.host, port: socks.port}, socksConnected.bind(this, !(!socks.user))); + this.socksSocket.once('data', socksAuth.bind(this, {user: socks.user || null, pass: socks.pass || null})); + this.socksSocket.on('error', this._error); }; util.inherits(SocksConnection, EventEmitter); -var socksConnected = function () { - if (this.socks.auth) { +module.exports = SocksConnection; + +SocksConnection.prototype.dispose = function () { + this.socksSocket.destroy(); + this.removeAllListeners(); +} + +SocksConnection.prototype._error = function (err) { + this.emit('error', err); +} + +var socksConnected = function (auth) { + if (auth) { this.socksSocket.write('\x05\x02\x02\x00'); // SOCKS version 5, supporting two auth methods // username/password and 'no authentication' } else { @@ -28,7 +51,7 @@ var socksConnected = function () { } }; -var socksAuth = function (data) { +var socksAuth = function (auth, data) { var bufs = []; switch (data.readUInt8(1)) { case 255: @@ -37,21 +60,21 @@ var socksAuth = function (data) { break; case 2: bufs[0] = new Buffer([1]); - bufs[1] = new Buffer([Buffer.byteLength(this.socks.auth.user)]); - bufs[2] = new Buffer(this.socks.auth.user); - bufs[3] = new Buffer([Buffer.byteLength(this.socks.auth.pass)]); - bufs[4] = new Buffer(this.socks.auth.pass); + bufs[1] = new Buffer([Buffer.byteLength(auth.user)]); + bufs[2] = new Buffer(auth.user); + bufs[3] = new Buffer([Buffer.byteLength(auth.pass)]); + bufs[4] = new Buffer(auth.pass); this.socksSocket.write(Buffer.concat(bufs)); this.socksSocket.once('data', socksAuthStatus.bind(this)); break; default: - socksRequest.call(this, this.destination.host, this.destination.port); + socksRequest.call(this, this.remoteAddress, this.remotePort); } }; var socksAuthStatus = function (data) { if (data.readUInt8(1) === 1) { - socksRequest.call(this, this.destination.host, this.destination.port); + socksRequest.call(this, this.remoteHost, this.remotePort); } else { this.emit('error', 'SOCKS: Authentication failed'); this.socksSocket.destroy(); @@ -157,18 +180,16 @@ var starttls = function () { pair.cleartext.authorised = false; pair.on('secure', function () { - that.emit('socksConnect', pair.cleartext, pair.encrypted); + that.emit('connect', pair.cleartext, this.socksSocket); + that.socksSocket.removeListener('error', that._error); }); } -var socksError = function (err) { - console.log(err); -} - var emitSocket = function () { - if (this.destination.ssl) { + if (this.ssl) { starttls.call(this); } else { - this.emit('socksConnect', this.socksSocket); + this.emit('connect', this.socksSocket); + this.socksSocket.removeListener('error', this._error); } };