Skip to content

Releases: zozo6015/wireMesh

WireMesh v0.11.1

Choose a tag to compare

@github-actions github-actions released this 27 Aug 12:38
Immutable release. Only release title and notes can be modified.
v0.11.1
39b7bfa

WireMesh v0.11.1

Patch release: the data-plane fix for the Phase-0 "receive-side cap" — a ~380× throughput defect in the gateway's embedded WireGuard engine.

Fixed

  • gateway: boringtun's per-peer connected UDP socket never worked (#106).
    boringtun 0.6.0 creates the per-peer connected socket with Type::STREAM +
    IPPROTO_UDP (device/peer.rs:120) — the kernel returns EPROTONOSUPPORT
    on every received packet, so the connected-socket receive fast path was
    silently dead and the device loop drained ~286 pps (~3 Mbit/s TCP through
    the tunnel, 97% receiver-side UDP loss as RcvbufErrors). Upstream fixed
    this on master (b8c668f, PR #430) but never cut a release; WireMesh now
    pins boringtun 0.6.0 plus that exact cherry-picked commit via
    [patch.crates-io] (fork rev b8c6ddc). The patch retires the day a
    crates.io boringtun release >0.6.0 contains b8c668f.

Measured (G-2 harness, netns + veth, MTU 1280, EPYC 9454P bare metal)

Metric v0.11.0 v0.11.1
TCP through the tunnel (pinned 4 vCPU) 3.04 Mbit/s 966 Mbit/s
TCP through the tunnel (unpinned) — 1.15 Gbit/s
UDP 100M offered, receiver loss 97% 0%

Evidence chain: docs/research/g2-bet1-receive-cap-reproduced-on-bare-metal.md
(#104) and docs/research/g2-root-cause-one-word-boringtun-fix.md (#105).

Notes

  • No config, proto, or CLI surface changes; drop-in replacement for v0.11.0.
  • All 7 CI jobs green on the PR, including the netns conformance suites —
    the first behavioural exercise of the now-working connected-socket path
    (mesh, NAT matrix, relay, rotation all pass unchanged).
  • G-2 formal standing: single-flow meets the ≥1 Gbps bar unpinned on EPYC
    (966 Mbit/s pinned; per-core clocks below the reference c6i.xlarge); the
    8-tunnel aggregate half still needs its harness.

WireMesh v0.11.0

Choose a tag to compare

@github-actions github-actions released this 26 Aug 17:34
Immutable release. Only release title and notes can be modified.
v0.11.0
0ca9d22

v0.11.0 — version fields on the wire (B10)

Minor release. Additive proto fields and a schema migration (SCHEMA_V4); no behaviour depends on the new fields.

Added

  • Every gateway and relay now reports its version. WatchRequest and EnrollRequest carry client_version (gateways also max_ir_schema); every StateSnapshot carries controller_version and min_supported_version; Admin.ListGateways exposes the reported pair. The controller stores these and never consults them in this release — no gating of any kind. Shipping them now is what makes a future skew policy (PRD X-6: controller vN supports vN and vN−1, one minor, non-cumulative) able to attribute v1.0 peers at all. (PR #94)
  • min_supported_version is derived from the controller's own version, not hand-maintained (the previous minor once ≥ 1.0.0; the controller's own minor before that), so the advertised floor cannot go stale at a release. Advertised, not enforced.
  • SCHEMA_V4: gateway.version, gateway.max_ir_schema, relay.version — all nullable; a never-reported value is NULL, never ""/0. Relays have no policy IR, so relay deliberately has no max_ir_schema column.

Operator notes

  • Legacy (pre-0.11) gateways and relays enroll and sync unchanged; their rows show NULL for the new columns.
  • The punch-retry log line now reads "broker re-punches on its ~5s sweep, up to a bounded retry budget".

Still off by default

Automatic key rotation remains off.

Full Changelog: v0.10.7...v0.11.0

WireMesh v0.10.7

Choose a tag to compare

@github-actions github-actions released this 26 Aug 17:20
Immutable release. Only release title and notes can be modified.
v0.10.7
941ed5f

v0.10.7 — the ROTATION STALLED warning names the right epoch

Patch release. Gateway-only.

Fixed

  • ROTATION STALLED named the wrong epoch after an abort. The warning (introduced in v0.10.6) computed its target as old_epoch + 1; after a rotation abort the next directive skips an epoch, so the line an operator reads when a rotation is stuck named the aborted epoch beside the correct new tun. The epoch now comes from the rotation state machine's own Overlapping { new_epoch } via a typed selection that cannot express the old arithmetic. (PR #93)

Test infrastructure

  • WIREMESH_TEST_OVERLAP_STALL_WARN_SECS (netns-tests feature only; compiled out of release binaries, verified with a positive control) lets the harness reach a genuine R2 stall in seconds instead of 90s. All test-only knobs now live in config::fault and nowhere else. The production threshold is unchanged at 90s.

Still off by default

Automatic key rotation remains off. Phase C items unchanged.

Full Changelog: v0.10.6...v0.10.7

WireMesh v0.10.6

Choose a tag to compare

@github-actions github-actions released this 26 Aug 09:02
Immutable release. Only release title and notes can be modified.
v0.10.6
a764233

v0.10.6 — a failed rotation unwinds itself (backlog item 9, route R1)

Patch release. Gateway-only; no proto or config change.

Fixed

  • The rotation wedge (backlog item 9, route R1). A rotation that failed part-way left the gateway's rotation state machine parked off Idle, and Rotation::on_directive is honoured only from Idle — so the gateway silently ignored every later RotateDirective until the process restarted, and the minted private key for the failed epoch survived on disk. handle_rotate now unwinds its own failure synchronously: drops the in-flight role, tears the new epoch's tun down, evicts its enforcer, scrubs the orphan mint from epoch_keys.json, and returns the state machine to Idle last, so the next directive is honoured. EpochKeys::generate_next is replaced by generate_next_at(n) — the gateway mints at the epoch the controller directed rather than keeping a second local counter that diverged the moment a scrub removed an entry. (PR #90)
  • Observability: wiremesh_gateway_rotation_phase{phase} gauge and rotation_aborts_total; a ROTATION STALLED warning after 90s in Overlapping (route R2 is not aborted gateway-side — that would be a hard blackhole — it is surfaced).
  • Test-only fault hook (netns-tests feature; compiled out of release binaries, verified by strings).

Found on the way

This release's done-bar (crates/wiremesh-gateway/tests/rotation_wedge.rs) found two controller defects that had been latent because clean aborts were never routine: the broker directing the aborted epoch's orphan sentinel (v0.10.4) and the tracker seeding from it and dropping the real epoch's ack (v0.10.5). This release depends on both.

Still off by default

Automatic key rotation remains off (no WIREMESH_ROTATION_INTERVAL = no timer). Route R1 of item 9 is closed; the timer stays off pending R2/R15 and the orphan-row lifecycle at abort ((C-drop)/(E)), all Phase C. Backlog item 34 records the 5s lost-directive window after an unwind (nothing retries a directive — C1).

Full Changelog: v0.10.5...v0.10.6

WireMesh v0.10.5

Choose a tag to compare

@github-actions github-actions released this 26 Aug 07:57
Immutable release. Only release title and notes can be modified.
v0.10.5
6aee6cc

v0.10.5 — the rotation tracker seeds from the newest pending row

Patch release. Controller-only; no proto, config, or gateway change.

Fixed

  • The controller's RotationTracker was seeded from the oldest pending key row. After a gateway-side rotation abort (v0.10.x Phase B, backlog item 9), the aborted rotation leaves an awaiting-submission sentinel row behind, and every later rotation's tracker was seeded from that orphan instead of the live rotation. The gateway's one-shot EpochAck for the real epoch then failed the tracker's epoch check and was dropped silently, so the real epoch was not promoted until the orphan aborted (~300s) and a zero-ack grace promote fired (~390s total) — reaching the right state by the hazard path, not the designed one. Seen as a deterministic red in rotation_wedge's 120s poll (3/3). All three seed sites (seed_and_record_epoch_acks, drive_rotation_for, sweep_rotations step 2) now share one private selector that picks the max-epoch pending row, threaded to both the lazy seed and the evict_decision staleness input at the two sweep-side sites. (PR #88)
  • This is deliberately not the broker's newest-sentinel selector from v0.10.4: on {orphan sentinel below an active epoch} the tracker must still seed the sentinel, because that tracker is the orphan's only garbage collector (Abort at ABORT_AFTER → drop_pending_epoch); seeding nothing there strands the row and initiate_due_rotations skips the gateway permanently. A test pins the difference with the consequence in its failure message.

Observability

  • The controller now logs an EpochAck whose epoch is not the rotation in flight (ignoring EpochAck(epoch=N) from gateway A for gateway B: the rotation in flight is epoch K). No state change on that path; a counter is a Phase-C item (the controller has no metrics surface yet).

Documented

  • docs/research/orphan-sentinel-mis-seeds-tracker.md — the mechanism, the ~390s self-heal (why a larger test budget would have passed a broken controller), the one-shot ack, and the measured site-guarding asymmetry (sweep_rotations step 2 is guarded only by the identity-stamp churn test, because step 2b re-arbitrates every gateway after it).
  • docs/BACKLOG.md item 35 (Phase C): make-before-break is enforced on the data plane, not on the roster — a rotating gateway destroys its retired key while the controller row still advertises it active; the window exists on the healthy path, this release only shortens it back.

Still off by default

Automatic key rotation remains off (no WIREMESH_ROTATION_INTERVAL = no timer). This release clears the second controller defect found by the Phase-B rotation-wedge done-bar; the timer stays off pending the Phase-C items (R2/R15, (C-drop)/(E)).

Full Changelog: v0.10.4...v0.10.5

WireMesh v0.10.4

Choose a tag to compare

@github-actions github-actions released this 26 Aug 02:44
Immutable release. Only release title and notes can be modified.
v0.10.4
44683d9

WireMesh v0.10.4

Patch release: the controller now directs a rotation only when the gateway's newest key row is still awaiting its key (PR1b, design Rev 1.40).

Fixed

  • controller: after a gateway aborted a rotation cleanly, the aborted epoch's pending row (sentinel pubkey) survived until ABORT_AFTER, and Broker::send_rotate_if_pending selected the FIRST sentinel row in ascending epoch order — so the next Admin.RotateKey directed the stale orphan epoch instead of the one it had just created; the gateway rotated to the stale epoch, refused the correct directives as in-flight, and the new epoch was never served. The broker now takes the max-epoch row over all rows and directs it only if it is a sentinel. Filter order matters: "highest sentinel" alone would later direct the orphan and rotate the fabric backwards, deleting the newer key.

Evidence

Six unit cases incl. the backwards-rotation guards; two falsification runs (.find() revert; filter-then-max) each redding exactly the cases that discriminate them; full controller suite green; no new clippy diagnostics.

Unchanged

Automatic key rotation stays off by default. Follow-ups filed for Phase C: an orphan pending row still suppresses timer-driven rotation for that gateway for up to 300s; epoch monotonicity guards on both sides.

Full diff: v0.10.3...v0.10.4

WireMesh v0.10.3

Choose a tag to compare

@github-actions github-actions released this 26 Aug 00:42
Immutable release. Only release title and notes can be modified.
v0.10.3
b1605bc

WireMesh v0.10.3

Patch release: relay ALPN pinned to one constant set with negotiated readback and distinguishable connect failures, plus a per-(peer, relay) connect back-off on the gateway (Phase B / D2, PR #82). Closes BACKLOG item 19.

Changed

  • relay: ALPN_V0 / ALPN_SUPPORTED are the single source of truth consumed by both server builders, the client endpoint, and the tests. The v1.0 client offers wiremesh-relay/0 only (owner ruling 2026-08-25); a future /1 is a one-line addition, and a test client offering [/1, /0] proves it negotiates /0.
  • relay: Client::negotiated_alpn() reads the handshake result back; the registration log line carries alpn="…" and a per-ALPN session counter (the deprecation anchor for /0).
  • relay: connect failures are classified at every finish_connect step on the raw error — AlpnMismatch, PeerRejectedCredentials(alert), Unreachable, Other — attached as the anyhow chain root; a credentials rejection surfaces at the ack read, not the connect.
  • gateway: a per-(peer, relay) connect back-off replaces the silent per-tick retry: 3 transient failures or 1 permanent (ALPN mismatch / rejected credentials) open a jittered window (30s base, 300s hard cap); an expired window always allows again, so a relay-only pair is never starved. An unparseable advertised endpoint is recorded like any other failure (found in review).

Evidence

  • relay/tests/alpn.rs 8/8; relay lib + 14 integration targets green; gateway lib 114 + punch_backoff 9 + relay_connect_backoff 14 green.
  • relay_matrix netns done-bar full marks (3 passed, case5 ignored by design): the symmetric-NAT pair stays path_state=relayed; relay eviction re-paths; relay-leg death recovers a real direct path.
  • Clippy identity diffs vs main: no new diagnostics in either crate.

Unchanged

Automatic key rotation stays off; unaffected by this release.

Full diff: v0.10.2...v0.10.3

WireMesh v0.10.2

Choose a tag to compare

@github-actions github-actions released this 25 Aug 22:46
Immutable release. Only release title and notes can be modified.
v0.10.2
2790292

WireMesh v0.10.2

Patch release: closes BACKLOG item 5 — the controller's Retire{0} wedge (Phase B / S3, PR #80).

Fixed

  • controller: a rotation tracker seeded from a key snapshot with no active row got prior_active_epoch = 0; once promoted it yielded Retire{0} on every tick, Db::retire_epoch's CAS matched nothing forever, and the stale tracker silently cost the next rotation its first EpochAck (falling back to the 90s grace promote). prior_active_epoch is now Option<u32> end to end, the coercion is gone from all three seed sites (drive_rotation_for, sweep_rotations step 2, and the Sync.Report ack path via the hoisted seed_and_record_epoch_acks), and decide yields the new RotationDecision::Finished — the tracker clears with no DB call.

Evidence

  • Full wiremesh-controller suite green (47 targets); 54 lib tests incl. five new pins.
  • Falsification: each seed site's .or(Some(0)) restored in turn turned exactly its own test red (3 runs, 12/12 results), and recorded_session_generation's unrelated .unwrap_or(0) is pinned as not-a-seed-site.
  • Clippy identity diff vs main: no new diagnostics.

Unchanged

Automatic key rotation stays off by default. This was hardening, not a timer gate; BACKLOG item 9 (the gateway rotation wedge, PR1/B2) is the remaining code gate, and the timer stays off pending R2/R15 (Phase C).

Full diff: v0.10.1...v0.10.2

WireMesh v0.10.1

Choose a tag to compare

@github-actions github-actions released this 25 Aug 17:06
Immutable release. Only release title and notes can be modified.
v0.10.1
e80ebe2

v0.10.0 was tagged but never published: its Release workflow failed in
the linux-binaries jobs because deploy/docker/Dockerfile ran an unpinned
cargo install bpf-linker, upstream released 0.11.0 (which links against
system LLVM), and rust:1-bookworm ships no llvm-config. Nothing in this
repo had changed -- the same content built green two days earlier. This
release pins bpf-linker to 0.10.4 (the version the dev container carries
and the whole test suite is proven against) in both Dockerfiles, and is
otherwise v0.10.0. Its notes follow, and they apply in full.

Note for CI: container-images.yml restores a cached builder layer, so it
never re-ran the install and stayed green; only the cold build in
release.yml reaches that line. The failure mode is invisible until a
release. (Tracked under B4 in the v1.0 release-scope inventory.)

v0.10.0 — automatic key rotation is opt-in; every artifact reports its real version

BEHAVIOUR CHANGE, read before upgrading. An absent WIREMESH_ROTATION_INTERVAL
used to mean "rotate every gateway every 30 days". It now means NO TIMER.
Automatic key rotation is opt-in in every deployment path -- .deb/.rpm,
container image, and source build alike. If you were relying on the old
default, this upgrade silently stops rotating and you must set an explicit
interval to get it back.

Why: the timer pointed at a known-open defect (BACKLOG item 9, the rotation
wedge). A rotation that fails part-way parks a gateway's state machine
off-idle, and that gateway then silently ignores every later rotation until
its process restarts, never scrubbing the old key. The schedule is what makes
that fabric-wide. Explicit intervals, off, and every malformed-value
rejection are unchanged.

Know before you arm it: on-demand rotation has NO CLI. The Admin RotateKey
RPC exists and works, but fabricctl does not wrap it, so triggering a
rotation means a hand-rolled gRPC call against an Admin service that binds
loopback-only by design -- from the controller host. Earlier releases
documented fabricctl rotation as the supported path; that was never true.
Tracked as BACKLOG item 33.

FIXED: every published container image reported 0.1.0. container-images.yml
never invoked scripts/set-version.sh, so controller, gateway, relay,
fabricctl and operator images all self-reported the placeholder on every
release. Binaries and packages were always stamped correctly. This is the
first release whose images report their real version. set-version.sh also
gained wiremesh-operator, which it had never stamped.

Also: the README described a project three cycles stale and linked to
neither install guide; the spike/ directory (8 throwaway Phase-0 crates,
8 of 10 open Dependabot alerts) is deleted; and the controller --help
DEPLOYMENT block, wrong three ways since v0.8.0, is corrected.

What's Changed (since v0.9.2 — v0.10.0 was never published)

  • fix(controller): automatic key rotation is now opt-in everywhere by @zozo6015 in #73
  • fix(release): stamp the version into every shipped artifact by @zozo6015 in #74
  • docs: rewrite the README, delete spike/, fix the manual-rotation claim by @zozo6015 in #75
  • fix(build): pin bpf-linker to 0.10.4, unbreaking the release build by @zozo6015 in #76

Full Changelog: v0.9.2...v0.10.1

WireMesh v0.9.2

Choose a tag to compare

@github-actions github-actions released this 11 Aug 18:23
Immutable release. Only release title and notes can be modified.
v0.9.2
692ad68

What's Changed

  • docs(progress): v0.9.1 — the last key-rotation blocker is cleared by @zozo6015 in #71

Full Changelog: v0.9.1...v0.9.2