diff --git a/browser/wsproxy.js b/browser/wsproxy.js index fc2792d3..58e3b1cf 100644 --- a/browser/wsproxy.js +++ b/browser/wsproxy.js @@ -213,6 +213,10 @@ WSProxy.prototype._handleConnect = function _handleConnect(ws, port, host, nonce }); }); + socket.on('timeout', function() { + ws.emit('tcp timeout'); + }); + socket.on('close', function() { self.log('Closing %s (%s).', state.remoteHost, state.host); ws.emit('tcp close'); @@ -225,6 +229,26 @@ WSProxy.prototype._handleConnect = function _handleConnect(ws, port, host, nonce socket.write(new Buffer(data, 'hex')); }); + ws.on('tcp keep alive', function(enable, delay) { + socket.setKeepAlive(enable, delay); + }); + + ws.on('tcp no delay', function(enable) { + socket.setNoDelay(enable); + }); + + ws.on('tcp set timeout', function(timeout) { + socket.setTimeout(timeout); + }); + + ws.on('tcp pause', function() { + socket.pause(); + }); + + ws.on('tcp resume', function() { + socket.resume(); + }); + ws.on('disconnect', function() { socket.destroy(); }); diff --git a/lib/net/peer.js b/lib/net/peer.js index 5b768743..a3db335a 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -387,6 +387,8 @@ Peer.prototype.bind = function bind(socket) { self.lastRecv = util.ms(); self.feedParser(chunk); }); + + this.socket.setNoDelay(true); }; /** diff --git a/lib/net/pool.js b/lib/net/pool.js index b6726c0b..c1171ca8 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -395,6 +395,8 @@ Pool.prototype.listen = co(function* listen() { if (!this.options.listen) return; + this.server.maxConnections = this.options.maxInbound; + yield this.server.listen(this.options.port, this.options.host); }); diff --git a/lib/net/proxysocket.js b/lib/net/proxysocket.js index 6d9d5949..96f30e9e 100644 --- a/lib/net/proxysocket.js +++ b/lib/net/proxysocket.js @@ -84,6 +84,10 @@ ProxySocket.prototype._init = function _init() { self.emit('error', err); }); + this.socket.on('tcp timeout', function() { + self.emit('timeout'); + }); + this.socket.on('disconnect', function() { if (self.closed) return; @@ -151,6 +155,20 @@ ProxySocket.prototype.connect = function connect(port, host) { this.sendBuffer.length = 0; }; +ProxySocket.prototype.setKeepAlive = function setKeepAlive(enable, delay) { + this.socket.emit('tcp keep alive', enable, delay); +}; + +ProxySocket.prototype.setNoDelay = function setNoDelay(enable) { + this.socket.emit('tcp no delay', enable); +}; + +ProxySocket.prototype.setTimeout = function setTimeout(timeout, callback) { + this.socket.emit('tcp set timeout', timeout); + if (callback) + this.on('timeout', callback); +}; + ProxySocket.prototype.write = function write(data, callback) { if (!this.info) { this.sendBuffer.push(data); diff --git a/lib/net/socks.js b/lib/net/socks.js index 36873ed8..0a6d6874 100644 --- a/lib/net/socks.js +++ b/lib/net/socks.js @@ -553,13 +553,14 @@ function Proxy(host, port, user, pass) { this.bytesRead = 0; this.remoteAddress = null; this.remotePort = 0; + this.ops = []; } util.inherits(Proxy, EventEmitter); Proxy.prototype.connect = co(function* connect(port, host) { var self = this; - var options, socket; + var i, options, socket; assert(!this.socket, 'Already connected.'); @@ -600,9 +601,48 @@ Proxy.prototype.connect = co(function* connect(port, host) { self.emit('drain'); }); + this.socket.on('timeout', function() { + self.emit('timeout'); + }); + + for (i = 0; i < this.ops.length; i++) + this.ops[i].call(this); + + this.ops.length = 0; + this.emit('connect'); }); +Proxy.prototype.setKeepAlive = function setKeepAlive(enable, delay) { + if (!this.socket) { + this.ops.push(function() { + this.socket.setKeepAlive(enable, delay); + }); + return; + } + this.socket.setKeepAlive(enable, delay); +}; + +Proxy.prototype.setNoDelay = function setNoDelay(enable) { + if (!this.socket) { + this.ops.push(function() { + this.socket.setNoDelay(enable); + }); + return; + } + this.socket.setNoDelay(enable); +}; + +Proxy.prototype.setTimeout = function setTimeout(timeout, callback) { + if (!this.socket) { + this.ops.push(function() { + this.socket.setTimeout(timeout, callback); + }); + return; + } + this.socket.setTimeout(timeout, callback); +}; + Proxy.prototype.write = function write(data, callback) { assert(this.socket, 'Not connected.'); this.bytesWritten += data.length; diff --git a/lib/net/tcp-browser.js b/lib/net/tcp-browser.js index f21a96e0..ee0076a2 100644 --- a/lib/net/tcp-browser.js +++ b/lib/net/tcp-browser.js @@ -16,18 +16,24 @@ tcp.createSocket = function createSocket(port, host, proxy) { tcp.createServer = function createServer() { var server = new EventEmitter(); + server.listen = function listen(port, host) { server.emit('listening'); return Promise.resolve(); }; + server.close = function close() { return Promise.resolve(); }; + server.address = function address() { return { address: '127.0.0.1', port: 0 }; }; + + server.maxConnections = undefined; + return server; }; diff --git a/lib/net/tcp.js b/lib/net/tcp.js index 8ded91f8..f5f1327e 100644 --- a/lib/net/tcp.js +++ b/lib/net/tcp.js @@ -37,6 +37,15 @@ tcp.createServer = function createServer() { return server.address(); }; + ee.__defineGetter__('maxConnections', function() { + return server.maxConnections; + }); + + ee.__defineSetter__('maxConnections', function(value) { + server.maxConnections = value; + return server.maxConnections; + }); + server.on('listening', function() { ee.emit('listening'); });