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 uTP support #1328

Closed
wants to merge 7 commits into from
Closed
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

Fix docs / new test no utp

  • Loading branch information
pldubouilh committed Mar 7, 2018
commit 35aedfbbff5e883bca8199a1809f272d7e3567ed
@@ -58,7 +58,8 @@ If `opts` is specified, then the default options (shown below) will be overridde
peerId: String|Buffer, // Wire protocol peer ID (default=randomly generated)
tracker: Boolean|Object, // Enable trackers (default=true), or options object for Tracker
dht: Boolean|Object, // Enable DHT (default=true), or options object for DHT
webSeeds: Boolean // Enable BEP19 web seeds (default=true)
webSeeds: Boolean, // Enable BEP19 web seeds (default=true)
utp: Boolean // Enable BEP29 uTP (default=true)
}
```

@@ -87,6 +87,7 @@ function WebTorrent (opts) {
self.tracker = opts.tracker !== undefined ? opts.tracker : {}
self.torrents = []
self.maxConns = Number(opts.maxConns) || 55
self.utp = opts.utp !== false

self._debug(
'new webtorrent (peerId %s, nodeId %s, port %s)',
@@ -23,14 +23,13 @@ function ConnPool (client) {
// Temporarily store incoming connections so they can be destroyed if the server is
// closed before the connection is passed off to a Torrent.
self._pendingConns = []
self.utp = client.utp

self._onConnectionBound = function (conn) {
self._onConnection(conn)
}

var listening = 0
self._onListening = function (e) {
if (++listening !== 2) return
self._onListening = function () {
self._client._onListening()
}

@@ -43,18 +42,23 @@ function ConnPool (client) {
// Setup TCP
self.tcpServer = net.createServer()
self.tcpServer.on('connection', self._onConnectionBound)
self.tcpServer.on('listening', self._onListening)
self.tcpServer.on('error', self._onError)

// Setup uTP
self.utpServer = utp.createServer()
self.utpServer.on('connection', self._onConnectionBound)
self.utpServer.on('listening', self._onListening)
self.utpServer.on('error', self._onError)
if (self.utp) {
self.utpServer = utp.createServer()
self.utpServer.on('connection', self._onConnectionBound)
self.utpServer.on('listening', self._onListening)
self.utpServer.on('error', self._onError)
}

// Start listening TCP then uTP
self.tcpServer.listen(client.torrentPort, function () {
self.utpServer.listen(this.address().port)
if (self.utp) {
self.utpServer.listen(this.address().port)
} else {
self._onListening()
}
})
}

@@ -66,9 +70,11 @@ ConnPool.prototype.destroy = function (cb) {
var self = this
debug('destroy pool')

self.utpServer.removeListener('connection', self._onConnectionBound)
self.utpServer.removeListener('listening', self._onListening)
self.utpServer.removeListener('error', self._onError)
if (self.utp) {
self.utpServer.removeListener('connection', self._onConnectionBound)
self.utpServer.removeListener('listening', self._onListening)
self.utpServer.removeListener('error', self._onError)
}

self.tcpServer.removeListener('connection', self._onConnectionBound)
self.tcpServer.removeListener('listening', self._onListening)
@@ -90,7 +90,6 @@ function Torrent (torrentId, client, opts) {
this.destroyed = false
this.paused = false
this.done = false
this.utp = opts.utp || true

this.metadata = null
this.store = null
@@ -1683,7 +1682,7 @@ Torrent.prototype._drain = function () {

Torrent.prototype._utpConnect = function (peer, connOpts) {
var self = this
if (!self.utp) return self._tcpConnect(peer, connOpts)
if (!self.client.utp) return self._tcpConnect(peer, connOpts)

this._debug('utp connect attempt to %s', peer.addr)

@@ -0,0 +1,115 @@
var DHT = require('bittorrent-dht/server')
var fixtures = require('webtorrent-fixtures')
var fs = require('fs')
var MemoryChunkStore = require('memory-chunk-store')
var networkAddress = require('network-address')
var series = require('run-series')
var test = require('tape')
var WebTorrent = require('../../')

test('Download using DHT (via magnet uri)', function (t) {
t.plan(12)

var dhtServer = new DHT({ bootstrap: false })

dhtServer.on('error', function (err) { t.fail(err) })
dhtServer.on('warning', function (err) { t.fail(err) })

var client1, client2

series([
function (cb) {
dhtServer.listen(cb)
},

function (cb) {
client1 = new WebTorrent({
tracker: false,
dht: { bootstrap: '127.0.0.1:' + dhtServer.address().port, host: networkAddress.ipv4() }
})

client1.dht.on('listening', function () {
t.equal(client1.dhtPort, client1.dht.address().port)
})

client1.on('error', function (err) { t.fail(err) })
client1.on('warning', function (err) { t.fail(err) })

var torrent = client1.add(fixtures.leaves.parsedTorrent, {store: MemoryChunkStore})

torrent.on('dhtAnnounce', function () {
t.pass('finished dht announce')
announced = true
maybeDone()
})

torrent.on('ready', function () {
// torrent metadata has been fetched -- sanity check it
t.equal(torrent.name, 'Leaves of Grass by Walt Whitman.epub')

var names = [ 'Leaves of Grass by Walt Whitman.epub' ]
t.deepEqual(torrent.files.map(function (file) { return file.name }), names)
})

torrent.load(fs.createReadStream(fixtures.leaves.contentPath), function (err) {
t.error(err)
loaded = true
maybeDone()
})

var announced = false
var loaded = false
function maybeDone () {
if (announced && loaded) cb(null)
}
},

function (cb) {
client2 = new WebTorrent({
tracker: false,
utp: false,
dht: { bootstrap: '127.0.0.1:' + dhtServer.address().port, host: networkAddress.ipv4() }
})

client2.on('error', function (err) { t.fail(err) })
client2.on('warning', function (err) { t.fail(err) })

client2.on('torrent', function (torrent) {
torrent.files[0].getBuffer(function (err, buf) {
t.error(err)
t.deepEqual(buf, fixtures.leaves.content, 'downloaded correct content')

gotBuffer = true
maybeDone()
})

torrent.once('done', function () {
t.pass('client2 downloaded torrent from client1')

gotDone = true
maybeDone()
})
})

client2.add(fixtures.leaves.magnetURI, {store: MemoryChunkStore})

var gotBuffer = false
var gotDone = false
function maybeDone () {
if (gotBuffer && gotDone) cb(null)
}
}
], function (err) {
t.error(err)

client1.destroy(function (err) {
t.error(err, 'client1 destroyed')
})
client2.destroy(function (err) {
t.error(err, 'client2 destroyed')
})
dhtServer.destroy(function (err) {
t.error(err, 'dht server destroyed')
})
})
})
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.