@hyperswarm/dht-relay v0.4.3
Hyperswarm 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.
Installation
npm install @hyperswarm/dht-relayUsage
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
Transports
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))CLI
You can start a DHT relay in the command line:
npm install -g @hyperswarm/dht-relayRun 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.
Protocol
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.
Messages
All types are specified as their corresponding compact-encoding codec.
handshake (0)
uint8Flagscustodial:1
fixed(32)The public key of the peer- (if
custodialis set)fixed(64)The secret key
ping (1)
Empty
pong (2)
Empty
connect (3)
uint8Flagscustodial:1
uint32The alias of the streamfixed(32)The public key of the peer- (if
custodialis set)fixed(64)The secret key fixed(32)The public key of the remote peer
connection (4)
uint8Flagscustodial:1
uint32The alias of the streamuint32The alias of the serverfixed(32)The public key of the remote peer- (if
custodialis set)fixed(64)The Noise handshake hash - (if
custodialis not set)uint32The ID of the Noise handshake session
connected (5)
uint32The alias of the streamuint32The remote alias of the stream
incoming (6)
uint32The ID of the requestuint32The alias of the serverfixed(32)The public key of the remote peerbufferThe Noise handshake payload
deny (7)
uint32The ID of the request
accept (8)
uint32The ID of the request
destroy (9)
uint8Flagspaired:1error:2
- (if
pairedis set)uint32The alias of the stream - (if
pairedis not set)uint32The remote alias of the stream - (if
erroris set)stringThe reason the stream was destroyed
listen (10)
uint8Flagscustodial:1
uint32The alias of the serverfixed(32)The public key of the server- (if
custodialis set)fixed(64)The secret key
listening (11)
uint32The alias of the serveruint32The remote alias of the serveripv4AddressThe address of the server
close (12)
uint32The alias of the server
closed (13)
uint32The alias of the server
open (14)
uint8Flagscustodial:1
uint32The alias of the streamuint32The alias of the server- (if
custodialis set)fixed(64)The Noise handshake hash - (if
custodialis not set)uint32The ID of the Noise handshake session
end (15)
uint32The alias of the stream
data (16)
uint32The alias of the streamarray(buffer)The data sent
result (17)
uint32The query IDbufferThe query specific data
finished (18)
uint32The query ID
lookup (19)
uint32The query IDfixed(32)The topic to look up
announce (20)
uint8Flagscustodial:1
uint32The query IDfixed(32)The topic to announcefixed(32)The public key to announce on- (if
custodialis set)fixed(64)The secret key
unannounce (21)
uint8Flagscustodial:1
uint32The query IDfixed(32)The topic to unannouncefixed(32)The public key that was announced on- (if
custodialis set)fixed(64)The secret key
signAnnounce (22)
uint32The ID of the requestuint32The alias of the signeefixed(32)The roundtrip token of the peerbufferThe ID of the peerarray(ipv4Address)The addresses that may relay messages
signUnannounce (23)
uint32The ID of the requestuint32The alias of the signeefixed(32)The roundtrip token of the peerbufferThe ID of the peerarray(ipv4Address)The addresses that may relay messages
signature (24)
uint32The ID of the requestbufferThe signature
noiseSend (25)
uint8FlagsisInitiator:1
uint32The ID of the handshake session- (if
isInitiatoris set) The alias of the remote stream bufferThe Noise handshake payload
noiseReceive (26)
uint8FlagsisInitiator:1
uint32The ID of the handshake session- (if
isInitiatoris not set) The alias of the server bufferThe Noise handshake payload
noiseReply (27)
uint8FlagsisInitiator:1complete:2
uint32The ID of the handshake sessionbufferThe Noise handshake payload- (if
isInitiatorandcompleteare not set)fixed(32)The public key of the remote peer - (if
completeis set)fixed(32)The ID of the remote stream - (if
completeis set)fixed(32)The holepunch secret
License
ISC