🧪 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.
TCP
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))
WebSocket
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.
uint8
Flagscustodial
:1
fixed(32)
The public key of the peer- (if
custodial
is set)fixed(64)
The secret key
Empty
Empty
uint8
Flagscustodial
:1
uint32
The alias of the streamfixed(32)
The public key of the peer- (if
custodial
is set)fixed(64)
The secret key fixed(32)
The public key of the remote peer
uint8
Flagscustodial
:1
uint32
The alias of the streamuint32
The alias of the serverfixed(32)
The public key of the remote peer- (if
custodial
is set)fixed(64)
The Noise handshake hash - (if
custodial
is not set)uint32
The ID of the Noise handshake session
uint32
The alias of the streamuint32
The remote alias of the stream
uint32
The ID of the requestuint32
The alias of the serverfixed(32)
The public key of the remote peerbuffer
The Noise handshake payload
uint32
The ID of the request
uint32
The ID of the request
uint8
Flagspaired
:1
error
:2
- (if
paired
is set)uint32
The alias of the stream - (if
paired
is not set)uint32
The remote alias of the stream - (if
error
is set)string
The reason the stream was destroyed
uint8
Flagscustodial
:1
uint32
The alias of the serverfixed(32)
The public key of the server- (if
custodial
is set)fixed(64)
The secret key
uint32
The alias of the serveruint32
The remote alias of the serveripv4Address
The address of the server
uint32
The alias of the server
uint32
The alias of the server
uint8
Flagscustodial
:1
uint32
The alias of the streamuint32
The alias of the server- (if
custodial
is set)fixed(64)
The Noise handshake hash - (if
custodial
is not set)uint32
The ID of the Noise handshake session
uint32
The alias of the stream
uint32
The alias of the streamarray(buffer)
The data sent
uint32
The query IDbuffer
The query specific data
uint32
The query ID
uint32
The query IDfixed(32)
The topic to look up
uint8
Flagscustodial
:1
uint32
The query IDfixed(32)
The topic to announcefixed(32)
The public key to announce on- (if
custodial
is set)fixed(64)
The secret key
uint8
Flagscustodial
:1
uint32
The query IDfixed(32)
The topic to unannouncefixed(32)
The public key that was announced on- (if
custodial
is set)fixed(64)
The secret key
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 messages
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 messages
uint32
The ID of the requestbuffer
The signature
uint8
FlagsisInitiator
:1
uint32
The ID of the handshake session- (if
isInitiator
is set) The alias of the remote stream buffer
The Noise handshake payload
uint8
FlagsisInitiator
:1
uint32
The ID of the handshake session- (if
isInitiator
is not set) The alias of the server buffer
The Noise handshake payload
uint8
FlagsisInitiator
:1
complete
:2
uint32
The ID of the handshake sessionbuffer
The Noise handshake payload- (if
isInitiator
andcomplete
are not set)fixed(32)
The public key of the remote peer - (if
complete
is set)fixed(32)
The ID of the remote stream - (if
complete
is set)fixed(32)
The holepunch secret
ISC