npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tradle/bittorrent-dht

v3.2.1

Published

Simple, robust, BitTorrent DHT implementation

Downloads

20

Readme

bittorrent-dht travis npm downloads

Simple, robust, BitTorrent DHT implementation

Node.js implementation of the BitTorrent DHT protocol. BitTorrent DHT is the main peer discovery layer for BitTorrent, which allows for trackerless torrents. DHTs are awesome!

This module is used by WebTorrent.

features

  • complete implementation of the DHT protocol in JavaScript
  • follows the spec
  • robust and well-tested (comprehensive test suite, and used by WebTorrent and peerflix)
  • efficient recursive lookup algorithm minimizes UDP traffic
  • supports multiple, concurrent lookups using the same routing table

Also see bittorrent-tracker.

install

npm install bittorrent-dht

example

npm install magnet-uri
var DHT    = require('bittorrent-dht')
var magnet = require('magnet-uri')

var uri = 'magnet:?xt=urn:btih:e3811b9539cacff680e418124272177c47477157'
var parsed = magnet(uri)

console.log(parsed.infoHash) // 'e3811b9539cacff680e418124272177c47477157'

var dht = new DHT()

dht.listen(20000, function () {
  console.log('now listening')
})

dht.on('ready', function () {
  // DHT is ready to use (i.e. the routing table contains at least K nodes, discovered
  // via the bootstrap nodes)

  // find peers for the given torrent info hash
  dht.lookup(parsed.infoHash)
})

dht.on('peer', function (addr, hash, from) {
  console.log('found potential peer ' + addr + ' through ' + from)
})

api

dht = new DHT([opts])

Create a new dht instance.

If opts is specified, then the default options (shown below) will be overridden.

{
  nodeId: '',   // 160-bit DHT node ID (Buffer or hex string, default: randomly generated)
  bootstrap: [] // bootstrap servers (default: router.bittorrent.com:6881, router.utorrent.com:6881, dht.transmissionbt.com:6881)
}

dht.lookup(infoHash, [callback])

Find peers for the given info hash.

This does a recursive lookup in the DHT. Potential peers that are discovered are emitted as peer events. See the peer event below for more info.

infoHash can be a string or Buffer. callback is called when the recursive lookup has terminated, and is called with two paramaters. The first is an Error or null. The second is an array of the K closest nodes. You usually don't need to use this info and can simply listen for peer events.

Note: dht.lookup() should only be called after the ready event has fired, otherwise the lookup may fail because the DHT routing table doesn't contain enough nodes.

dht.listen([port], [address], [onlistening])

Make the DHT listen on the given port. If port is undefined, an available port is automatically picked.

If address is undefined, the DHT will try to listen on all addresses.

If onlistening is defined, it is attached to the listening event.

dht.address()

Returns an object containing the address information for the listening socket of the DHT. This object contains address, family and port properties.

dht.announce(infoHash, port, [callback])

Announce that the peer, controlling the querying node, is downloading a torrent on a port.

If dht.announce is called soon (< 5 minutes) after dht.lookup, then the routing table generated during the lookup can be re-used, because the "tokens" sent by each node will still be valid.

If dht.announce is called and there is no cached routing table, then a dht.lookup will first be performed to discover relevant nodes and get valid "tokens" from each of them. This will take longer.

A "token" is an opaque value that must be presented for a node to announce that its controlling peer is downloading a torrent. It must present the token received from the same queried node in a recent query for peers. This is to prevent malicious hosts from signing up other hosts for torrents. All token management is handled internally by this module.

callback will be called when the announce operation has completed, and is called with a single parameter that is an Error or null.

arr = dht.toArray()

Returns the nodes in the DHT as an array. This is useful for persisting the DHT to disk between restarts of a BitTorrent client (as recommended by the spec). Each node in the array is an object with id (hex string) and addr (string) properties.

To restore the DHT nodes when instantiating a new DHT object, simply pass in the array as the value of the bootstrap option.

var dht1 = new DHT()

// some time passes ...

// destroy the dht
var arr = dht1.toArray()
dht1.destroy()

// some time passes ...

// initialize a new dht with the same routing table as the first
var dht2 = new DHT({ bootstrap: arr })

dht.addNode(addr, [nodeId])

Manually add a node to the DHT routing table. If there is space in the routing table (or an unresponsive node can be evicted to make space), the node will be added. If not, the node will not be added. This is useful to call when a peer wire sends a PORT message to share their DHT port.

If nodeId is undefined, then the peer will be pinged to learn their node id. If the peer does not respond, the will not be added to the routing table.

dht.destroy([callback])

Destroy the DHT. Closes the socket and cleans up large data structure resources.

events

dht.on('ready', function () { ... })

Emitted when the DHT is ready to handle lookups (i.e. the routing table is sufficiently populated via the bootstrap nodes).

Note: If you initialize the DHT with the { bootstrap: false } option, then the 'ready' event will fire on the next tick even if there are not any nodes in the routing table. It is assumed that you will manually populate the routing table with dht.addNode if you pass this option.

dht.on('listening', function () { ... })

Emitted when the DHT is listening.

dht.on('peer', function (addr, infoHash, from) { ... })

Emitted when a potential peer is found. addr is of the form IP_ADDRESS:PORT. infoHash is the torrent info hash of the swarm that the peer belongs to. Emitted in response to a lookup(infoHash) call.

dht.on('error', function (err) { ... })

Emitted when the DHT has a fatal error.

internal events

dht.on('node', function (addr, nodeId, from) { ... })

Emitted when the DHT finds a new node.

dht.on('announce', function (addr, infoHash) { ... })

Emitted when a peer announces itself in order to be stored in the DHT.

dht.on('warning', function (err) { ... })

Emitted when the DHT gets an unexpected message from another DHT node. This is purely informational.

further reading

license

MIT. Copyright (c) Feross Aboukhadijeh.