216 lines
5.1 KiB
Markdown
216 lines
5.1 KiB
Markdown
|
|
# waste-rs
|
||
|
|
|
||
|
|
A modern reimagining of [WASTE](https://en.wikipedia.org/wiki/WASTE) - decentralized,
|
||
|
|
friend-to-friend encrypted mesh networking with chat and file sharing.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
waste-rs/
|
||
|
|
|-- proto/ Shared types (wire protocol, IPC messages)
|
||
|
|
|-- daemon/ Main peer process - runs locally on each friend's machine
|
||
|
|
| |-- crypto.rs Ed25519 identity, X25519 ECDH, ChaCha20-Poly1305 AEAD
|
||
|
|
| |-- mesh/ Connected peer state, gossip, broadcast
|
||
|
|
| |-- nat.rs Relay client + future hole-punching
|
||
|
|
| `-- ipc.rs Local JSON API for UIs (port 17337)
|
||
|
|
`-- relay/ Bootstrap/relay server - runs on your VPS
|
||
|
|
```
|
||
|
|
|
||
|
|
### How it works
|
||
|
|
|
||
|
|
1. Each peer generates an Ed25519 keypair on first run -> their identity.
|
||
|
|
2. Two peers exchange invite info out-of-band (public key + IP:port).
|
||
|
|
3. On connect: Ed25519-authenticated X25519 handshake -> per-session ChaCha20 key.
|
||
|
|
4. All traffic is encrypted; the relay only forwards opaque blobs.
|
||
|
|
5. Connected peers gossip each other's addresses to strengthen the mesh.
|
||
|
|
|
||
|
|
## Prerequisites
|
||
|
|
|
||
|
|
- Rust 1.78+ (via rustup)
|
||
|
|
- VS Code with the extensions in `.vscode/extensions.json`
|
||
|
|
- `cargo-lldb` for debugging (installed by the LLDB extension)
|
||
|
|
|
||
|
|
### Install toolchain (Windows, Linux, macOS)
|
||
|
|
|
||
|
|
Use rustup on all platforms.
|
||
|
|
|
||
|
|
Windows (PowerShell):
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
winget install Rustlang.Rustup
|
||
|
|
```
|
||
|
|
|
||
|
|
Linux/macOS (bash/zsh):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||
|
|
```
|
||
|
|
|
||
|
|
Then install required components:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
rustup toolchain install stable
|
||
|
|
rustup default stable
|
||
|
|
rustup component add rustfmt clippy
|
||
|
|
```
|
||
|
|
|
||
|
|
Verify your setup:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
rustup --version
|
||
|
|
rustc --version
|
||
|
|
cargo --version
|
||
|
|
cargo clippy --version
|
||
|
|
```
|
||
|
|
|
||
|
|
## Getting started
|
||
|
|
|
||
|
|
### 1) Build workspace
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cargo build --workspace
|
||
|
|
cargo clippy --workspace -- -D warnings
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2) Run local relay
|
||
|
|
|
||
|
|
Linux/macOS (bash/zsh):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
RUST_LOG=debug cargo run --bin waste-relay -- --bind 127.0.0.1:17339
|
||
|
|
```
|
||
|
|
|
||
|
|
Windows PowerShell:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$env:RUST_LOG = "debug"
|
||
|
|
cargo run --bin waste-relay -- --bind 127.0.0.1:17339
|
||
|
|
```
|
||
|
|
|
||
|
|
Windows cmd.exe:
|
||
|
|
|
||
|
|
```cmd
|
||
|
|
set RUST_LOG=debug && cargo run --bin waste-relay -- --bind 127.0.0.1:17339
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3) Run two peers
|
||
|
|
|
||
|
|
Use a local folder for data so paths are portable across platforms.
|
||
|
|
|
||
|
|
Peer A (terminal 2)
|
||
|
|
|
||
|
|
Linux/macOS (bash/zsh):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
RUST_LOG=debug cargo run --bin waste-daemon -- \
|
||
|
|
--alias alice --data-dir ./.local-dev/waste-alice \
|
||
|
|
--peer-port 17338 --ipc-port 17337
|
||
|
|
```
|
||
|
|
|
||
|
|
Windows PowerShell:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$env:RUST_LOG = "debug"
|
||
|
|
cargo run --bin waste-daemon -- --alias alice --data-dir ./.local-dev/waste-alice --peer-port 17338 --ipc-port 17337
|
||
|
|
```
|
||
|
|
|
||
|
|
Windows cmd.exe:
|
||
|
|
|
||
|
|
```cmd
|
||
|
|
set RUST_LOG=debug && cargo run --bin waste-daemon -- --alias alice --data-dir ./.local-dev/waste-alice --peer-port 17338 --ipc-port 17337
|
||
|
|
```
|
||
|
|
|
||
|
|
Peer B (terminal 3)
|
||
|
|
|
||
|
|
Linux/macOS (bash/zsh):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
RUST_LOG=debug cargo run --bin waste-daemon -- \
|
||
|
|
--alias bob --data-dir ./.local-dev/waste-bob \
|
||
|
|
--peer-port 17340 --ipc-port 17341
|
||
|
|
```
|
||
|
|
|
||
|
|
Windows PowerShell:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$env:RUST_LOG = "debug"
|
||
|
|
cargo run --bin waste-daemon -- --alias bob --data-dir ./.local-dev/waste-bob --peer-port 17340 --ipc-port 17341
|
||
|
|
```
|
||
|
|
|
||
|
|
Windows cmd.exe:
|
||
|
|
|
||
|
|
```cmd
|
||
|
|
set RUST_LOG=debug && cargo run --bin waste-daemon -- --alias bob --data-dir ./.local-dev/waste-bob --peer-port 17340 --ipc-port 17341
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4) Connect B -> A via IPC
|
||
|
|
|
||
|
|
If nc/netcat is available:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
echo '{"type":"connect","addr":"127.0.0.1:17338"}' | nc 127.0.0.1 17341
|
||
|
|
```
|
||
|
|
|
||
|
|
PowerShell equivalent:
|
||
|
|
|
||
|
|
```powershell
|
||
|
|
$json = '{"type":"connect","addr":"127.0.0.1:17338"}' + "`n"
|
||
|
|
$client = [System.Net.Sockets.TcpClient]::new("127.0.0.1", 17341)
|
||
|
|
$stream = $client.GetStream()
|
||
|
|
$writer = New-Object System.IO.StreamWriter($stream)
|
||
|
|
$writer.AutoFlush = $true
|
||
|
|
$writer.Write($json)
|
||
|
|
$writer.Dispose(); $stream.Dispose(); $client.Dispose()
|
||
|
|
```
|
||
|
|
|
||
|
|
## Relay on Hetzner VPS
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cargo build --release --bin waste-relay
|
||
|
|
scp target/release/waste-relay user@your-vps:~/
|
||
|
|
ssh user@your-vps './waste-relay --bind 0.0.0.0:17339'
|
||
|
|
```
|
||
|
|
|
||
|
|
Then start the daemon with `--relay your-vps-ip:17339`.
|
||
|
|
|
||
|
|
## IPC protocol
|
||
|
|
|
||
|
|
The daemon exposes a newline-delimited JSON API on `127.0.0.1:17337`.
|
||
|
|
|
||
|
|
Commands (send to daemon):
|
||
|
|
|
||
|
|
```json
|
||
|
|
{"type":"send_message","room":"general","body":"hello"}
|
||
|
|
{"type":"connect","addr":"1.2.3.4:17338"}
|
||
|
|
{"type":"get_state"}
|
||
|
|
```
|
||
|
|
|
||
|
|
Events (daemon pushes to you):
|
||
|
|
|
||
|
|
```json
|
||
|
|
{"type":"message_received","id":"...","from":"...","room":"general","body":"hello"}
|
||
|
|
{"type":"peer_connected","peer":{...}}
|
||
|
|
{"type":"state_snapshot","local_peer":{...},"connected_peers":[...]}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Roadmap
|
||
|
|
|
||
|
|
- [ ] UDP hole-punching (STUN) in `nat.rs`
|
||
|
|
- [ ] Invite file format (`.waste-invite`) for easy onboarding
|
||
|
|
- [ ] File transfer implementation
|
||
|
|
- [ ] Tauri UI wrapping the daemon
|
||
|
|
- [ ] Peer gossip -> auto-connect to friends-of-friends
|
||
|
|
- [ ] Message persistence (SQLite)
|
||
|
|
- [ ] Mobile daemon (Android/iOS via Rust cross-compilation)
|
||
|
|
|
||
|
|
## Crypto choices
|
||
|
|
|
||
|
|
| Purpose | Algorithm | Why |
|
||
|
|
|---|---|---|
|
||
|
|
| Identity | Ed25519 | Fast, small keys, strong |
|
||
|
|
| Key exchange | X25519 ECDH | Modern, fast, safe |
|
||
|
|
| Symmetric | ChaCha20-Poly1305 | No timing side-channels, fast without AES-NI |
|
||
|
|
| Hashing | SHA-256 (ring) | File integrity |
|
||
|
|
|
||
|
|
Replaces WASTE's original Blowfish/PCBC (broken mode) + RSA.
|