Browse Source

Add test case for bootstrapper (#50)

* add test case for bootstrapper

* fix port/host/opts args in bootstrapper

* add more test cases for bootstrapper

* feedback from mafintosh

* added options.host for bind
master
Lucas 2 years ago
committed by GitHub
parent
commit
6031c21d39
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      README.md
  2. 2
      examples/bootstrap.mjs
  3. 3
      index.js
  4. 9
      lib/io.js
  5. 55
      test.js

3
README.md

@ -116,6 +116,8 @@ Options include:
nodes: [{ host, port }, ...], nodes: [{ host, port }, ...],
// Optionally pass a port you prefer to bind to instead of a random one // Optionally pass a port you prefer to bind to instead of a random one
port: 0, port: 0,
// Optionally pass a host you prefer to bind to instead of all networks
host: '0.0.0.0',
// Optionally pass a UDX instance on which sockets will be created. // Optionally pass a UDX instance on which sockets will be created.
udx, udx,
// dht-rpc will automatically detect if you are firewalled. If you know that you are not set this to false // dht-rpc will automatically detect if you are firewalled. If you know that you are not set this to false
@ -132,6 +134,7 @@ Your DHT routing id is `hash(publicIp + publicPort)` and will be autoconfigured
#### `const node = DHT.bootrapper(port, host, [options])` #### `const node = DHT.bootrapper(port, host, [options])`
Make a bootstrap node for your DHT. The port and host needs to be it's globally accessable port and host. Make a bootstrap node for your DHT. The port and host needs to be it's globally accessable port and host.
Note: `port` and `host` parameters are used to create the node id. Use `options.host` if you want to bind to i.e. 127.0.0.1.
DHT nodes can use any other DHT node to bootstrap, but a bootstrap node can bootstrap itself, by itself. DHT nodes can use any other DHT node to bootstrap, but a bootstrap node can bootstrap itself, by itself.
#### `await node.ready()` #### `await node.ready()`

2
examples/bootstrap.mjs

@ -1,5 +1,5 @@
import DHT from '../index.js' import DHT from '../index.js'
const bootstrap = new DHT({ ephemeral: false, firewalled: false, port: 10001 }) const bootstrap = DHT.bootstrapper(10001, '127.0.0.1')
await bootstrap.ready() await bootstrap.ready()
console.log(bootstrap.address()) console.log(bootstrap.address())

3
index.js

@ -45,6 +45,7 @@ class DHT extends EventEmitter {
this._nat = new NatSampler() this._nat = new NatSampler()
this._port = opts.port || 0 this._port = opts.port || 0
this._host = opts.host || '0.0.0.0'
this._quickFirewall = opts.quickFirewall !== false this._quickFirewall = opts.quickFirewall !== false
this._forcePersistent = opts.ephemeral === false this._forcePersistent = opts.ephemeral === false
this._repinging = 0 this._repinging = 0
@ -72,6 +73,8 @@ class DHT extends EventEmitter {
} }
static bootstrapper (port, host, opts) { static bootstrapper (port, host, opts) {
if (!port) throw new Error('Port is required')
if (!host) throw new Error('Host is required')
const id = peer.id(host, port) const id = peer.id(host, port)
return new this({ port, id, ephemeral: false, firewalled: false, anyPort: false, bootstrap: [], ...opts }) return new this({ port, id, ephemeral: false, firewalled: false, anyPort: false, bootstrap: [], ...opts })
} }

9
lib/io.js

@ -12,7 +12,7 @@ const TMP = b4a.alloc(32)
const EMPTY_ARRAY = [] const EMPTY_ARRAY = []
module.exports = class IO { module.exports = class IO {
constructor (table, udx, { maxWindow = 80, port = 0, anyPort = true, firewalled = true, onrequest, onresponse = noop, ontimeout = noop } = {}) { constructor (table, udx, { maxWindow = 80, port = 0, host = '0.0.0.0', anyPort = true, firewalled = true, onrequest, onresponse = noop, ontimeout = noop } = {}) {
this.table = table this.table = table
this.udx = udx this.udx = udx
this.inflight = [] this.inflight = []
@ -35,6 +35,7 @@ module.exports = class IO {
this._destroying = null this._destroying = null
this._binding = null this._binding = null
this._port = port this._port = port
this._host = host
this._anyPort = anyPort !== false this._anyPort = anyPort !== false
} }
@ -135,7 +136,7 @@ module.exports = class IO {
const serverSocket = this.udx.createSocket() const serverSocket = this.udx.createSocket()
try { try {
serverSocket.bind(this._port) serverSocket.bind(this._port, this._host)
} catch (err) { } catch (err) {
if (!this._anyPort) { if (!this._anyPort) {
await serverSocket.close() await serverSocket.close()
@ -143,7 +144,7 @@ module.exports = class IO {
} }
try { try {
serverSocket.bind() serverSocket.bind(0, this._host)
} catch (err) { } catch (err) {
await serverSocket.close() await serverSocket.close()
throw err throw err
@ -153,7 +154,7 @@ module.exports = class IO {
const clientSocket = this.udx.createSocket() const clientSocket = this.udx.createSocket()
try { try {
clientSocket.bind() clientSocket.bind(0, this._host)
} catch (err) { } catch (err) {
await serverSocket.close() await serverSocket.close()
await clientSocket.close() await clientSocket.close()

55
test.js

@ -2,6 +2,61 @@ const test = require('brittle')
const dgram = require('dgram') const dgram = require('dgram')
const DHT = require('./') const DHT = require('./')
test('bootstrapper', async function (t) {
const node = DHT.bootstrapper(49737, '127.0.0.1')
await node.ready()
t.is(node.address().host, '0.0.0.0')
t.is(node.address().family, 4)
t.is(node.address().port, 49737)
await node.destroy()
})
test('bootstrapper - bind host', async function (t) {
const node = DHT.bootstrapper(49737, '127.0.0.1', { host: '127.0.0.1' })
await node.ready()
t.is(node.address().host, '127.0.0.1')
t.is(node.address().family, 4)
t.is(node.address().port, 49737)
await node.destroy()
})
test('bootstrapper - opts', async function (t) {
const node = DHT.bootstrapper(49737, '127.0.0.1', { port: 49738 })
await node.ready()
t.is(node.address().host, '0.0.0.0')
t.is(node.address().family, 4)
t.is(node.address().port, 49738)
await node.destroy()
})
test('bootstrapper - port and host are required', function (t) {
t.plan(3)
try {
DHT.bootstrapper()
} catch (error) {
t.is(error.message, 'Port is required')
}
try {
DHT.bootstrapper(0)
} catch (error) {
t.is(error.message, 'Port is required')
}
try {
DHT.bootstrapper(49737)
} catch (error) {
t.is(error.message, 'Host is required')
}
})
test('make tiny swarm', async function (t) { test('make tiny swarm', async function (t) {
await makeSwarm(2, t) await makeSwarm(2, t)
t.pass('could make swarm') t.pass('could make swarm')

Loading…
Cancel
Save