Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for NAT traversal techniques #1051

Open
wants to merge 7 commits into
base: master
from
Open
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

Add upnp nat traversal

  • Loading branch information
yciabaud committed Feb 18, 2017
commit 65e1ff3e9abb2ef705907e0791c501b5a08c57d9
@@ -19,6 +19,7 @@ var randombytes = require('randombytes')
var speedometer = require('speedometer')
var zeroFill = require('zero-fill')

var NatTraversal = require('./lib/nat-traversal') // browser exclude
var TCPPool = require('./lib/tcp-pool') // browser exclude
var Torrent = require('./lib/torrent')

@@ -106,6 +107,10 @@ function WebTorrent (opts) {
if (global.WRTC && !self.tracker.wrtc) self.tracker.wrtc = global.WRTC
}

if (typeof NatTraversal === 'function') {
self._natTraversal = new NatTraversal()
}

if (typeof TCPPool === 'function') {
self._tcpPool = new TCPPool(self)
} else {
@@ -128,7 +133,12 @@ function WebTorrent (opts) {

self.dht.once('listening', function () {
var address = self.dht.address()
if (address) self.dhtPort = address.port
if (address) {
self.dhtPort = address.port
if (self._natTraversal) {
self._natTraversal.portMapping(self.dhtPort)
}
}
})

// Ignore warning when there are > 10 torrents in the client
@@ -425,6 +435,18 @@ WebTorrent.prototype._destroy = function (err, cb) {
})
}

if (self._natTraversal) {
tasks.push(function (cb) {
if (self.dhtPort) {
self._natTraversal.portUnMapping(self.dhtPort)
}
if (self.torrentPort) {
self._natTraversal.portUnMapping(self.torrentPort)
}
self._natTraversal.destroy(cb)
})
}

parallel(tasks, cb)

if (err) self.emit('error', err)
@@ -441,7 +463,12 @@ WebTorrent.prototype._onListening = function () {
// Sometimes server.address() returns `null` in Docker.
// WebTorrent issue: https://github.com/feross/bittorrent-swarm/pull/18
var address = this._tcpPool.server.address()
if (address) this.torrentPort = address.port
if (address) {
this.torrentPort = address.port
if (this._natTraversal) {
this._natTraversal.portMapping(this.torrentPort)
}
}
}

this.emit('listening')
@@ -0,0 +1,69 @@

module.exports = NatTraversal

var debug = require('debug')('webtorrent:nat-traversal')
var natUpnp = require('nat-upnp') // browser exclude

function NatTraversal () {
var self = this

debug('Create UPnP client')
self._upnpClient = natUpnp.createClient()
self.ttl = 60 * 30
self.timeout = self.ttl - 60
self.intervals = {}
}

NatTraversal.prototype.portMapping = function (port, cb) {
var self = this

debug('Mapping port %d on router using UPnP', port)
self._upnpClient.portMapping({
public: port,
private: port,
description: 'WebTorrent',
ttl: self.ttl
}, function (err) {
if (err) {
return typeof cb === 'function' && cb(err)
}
self.intervals[port] = setInterval(NatTraversal.prototype.portMapping.bind(self, port), self.timeout)
debug('Port %d mapped on router using UPnP', port)
if (typeof cb === 'function') cb()
})
}

NatTraversal.prototype.portUnMapping = function (port, cb) {
var self = this
if (!self.intervals[port]) return typeof cb === 'function' && cb(new Error('Port not mapped'))

debug('Unmapping port %d on router using UPnP', port)
clearInterval(self.intervals[port])
delete self.intervals[port]

self._upnpClient.portUnmapping({
public: port
}, function (err) {
if (err) {
return typeof cb === 'function' && cb(err)
}
debug('Port %d unmapped on router using UPnP', port)
if (typeof cb === 'function') cb()
})
}

NatTraversal.prototype.destroy = function (cb) {
var self = this

// Clear all intervals
Object.keys(self.intervals).forEach(function (port) {
self.portUnMapping(port)
})

// Waiting next tick to prevent breaking some sockets
process.nextTick(function () {
self._upnpClient.close()
debug('UPnP client closed')
cb()
})
}
@@ -8,11 +8,13 @@
"url": "https://webtorrent.io"
},
"browser": {
"./lib/nat-traversal.js": false,
"./lib/server.js": false,
"./lib/tcp-pool.js": false,
"bittorrent-dht/client": false,
"fs-chunk-store": "memory-chunk-store",
"load-ip-set": false,
"nat-upnp": false,
"net": false,
"os": false,
"ut_pex": false
@@ -41,6 +43,7 @@
"memory-chunk-store": "^1.2.0",
"mime": "^1.3.4",
"multistream": "^2.0.5",
"nat-upnp": "^1.0.4",
"package-json-versionify": "^1.0.2",
"parse-torrent": "^5.8.0",
"pump": "^1.0.1",
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.