diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-10 22:12:59 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-10 22:12:59 +0200 |
| commit | 60c4570e72e36c2a9720593c8baec74ee2ab52d6 (patch) | |
| tree | e833e222a6a95e64e5b24a0813882636044198c2 /CLAUDE.md | |
| parent | 1a53eb4cc404ec94658fde0ae04cfe2ccf1810dc (diff) | |
| download | meshbay-60c4570e72e36c2a9720593c8baec74ee2ab52d6.tar.gz | |
feat: Phase 9.1–9.5 — WebRTC DataChannel transport for browser P2P
Browser clients can now connect P2P to nodes behind residential NAT via
WebRTC DataChannel with ICE/STUN. Validated on SFR Port-Restricted Cone
NAT + 4G CGNAT across three scenarios (WiFi LAN, 4G IPv6, 4G IPv4 STUN).
No TURN relay needed. Hub serves only as signaling relay (<1 KB).
New files:
- webrtc_server.py: aiortc-based WebRTC transport (node side)
- signaling.py: SDP/ICE relay endpoint (hub side)
- transport.js: browser WebRTC client with msgpack framing
- webrtc-test.html: spike test page for browser→NAT→node validation
- test_webrtc_transport.py: 4 tests (handshake, file transfer, auth, guard)
- meshbay-draft-v4.md: architecture spec updated for web client
Modified:
- hub_client.py: WebRTC offer handling via hub WebSocket
- revocation.py: node_id from WS auth + webrtc_answer routing
- pyproject.toml: aiortc>=1.9 dependency
123 tests passing (117 existing + 6 new).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'CLAUDE.md')
| -rw-r--r-- | CLAUDE.md | 53 |
1 files changed, 34 insertions, 19 deletions
@@ -121,33 +121,48 @@ key hierarchy, on-the-fly encryption, transport abstraction. Existing v1 users (64 MB) are transparently rehashed on next successful login. CLI `calibrate` command still TODO for per-hardware tuning. -## NAT traversal — résultats empiriques (demo-v2) +## NAT traversal — empirical results -SFR résidentiel Fedora 44 → meshbay.org OVH VPS : -- **IPv6** : adresse publique présente MAIS entrant bloqué par la box → skippé -- **NAT type** : **Port-Restricted Cone** (pas Address-Restricted comme supposé en Spike 4) -- **Mécanisme validé** : `QuicChunkServer.punch_nat(peer_ip, peer_port)` envoie la probe - depuis le socket QUIC interne (`_transport.sendto()`). Le client DOIT se connecter - depuis le même port (local_port=QUIC_PORT dans QuicChunkClient). -- **UPnP** : désactivé sur box SFR → skippé -- **Handshake QUIC** : 12.7s (demo) → < 500ms attendu en prod (gap probe↔connect réduit + 0-RTT) -- **Scripts** : `QE/demo-v2/` — run_node.py / download.py / nat.py / setup_demo.py +### QUIC native clients (demo-v2) + +SFR residential Fedora 44 → meshbay.org OVH VPS: +- **NAT type**: Port-Restricted Cone +- **Mechanism**: `QuicChunkServer.punch_nat()` sends probe from QUIC server socket +- **Scripts**: `QE/demo-v2/` + +### WebRTC browser clients (Phase 9 spike, 2026-08-10) + +Mobile 4G SFR → node behind SFR residential NAT (Port-Restricted Cone + CGNAT 4G): + +| Test | ICE path | Result | +|---|---|---| +| WiFi LAN | IPv6 direct | OK, ~100ms | +| 4G + IPv6 | IPv6 inter-network | OK, ~600ms | +| 4G + IPv4 only (IPv6 disabled) | STUN hole-punch IPv4 | OK, ~650ms | + +- **No TURN relay needed** — ICE/STUN handles both NAT types automatically +- **Hub role**: signaling only (SDP/ICE relay via WebSocket, <1 KB) +- **Data path**: browser ↔ node P2P via WebRTC DataChannel +- **Scripts**: `QE/demo-v3/run_node_webrtc.py`, test page at `/webrtc-test.html` ## Key modules — où trouver quoi -| Besoin | Module | Fichier | +| Need | Module | File | |---|---|---| -| Chiffrement chunks (prod) | `meshbay_common.crypto` | `crypto.py` | -| Dérivation clés depuis password | `meshbay_common.keyderive` | `keyderive.py` | -| Bundle clés (web) | `meshbay_common.keyderive` | `keyderive.py` + `static/keyderive.js` | +| Chunk encryption (prod) | `meshbay_common.crypto` | `crypto.py` | +| Key derivation from password | `meshbay_common.keyderive` | `keyderive.py` | +| Key bundle (web) | `meshbay_common.keyderive` | `keyderive.py` + `static/keyderive.js` | | GEK wrap/unwrap (ECIES) | `meshbay_common.crypto` | `crypto.py` | | Double Ratchet (1:1 DM, future) | `meshbay_common.ratchet` | `ratchet.py` | | Sender Keys (group chat) | `meshbay_common.senderkeys` | `senderkeys.py` (Phase 7.5) | -| AES-GCM (navigateur) | `meshbay_common.webcrypto` | `webcrypto.py` + `static/crypto.js` | -| Keystore node | `meshbay_node.keystore` | `keystore.py` | -| NAT traversal | `QE/demo-v2/nat.py` | non versionné — résultats dans devel-phases.md | -| QUIC NAT punch | `meshbay_node.transport.quic_server` | `QuicChunkServer.punch_nat()` | -| Scripts de démo opérationnels | — | `QE/demo-v1/*.py` (non versionné) | +| AES-GCM (browser) | `meshbay_common.webcrypto` | `webcrypto.py` + `static/crypto.js` | +| Node keystore | `meshbay_node.keystore` | `keystore.py` | +| QUIC NAT punch (native) | `meshbay_node.transport.quic_server` | `QuicChunkServer.punch_nat()` | +| WebRTC transport (browser) | `meshbay_node.transport.webrtc_server` | Phase 9.3 — `aiortc` DataChannel | +| WebRTC signaling (hub) | `meshbay_hub.api.signaling` | Phase 9.2 — SDP/ICE relay | +| Browser transport client | `static/transport.js` | Phase 9.4 — WebRTC DataChannel | +| Web SPA | `static/app.js` | Phase 9.6 — Preact + preact-router | +| Demo scripts | — | `QE/demo-v1/*.py`, `QE/demo-v2/*.py` (not versioned) | ## meshbay.org server (état cible) |