diff options
Diffstat (limited to 'docs/meshbay-draft-v3.md')
| -rw-r--r-- | docs/meshbay-draft-v3.md | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/docs/meshbay-draft-v3.md b/docs/meshbay-draft-v3.md index 6983191..e11200c 100644 --- a/docs/meshbay-draft-v3.md +++ b/docs/meshbay-draft-v3.md @@ -222,14 +222,20 @@ Complete table of validated and planned hub REST API endpoints. Endpoints marked A local program running on the host user's machine. The node is the actual host of all content. **Responsibilities:** -- Watch and index shared directories (Mesh Group Index) -- Serve files and video streams to group members +- Watch and index shared directories (Mesh Group Index) — one directory per group +- Serve files, video streams, and group chat to members - Manage all cryptographic keys locally (encrypted keystore) -- Handle P2P connections and NAT traversal -- Run the MNP protocol +- Handle P2P connections and NAT traversal (STUN + QUIC hole punching) +- Run the MNP protocol (QUIC v2, TCP+TLS v1) - Host the Python extension module sandbox - Serve the local web UI (localhost:18000) -- Host the group chat (core feature) + +**Multi-group architecture (decided Phase 7):** +A node exposes **one QUIC port** for all groups it hosts. Groups are not isolated +by port — the MNP handshake identifies the target group via the `group_id` claim +in the client JWT. The server routes each connection to the appropriate +DirectoryIndexer and GEK after JWT verification. +Rationale: one NAT hole to maintain, one port to forward manually if needed. **Platform:** Linux primary, cross-platform from the start (Windows/macOS). Python ensures portability. @@ -582,13 +588,23 @@ Node → Client: session established - `18001/tcp` — MNP P2P listener (exposed externally, TLS required) - Configurable via `~/.config/meshbay/node.toml` -### 6.6 Chat Encryption +### 6.6 Chat Encryption and Model + +Group chat is a **core feature** (not an extension module). + +**Model (decided):** between a forum and Signal. +- **Persistent:** messages stored on the node (not ephemeral like Signal by default) +- **Structured:** optional threads/topics for longer discussions, flat stream for quick messages +- **Scope:** per group (not per user pair) +- **Attachments:** files and images, shared like regular group files +- **Push/pull:** connected members get real-time push (WebSocket); offline members pull history on reconnect +- **Retention:** managed by the group admin (no automatic expiry) -Group chat is a **core feature** (not an extension module). Uses the **Double Ratchet algorithm** (as in Signal): +**Encryption:** Double Ratchet algorithm (implemented in `meshbay_common.ratchet`): - Forward secrecy and break-in recovery per message -- Each message independently encrypted -- Attachment files: encrypted with the current Double Ratchet message key, hash included in message -- Python implementation: [TBD — evaluate existing libraries] +- Each message independently encrypted, out-of-order delivery handled +- Attachment files: encrypted with GEK-derived key (same as file chunks), hash in message +- Group scope: all members share the same ratchet state seeded from the group GEK --- @@ -613,7 +629,23 @@ Group chat is a **core feature** (not an extension module). Uses the **Double Ra Without step 4 (Mesh Relay), approximately 15% of connections between symmetric-NAT peers will fail. This is documented behavior until Mesh Relay is implemented. -Signaling for hole punching: coordinated via hub WebSocket endpoint, <1 KB per attempt, no persistent state. +**Signaling punch/connect (Phase 7.2 — reduces handshake from 12.7s to < 200ms):** +Currently the node punches blindly at startup; the client may connect 10-20s later +on an aging NAT entry, causing retransmissions. The coordinated flow uses the +existing hub→node WebSocket (revocation channel): +``` +Client → Hub : POST /v1/nodes/{id}/incoming {peer_ip, peer_port} +Hub → Node (WS) : {type: "client_incoming", peer_ip, peer_port} +Node : punch_nat(peer_ip, peer_port) immediately +Node → Hub (WS) : {type: "punch_ready"} +Hub → Client: 200 OK "connect now" +Client → QUIC: first packet < 2s after probe → fresh NAT entry +``` +demo-v2 finding: SFR residential is **Port-Restricted Cone NAT**. +The probe must come from the QUIC server's own socket (`punch_nat()` via +`_transport.sendto()`). The QUIC client must connect from the same port +as the probe's destination (`local_port=QUIC_PORT`). Handshake time +with proper signaling: < 200ms (vs 12.7s without). ### 7.2 MNP — Mesh Node Protocol |