$ npm install @hyperswarm/dht-relay:test_tube: This project is still experimental. Do not use it in production.
Relaying the Hyperswarm DHT over framed streams to bring decentralized networking to everyone.
npm install @hyperswarm/dht-relay
On the relaying side:
import DHT from 'hyperdht'
import { relay } from '@hyperswarm/dht-relay'
relay(new DHT(), stream)
On the relayed side:
import DHT from '@hyperswarm/dht-relay'
const dht = new DHT(stream)
From here, the API matches that of the Hyperswarm DHT: https://github.com/holepunchto/hyperdht#api
As a convenience, we provide stream wrappers for common transport protocols. These may or may not be appropriate for your particular use case and so your mileage may vary.
The TCP wrapper is a re-export of https://github.com/holepunchto/hyperswarm-secret-stream which adds both framing and encryption.
On the relaying side:
import net from 'net'
import DHT from 'hyperdht'
import { relay } from '@hyperswarm/dht-relay'
import Stream from '@hyperswarm/dht-relay/tcp'
const dht = new DHT()
const server = net.createServer().listen(8080)
server.on('connection', (socket) => {
relay(dht, new Stream(false, socket))
})
On the relayed side:
import net from 'net'
import DHT from '@hyperswarm/dht-relay'
import Stream from '@hyperswarm/dht-relay/tcp'
const socket = net.connect(8080)
const dht = new DHT(new Stream(true, socket))
The WebSocket wrapper is a simple Duplex stream that only adapts the interface of the WebSocket as the WebSocket API already provides its own framing and encryption.
On the relaying side:
import { WebSocketServer } from 'ws'
import DHT from 'hyperdht'
import { relay } from '@hyperswarm/dht-relay'
import Stream from '@hyperswarm/dht-relay/ws'
const dht = new DHT()
const server = new WebSocketServer({ port: 8080 })
server.on('connection', (socket) => {
relay(dht, new Stream(false, socket))
})
On the relayed side:
import DHT from '@hyperswarm/dht-relay'
import Stream from '@hyperswarm/dht-relay/ws'
const socket = new WebSocket('ws://localhost:8080')
const dht = new DHT(new Stream(true, socket))
You can start a DHT relay in the command line:
npm install -g @hyperswarm/dht-relay
Run a DHT relay server:
dht-relay # [--port 49443] [--host 0.0.0.0] [--cert <path fullchain.pem>] [--key <path privkey.pem>]
If running behind a proxy like NGINX then add --behind-proxy so logging info is correct.
A reference implementation of the relay protocol can be found in the lib/protocol.js module. The protocol is versioned and built on top of https://github.com/mafintosh/protomux.
All types are specified as their corresponding compact-encoding codec.
handshake (0)uint8 Flags
custodial: 1fixed(32) The public key of the peercustodial is set) fixed(64) The secret keyping (1)Empty
pong (2)Empty
connect (3)uint8 Flags
custodial: 1uint32 The alias of the streamfixed(32) The public key of the peercustodial is set) fixed(64) The secret keyfixed(32) The public key of the remote peerconnection (4)uint8 Flags
custodial: 1uint32 The alias of the streamuint32 The alias of the serverfixed(32) The public key of the remote peercustodial is set) fixed(64) The Noise handshake hashcustodial is not set) uint32 The ID of the Noise handshake sessionconnected (5)uint32 The alias of the streamuint32 The remote alias of the streamincoming (6)uint32 The ID of the requestuint32 The alias of the serverfixed(32) The public key of the remote peerbuffer The Noise handshake payloaddeny (7)uint32 The ID of the requestaccept (8)uint32 The ID of the requestdestroy (9)uint8 Flags
paired: 1error: 2paired is set) uint32 The alias of the streampaired is not set) uint32 The remote alias of the streamerror is set) string The reason the stream was destroyedlisten (10)uint8 Flags
custodial: 1uint32 The alias of the serverfixed(32) The public key of the servercustodial is set) fixed(64) The secret keylistening (11)uint32 The alias of the serveruint32 The remote alias of the serveripv4Address The address of the serverclose (12)uint32 The alias of the serverclosed (13)uint32 The alias of the serveropen (14)uint8 Flags
custodial: 1uint32 The alias of the streamuint32 The alias of the servercustodial is set) fixed(64) The Noise handshake hashcustodial is not set) uint32 The ID of the Noise handshake sessionend (15)uint32 The alias of the streamdata (16)uint32 The alias of the streamarray(buffer) The data sentresult (17)uint32 The query IDbuffer The query specific datafinished (18)uint32 The query IDlookup (19)uint32 The query IDfixed(32) The topic to look upannounce (20)uint8 Flags
custodial: 1uint32 The query IDfixed(32) The topic to announcefixed(32) The public key to announce oncustodial is set) fixed(64) The secret keyunannounce (21)uint8 Flags
custodial: 1uint32 The query IDfixed(32) The topic to unannouncefixed(32) The public key that was announced oncustodial is set) fixed(64) The secret keysignAnnounce (22)uint32 The ID of the requestuint32 The alias of the signeefixed(32) The roundtrip token of the peerbuffer The ID of the peerarray(ipv4Address) The addresses that may relay messagessignUnannounce (23)uint32 The ID of the requestuint32 The alias of the signeefixed(32) The roundtrip token of the peerbuffer The ID of the peerarray(ipv4Address) The addresses that may relay messagessignature (24)uint32 The ID of the requestbuffer The signaturenoiseSend (25)uint8 Flags
isInitiator: 1uint32 The ID of the handshake sessionisInitiator is set) The alias of the remote streambuffer The Noise handshake payloadnoiseReceive (26)uint8 Flags
isInitiator: 1uint32 The ID of the handshake sessionisInitiator is not set) The alias of the serverbuffer The Noise handshake payloadnoiseReply (27)uint8 Flags
isInitiator: 1complete: 2uint32 The ID of the handshake sessionbuffer The Noise handshake payloadisInitiator and complete are not set) fixed(32) The public key of the remote peercomplete is set) fixed(32) The ID of the remote streamcomplete is set) fixed(32) The holepunch secretISC