From cd519708b1214c42733a83420f8aa76147575997 Mon Sep 17 00:00:00 2001 From: cgeek <cem.moreau@gmail.com> Date: Thu, 27 Jul 2017 16:06:42 +0200 Subject: [PATCH] [fix] #1045 Detect the best UPnP available port --- app/modules/bma/index.ts | 10 +--------- app/modules/bma/lib/constants.ts | 4 ++++ app/modules/bma/lib/network.ts | 27 ++++++++++++++++++++------- test/integration/tools/toolbox.ts | 5 +++-- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/modules/bma/index.ts b/app/modules/bma/index.ts index ae281165e..7b4a958c7 100644 --- a/app/modules/bma/index.ts +++ b/app/modules/bma/index.ts @@ -147,15 +147,7 @@ export const BmaDependency = { methods: { noLimit: () => BMALimitation.noLimit(), bma, sanitize, dtos, - upnpConf: Network.upnpConf, - getRandomPort: Network.getRandomPort, - listInterfaces: Network.listInterfaces, - getEndpoint: getEndpoint, - getMainEndpoint: (conf:NetworkConfDTO) => Promise.resolve(getEndpoint(conf)), - getBestLocalIPv6: Network.getBestLocalIPv6, - getBestLocalIPv4: Network.getBestLocalIPv4, - createServersAndListen: Network.createServersAndListen, - http2raw + getMainEndpoint: (conf:NetworkConfDTO) => Promise.resolve(getEndpoint(conf)) } } } diff --git a/app/modules/bma/lib/constants.ts b/app/modules/bma/lib/constants.ts index 5dd915869..18abf2eb7 100644 --- a/app/modules/bma/lib/constants.ts +++ b/app/modules/bma/lib/constants.ts @@ -1,4 +1,8 @@ export const BMAConstants = { + + BMA_PORTS_START: 10901, + BMA_PORTS_END: 10999, + ENTITY_BLOCK: 'block', ENTITY_IDENTITY: 'identity', ENTITY_CERTIFICATION: 'certification', diff --git a/app/modules/bma/lib/network.ts b/app/modules/bma/lib/network.ts index ea20a3eda..cdb146801 100644 --- a/app/modules/bma/lib/network.ts +++ b/app/modules/bma/lib/network.ts @@ -29,7 +29,7 @@ export const Network = { listInterfaces: listInterfaces, - upnpConf: (noupnp:boolean, logger:any) => upnpConf(noupnp, logger), + upnpConf, getRandomPort: getRandomPort, @@ -335,22 +335,22 @@ function listInterfaces() { } async function upnpConf (noupnp:boolean, logger:any) { + const client = require('nnupnp').createClient(); + // Look for 2 random ports + const publicPort = await getAvailablePort(client) + const privatePort = publicPort const conf:NetworkConfDTO = { - port: 10901, + port: privatePort, ipv4: '127.0.0.1', ipv6: '::1', dos: null, upnp: false, httplogs: false, - remoteport: 10901, + remoteport: publicPort, remotehost: null, remoteipv4: null, remoteipv6: null } - const client = require('nnupnp').createClient(); - // Look for 2 random ports - const privatePort = getRandomPort(conf); - const publicPort = privatePort; logger && logger.info('Checking UPnP features...'); if (noupnp) { throw Error('No UPnP'); @@ -374,6 +374,19 @@ async function upnpConf (noupnp:boolean, logger:any) { return conf; } +async function getAvailablePort(client:any) { + const mappings:{ public: { port:number }}[] = await Q.nbind(client.getMappings, client)(); + const externalPortsUsed = mappings.map(m => m.public.port) + let availablePort = BMAConstants.BMA_PORTS_START + while (externalPortsUsed.indexOf(availablePort) !== -1 && availablePort <= BMAConstants.BMA_PORTS_END) { + availablePort++ + } + if (availablePort > BMAConstants.BMA_PORTS_END) { + throw "No port available for UPnP" + } + return availablePort +} + function getRandomPort(conf:NetworkConfDTO) { if (conf && conf.remoteport) { return conf.remoteport; diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts index 2efb96025..1205a3fbd 100644 --- a/test/integration/tools/toolbox.ts +++ b/test/integration/tools/toolbox.ts @@ -6,6 +6,7 @@ import * as stream from "stream" import {RevocationDTO} from "../../../app/lib/dto/RevocationDTO" import {IdentityDTO} from "../../../app/lib/dto/IdentityDTO" import {PeerDTO} from "../../../app/lib/dto/PeerDTO" +import {Network} from "../../../app/modules/bma/lib/network"; const _ = require('underscore'); const rp = require('request-promise'); @@ -135,7 +136,7 @@ export const fakeSyncServer = async (readBlocksMethod:any, readParticularBlockMe processRequest: () => { /* Does nothing */ } }; - const fakeServer = await require('../../../app/modules/bma').BmaDependency.duniter.methods.createServersAndListen("Fake Duniter Server", { conf: {} }, [{ + const fakeServer = await Network.createServersAndListen("Fake Duniter Server", new Server("", true, {}), [{ ip: host, port: port }], NO_HTTP_LOGS, logger, NO_STATIC_PATH, (app:any, httpMethods:any) => { @@ -170,7 +171,7 @@ export const fakeSyncServer = async (readBlocksMethod:any, readParticularBlockMe return readParticularBlockMethod(number); }, dtos.Block, noLimit); - }); + }, null) await fakeServer.openConnections(); return { -- GitLab