Skip to content
Snippets Groups Projects
Commit 3eed409d authored by Cédric Moreau's avatar Cédric Moreau
Browse files

[enh] #1084 WS2P: always keep the same UPnP port opened during a session

parent 1bf4910e
No related branches found
No related tags found
No related merge requests found
import {WS2PConstants} from "./constants" import {WS2PConstants} from "./constants"
const upnp = require('nnupnp'); const upnp = require('nnupnp');
const Q = require('q');
interface UPnPBinding { export interface UPnPBinding {
remotehost:string remotehost:string
host:string host:string
port:number port:number
...@@ -20,25 +19,39 @@ export class WS2PUpnp { ...@@ -20,25 +19,39 @@ export class WS2PUpnp {
async checkUPnPisAvailable() { async checkUPnPisAvailable() {
try { try {
await Q.nbind(this.client.externalIp, this.client)() await new Promise((resolve, reject) => {
this.client.externalIp((err:any, res:any) => {
if (err) {
resolve(true)
} else {
resolve(false)
}
})
})
return true return true
} catch (err) { } catch (err) {
return false return false
} }
} }
async getRemoteEndpoint() { getCurrentConfig() {
return !this.currentConfig ? '' : ['WS2P', this.currentConfig.remotehost, this.currentConfig.port].join(' ') return this.currentConfig
} }
/**
* Always open the same port during an execution of Duniter.
* @returns { host:string, port:number }
*/
openPort() { openPort() {
return Q.Promise(async (resolve:any, reject:any) => { return new Promise<{ host:string, port:number }>(async (resolve:any, reject:any) => {
const upnpBinding = await WS2PUpnp.getAvailablePort(this.client) if (!this.currentConfig) {
this.logger.trace('WS2P: mapping external port %s to local %s using UPnP...', upnpBinding.port, [upnpBinding.host, upnpBinding.port].join(':')) this.currentConfig = await WS2PUpnp.getAvailablePort(this.client)
}
this.logger.trace('WS2P: mapping external port %s to local %s using UPnP...', this.currentConfig.port, [this.currentConfig.host, this.currentConfig.port].join(':'))
const client = upnp.createClient() const client = upnp.createClient()
client.portMapping({ client.portMapping({
'public': upnpBinding.port, 'public': this.currentConfig.port,
'private': upnpBinding.port, 'private': this.currentConfig.port,
'ttl': WS2PConstants.WS2P_UPNP_TTL 'ttl': WS2PConstants.WS2P_UPNP_TTL
}, (err:any) => { }, (err:any) => {
client.close() client.close()
...@@ -46,8 +59,7 @@ export class WS2PUpnp { ...@@ -46,8 +59,7 @@ export class WS2PUpnp {
this.logger.warn(err) this.logger.warn(err)
return reject(err) return reject(err)
} }
this.currentConfig = upnpBinding resolve(this.currentConfig)
resolve(upnpBinding)
}) })
}) })
} }
...@@ -96,14 +108,11 @@ export class WS2PUpnp { ...@@ -96,14 +108,11 @@ export class WS2PUpnp {
port:number port:number
} }
}[] = await WS2PUpnp.getUPnPMappings(client) }[] = await WS2PUpnp.getUPnPMappings(client)
const ipOfPort:string[] = []
const externalPortsUsed = mappings.map((m) => { const externalPortsUsed = mappings.map((m) => {
ipOfPort.push(m.private.host)
return m.public.port return m.public.port
}) })
let availablePort = WS2PConstants.WS2P_PORTS_START let availablePort = WS2PConstants.WS2P_PORTS_START
while (externalPortsUsed.indexOf(availablePort) !== -1 while (externalPortsUsed.indexOf(availablePort) !== -1
&& ipOfPort[externalPortsUsed.indexOf(availablePort)] !== localIP
&& availablePort <= WS2PConstants.WS2P_PORTS_END) { && availablePort <= WS2PConstants.WS2P_PORTS_END) {
availablePort++ availablePort++
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment