Implement the WireGuard data plane plugin
The first IP plugin, built on the data plane boundary the core already had. Plugin: - one X25519 key per network in the plugin's own wireguard.sqlite, separate from the iroh identity and from the network secret; a damaged store is an error, never a silently regenerated identity - deterministic IPv6 ULA overlay: every member derives the same /64 from the network id and its own /128 from its WireGuard public key, so no coordinator allocates addresses - AllowedIPs are derived locally, never taken from a peer's announcement, so a member cannot claim another member's overlay address; a mismatched claim is rejected - bounded, versioned, validated announcement carried as the existing opaque capability payload, which the core still never parses - each agent builds its own full-mesh configuration (N-1 peers) and reconciles on every change and on a timer, repairing drift - WireguardBackend abstraction: RecordingBackend in memory, and WgToolBackend driving real wg/ip on Linux, split into a pure planner plus parsers and a thin executor so everything interesting is testable without root Core, three generic additions the plugin needed: - IpPlugin::on_network_activated, so per-network state is ready before peers - PluginContext for re-announcements and error reports from plugin tasks, with errors counted by the owning network runtime - IpPlugin::shutdown, awaited with a grace period, so system objects go away 94 tests pass offline with no privileges: 35 new WireGuard unit tests and 12 integration tests over real iroh connections. The real wg/ip backend needs root and is behind --ignored in tests/wireguard_system.rs; it was not run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -19,8 +19,16 @@ Keep these separate. Crossing them is the main thing to review for.
|
||||
|
||||
- **Control plane vs data plane.** iroh carries control messages only. User IP
|
||||
traffic is never tunnelled through it. The core must never parse a plugin's
|
||||
payload — see `src/dataplane.rs`. Do not advertise WireGuard as available
|
||||
transport before it exists; tests use an explicitly test-only capability id.
|
||||
payload — see `src/dataplane/mod.rs`. Only
|
||||
`src/dataplane/wireguard/announcement.rs` interprets WireGuard payloads, and
|
||||
only after bounding every field. A data plane failure must never stop the
|
||||
control plane.
|
||||
- **Derived, not claimed.** A WireGuard peer's `AllowedIPs` are always derived
|
||||
locally from its public key. Never take them from what the peer announces, or
|
||||
a member can route another member's traffic to itself.
|
||||
- **Plugins own their system objects.** A plugin creates and removes its own
|
||||
interface and nothing else. An interface that already exists and is not ours
|
||||
is refused, never adopted. Never touch routing, DNS or firewall settings.
|
||||
- **Device identity vs network identity.** The iroh endpoint id is the device's
|
||||
public key. `NetworkId` is derived from name + secret only. Never conflate
|
||||
them, and never let one change the other.
|
||||
@@ -80,7 +88,7 @@ Keep these separate. Crossing them is the main thing to review for.
|
||||
| `src/proto/` | framing, message formats, membership handshake |
|
||||
| `src/net.rs` | iroh endpoint adapter and observability snapshots |
|
||||
| `src/agent/` | agent lifecycle, per-network runtimes, sessions, events, status |
|
||||
| `src/dataplane.rs` | the contract future IP plugins implement |
|
||||
| `src/dataplane/` | the contract IP plugins implement, and the WireGuard plugin |
|
||||
| `tests/` | integration tests; `tests/common/` is the shared harness |
|
||||
|
||||
Add abstractions only at real substitution or testing boundaries. Do not add a
|
||||
@@ -98,7 +106,11 @@ trait per struct. Prefer one crate with clear modules over many small crates.
|
||||
happen.
|
||||
- The default suite must pass with no internet, no DHT, no public relay, no
|
||||
administrator rights and no changes to OS network settings. Anything needing
|
||||
the internet stays out of the default set.
|
||||
the internet, or root, stays out of the default set — the real WireGuard
|
||||
backend's tests live in `tests/wireguard_system.rs` behind `--ignored`.
|
||||
- The WireGuard backend may be substituted (`RecordingBackend`). Its key
|
||||
handling, announcements, derived addressing, configuration builder and
|
||||
reconciliation may not.
|
||||
- Running several library instances in one process is not a test of several
|
||||
system processes; do not describe it as one.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user