From 509841104b2d60b21f7ea547457f16eb191ad696 Mon Sep 17 00:00:00 2001 From: Roman Shtylman Date: Mon, 14 Apr 2014 15:28:09 -0400 Subject: [PATCH] fix for RangeError stack size exceeded This error would happen when there was a problem connecting to the local server. The local.on('error') handler should have been a 'once' handler because we emit the error again if it isn't a CONNREFUSED. So in the case of a CONNRESET, it would trigger an infinite loop since the error was being emitted back onto the local variable. Instead we just close the remote socket and let a new one takes its place. fixes #36 --- client.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client.js b/client.js index bddb394..b78ac33 100644 --- a/client.js +++ b/client.js @@ -87,13 +87,13 @@ TunnelCluster.prototype.open = function() { }); function conn_local() { - debug('connecting locally to %s:%d', local_host, local_port); - if (remote.destroyed) { + debug('remote destroyed'); self.emit('dead'); return; } + debug('connecting locally to %s:%d', local_host, local_port); remote.pause(); // connection to local http server @@ -103,19 +103,24 @@ TunnelCluster.prototype.open = function() { }); function remote_close() { + debug('remote close'); self.emit('dead'); local.end(); }; remote.once('close', remote_close); - local.on('error', function(err) { + // TODO some languages have single threaded servers which makes opening up + // multiple local connections impossible. We need a smarter way to scale + // and adjust for such instances to avoid beating on the door of the server + local.once('error', function(err) { + debug('local error %s', err.message); local.end(); remote.removeListener('close', remote_close); if (err.code !== 'ECONNREFUSED') { - return local.emit('error', err); + return remove.end(); } // retrying connection to local server @@ -146,8 +151,8 @@ TunnelCluster.prototype.open = function() { // tunnel is considered open when remote connects remote.once('connect', function() { self.emit('open', remote); + conn_local(); }); - remote.once('connect', conn_local); }; var Tunnel = function(opt) {