From ee77d6a41b71ffe3c48bfdab89df4206df310e78 Mon Sep 17 00:00:00 2001 From: Jonathan Chan Date: Mon, 21 Jan 2019 22:59:01 -0600 Subject: [PATCH] added option to specify port range for client ports --- bin/server | 12 +++++++++++- lib/ClientManager.js | 6 +++++- lib/TunnelAgent.js | 28 ++++++++++++++++++++-------- package.json | 3 ++- yarn.lock | 20 +++++++++++++++++++- 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/bin/server b/bin/server index a6bba9d8..bb216cd5 100755 --- a/bin/server +++ b/bin/server @@ -11,7 +11,7 @@ import CreateServer from '../server'; const debug = Debug('localtunnel'); const argv = optimist - .usage('Usage: $0 --port [num]') + .usage('Usage: $0 [--port num] [--address address] [--domain domain] [--max-sockets 10] [--client-min-port-range 3000 --client-max-port-range 3500]') .options('secure', { default: false, describe: 'use this flag to indicate proxy over https' @@ -31,6 +31,14 @@ const argv = optimist default: 10, describe: 'maximum number of tcp sockets each client is allowed to establish at one time (the tunnels)' }) + .options('client-min-port-range', { + default: 1024, + describe: 'Port start range to use for localtunnel clients to connect to' + }) + .options('client-max-port-range', { + default: 65535, + describe: 'Port end range to use for localtunnel clients to connect to' + }) .argv; if (argv.help) { @@ -42,6 +50,8 @@ const server = CreateServer({ max_tcp_sockets: argv['max-sockets'], secure: argv.secure, domain: argv.domain, + client_min_port_range: argv['client-min-port-range'], + client_max_port_range: argv['client-max-port-range'] }); server.listen(argv.port, argv.address, () => { diff --git a/lib/ClientManager.js b/lib/ClientManager.js index e1a78386..2d9c2d86 100644 --- a/lib/ClientManager.js +++ b/lib/ClientManager.js @@ -38,9 +38,13 @@ class ClientManager { } const maxSockets = this.opt.max_tcp_sockets; + const client_min_port_range = this.opt.client_min_port_range; + const client_max_port_range = this.opt.client_max_port_range; const agent = new TunnelAgent({ clientId: id, - maxSockets: 10, + maxSockets: maxSockets, + client_min_port_range: client_min_port_range, + client_max_port_range: client_max_port_range }); const client = new Client({ diff --git a/lib/TunnelAgent.js b/lib/TunnelAgent.js index efc2231b..5b8115d4 100644 --- a/lib/TunnelAgent.js +++ b/lib/TunnelAgent.js @@ -4,8 +4,12 @@ import assert from 'assert'; import log from 'book'; import Debug from 'debug'; +import { getPort } from 'portfinder'; const DEFAULT_MAX_SOCKETS = 10; +const DEFAULT_MIN_PORT_RANGE = 1024; +const DEFAULT_MAX_PORT_RANGE = 65535; + // Implements an http.Agent interface to a pool of tunnel sockets // A tunnel socket is a connection _from_ a client that will // service http requests. This agent is usable wherever one can use an http.Agent @@ -31,6 +35,9 @@ class TunnelAgent extends Agent { this.connectedSockets = 0; this.maxTcpSockets = options.maxTcpSockets || DEFAULT_MAX_SOCKETS; + this.client_min_port_range = options.client_min_port_range || DEFAULT_MIN_PORT_RANGE; + this.client_max_port_range = options.client_max_port_range || DEFAULT_MAX_PORT_RANGE; + // new tcp server to service requests for this client this.server = net.createServer(); @@ -63,14 +70,19 @@ class TunnelAgent extends Agent { }); return new Promise((resolve) => { - server.listen(() => { - const port = server.address().port; - this.debug('tcp server listening on port: %d', port); - - resolve({ - // port for lt client tcp connections - port: port, - }); + getPort({ + port: this.client_min_port_range, // minimum port + stopPort: this.client_max_port_range // maximum port + }, (err,port) => { + server.listen(port,() => { + const port = server.address().port; + this.debug('tcp server listening on port: %d', port); + + resolve({ + // port for lt client tcp connections + port: port, + }); + }); }); }); } diff --git a/package.json b/package.json index 0693b8dd..999a1de0 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "localenv": "0.2.2", "optimist": "0.6.1", "pump": "3.0.0", - "tldjs": "2.3.1" + "tldjs": "2.3.1", + "portfinder": "1.0.20" }, "devDependencies": { "mocha": "5.1.1", diff --git a/yarn.lock b/yarn.lock index 9ad744bf..087987de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33,6 +33,10 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -179,6 +183,12 @@ debug@*, debug@3.1.0, debug@^3.1.0: dependencies: ms "2.0.0" +debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -666,7 +676,7 @@ minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" -mkdirp@0.5.1: +mkdirp@0.5.1, mkdirp@0.5.x: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -825,6 +835,14 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" +portfinder@1.0.20: + version "1.0.20" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"