Two crates, layered:
| Crate | Path | Purpose |
|---|---|---|
hyperdht-sys |
wrappers/rust/hyperdht-sys/ |
Raw unsafe extern "C" FFI bindings to libhyperdht.a + libudx.a, generated by bindgen at build time |
hyperdht |
wrappers/rust/hyperdht/ |
Safe async wrapper built on hyperdht-sys. Provides Dht, Server, Stream, Keypair with tokio::io::AsyncRead + AsyncWrite |
App code should depend on hyperdht, not hyperdht-sys directly.
Build-time:
cmake3.20+ninja- C++20 compiler (
g++orclang++) libclang(forbindgen)pkg-config
Runtime libraries (also build-time for headers):
libsodium-devlibuv1-dev
sudo apt install cmake ninja-build pkg-config g++ git \
libsodium-dev libuv1-dev libclang-devnix develop .#rustProvides cmake, ninja, libsodium, libuv, libclang, and a recent Rust
toolchain. Recommended — avoids version-skew issues with bindgen's
clang dependency.
cd wrappers/rust
cargo build # builds both crates
cargo build --release # release profilehyperdht-sys/build.rs drives:
cmake-rs→ buildslibhyperdht.a+libudx.aintarget/.../out/build/bindgen→ generates Rust FFI fromwrappers/rust/hyperdht-sys/wrapper.h
The C library is rebuilt incrementally by Cargo when sources change.
cd wrappers/rust
cargo testSuite covers:
hyperdht-sys/tests/smoke.rs— verifies FFI table is generatedhyperdht/tests/concurrent.rs— 8 simultaneous connectshyperdht/tests/drop_midflight.rs— drop futures before resolve (UAF hunt)hyperdht/tests/mutable.rs— mutable_put / mutable_get round-trip
Live tests cross-talk to JS HyperDHT and the public network — they need internet access.
Memory-bug harness:
wrappers/rust/scripts/asan-test.shBuilds with -Z sanitizer=address (requires nightly), runs the full
test suite with libsodium + libuv suppressions
(wrappers/rust/scripts/asan-suppressions.txt).
Known status: wrapper itself is clean; remaining leaks all in C-side
code, one documented as accepted. See memory note
asan_phase_2_5.md for details.
In your Cargo.toml:
[dependencies]
hyperdht = { path = "../hyperdht-cpp/wrappers/rust/hyperdht" }
tokio = { version = "1", features = ["full"] }Or via git:
[dependencies]
hyperdht = { git = "https://github.com/jjacke13/hyperdht-cpp.git", branch = "main" }If you go the git route and the consuming project is a Nix flake, set
inputs.<name>.submodules = true so deps/libudx ships with the
source tree.
Minimal client:
use hyperdht::{Dht, DhtOptions, Keypair, ConnectOptions};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let dht = Dht::new(DhtOptions::default()).await?;
let kp = Keypair::generate();
println!("our pubkey: {}", hex::encode(kp.public().as_bytes()));
Ok(())
}Default: static linking of libhyperdht.a + libudx.a into the
final .rlib / binary. Runtime deps remain dynamic:
libsodium.solibuv.so.1libstdc++.so.6libc.so.6
To statically link libsodium / libuv too, override via CMake flags in
build.rs (-DSODIUM_LIBRARY=/path/to/libsodium.a, similar for libuv)
or vendor them via pkg-config-static.
examples/rust/holesail-server/— TCP-over-DHT tunnel serverexamples/rust/static-http/— minimal HTTP server reachable via pubkey
Build:
cd examples/rust
cargo build --releaseNo dedicated Rust CI job yet. The crates build on top of the same
system deps as the Linux jobs in .github/workflows/build.yml, so
locally validate before merging Rust changes.
- Raw FFI:
wrappers/rust/hyperdht-sys/README.md - Safe wrapper:
wrappers/rust/hyperdht/README.md - Architecture rationale:
RUSTDESK-INTEGRATION-PLAN.md(repo root)