Mac mesh break-it on dev 9b0c731e8 (J267) #375

Open
opened 2026-11-05 22:55:30 +00:00 by kayg · 5 comments
Owner

J267 break-it tester. Measure and break the merged dev mesh stack (GotaTun, mesh, mesh SSH, mesh DNS) with the macOS VM as a mesh node and compute01 as the Linux end. Report only, no code fixes.

Links: #260 (GotaTun perf), #285 (Mac parity). Decisions: D166, D327, D340, D346, D348, D352.

Base: origin/dev 9b0c731e89

Plan (estimate ~3 h):

  1. Build the release CLI on the Mac at the base SHA; measure Mac <-> compute01 over GotaTun vs the plain path (iperf3 1 and 8 flows, p99 ping RTT). Measurement, not a gate.
  2. Break cases on the Mac node: kill -9 mid-transfer + restart, interface down/up, revoke mid-flow (and after restart), userspace packet filter allowed vs denied port, mesh DNS resolve + revoked name stops resolving, stale run/state after crash, D166 no rotation in a mesh with a Mac.
  3. One issue per real bug with a reproducer, ranked by severity.
  4. Clean up Mac + Linux, release mac lock and mesh-vm claim, delete scratch targets.
J267 break-it tester. Measure and break the merged dev mesh stack (GotaTun, mesh, mesh SSH, mesh DNS) with the macOS VM as a mesh node and compute01 as the Linux end. Report only, no code fixes. Links: #260 (GotaTun perf), #285 (Mac parity). Decisions: D166, D327, D340, D346, D348, D352. Base: origin/dev 9b0c731e89b70408ac719ef3a10cb1bf36bebf99 Plan (estimate ~3 h): 1. Build the release CLI on the Mac at the base SHA; measure Mac <-> compute01 over GotaTun vs the plain path (iperf3 1 and 8 flows, p99 ping RTT). Measurement, not a gate. 2. Break cases on the Mac node: kill -9 mid-transfer + restart, interface down/up, revoke mid-flow (and after restart), userspace packet filter allowed vs denied port, mesh DNS resolve + revoked name stops resolving, stale run/state after crash, D166 no rotation in a mesh with a Mac. 3. One issue per real bug with a reproducer, ranked by severity. 4. Clean up Mac + Linux, release mac lock and mesh-vm claim, delete scratch targets.
Author
Owner

J267 start (Claude Opus 5.5). Review/break-it job, no code changes, so no branch of my own.

  • Base: origin/dev 9b0c731e89b70408ac719ef3a10cb1bf36bebf99.
  • Worktrees: claude@compute01:~/worktrees/j267, lume@mac:~/worktrees/j267 (detached at the base).
  • Builds: compute01 static x86 server (--features desktop) plus web UI, through build-slot (log ~/.cache/codex-scratch/j267/logs/build.log). Mac: cargo build --locked --release -p infraternal under lockf /tmp/mac-bench.lock (log ~/j267-evidence/build.log).
  • Setup (from J80 and J255): a throwaway root server on compute01 with private data, ports and a private software passkey. Its embedded agent is the Linux GotaTun node. The Mac enrolls with a key-bound invitation (POST /remote/invitations, agent join), then mesh up starts the launchd node.
  • ~/mesh-vm.claim on compute01 is held by J175, so the Linux side waits for it. Builds and the Mac-only checks run now.
  • Mac pre-existing state: /var/lib/infraternal/{agent,state,bin,j80-preserve,j80d-preserve} plus the plist, all from J80, with the service unloaded. I'll snapshot it before I touch it and restore it at cleanup.
**J267 start** (Claude Opus 5.5). Review/break-it job, no code changes, so no branch of my own. - Base: origin/dev `9b0c731e89b70408ac719ef3a10cb1bf36bebf99`. - Worktrees: `claude@compute01:~/worktrees/j267`, `lume@mac:~/worktrees/j267` (detached at the base). - Builds: compute01 static x86 server (`--features desktop`) plus web UI, through build-slot (log `~/.cache/codex-scratch/j267/logs/build.log`). Mac: `cargo build --locked --release -p infraternal` under `lockf /tmp/mac-bench.lock` (log `~/j267-evidence/build.log`). - Setup (from J80 and J255): a throwaway root server on compute01 with private data, ports and a private software passkey. Its embedded agent is the Linux GotaTun node. The Mac enrolls with a key-bound invitation (`POST /remote/invitations`, `agent join`), then `mesh up` starts the launchd node. - `~/mesh-vm.claim` on compute01 is held by J175, so the Linux side waits for it. Builds and the Mac-only checks run now. - Mac pre-existing state: `/var/lib/infraternal/{agent,state,bin,j80-preserve,j80d-preserve}` plus the plist, all from J80, with the service unloaded. I'll snapshot it before I touch it and restore it at cleanup.
Author
Owner

J267 progress (05:30 IST). Both builds are done at 9b0c731e8:

  • Mac: cargo build --locked --release -p infraternal, Finished release in 34m 12s, sha256 2f9863b217ba07b2c99f69403852e4194898b5f02582c176f528e9fb5f254d12. otool -L shows only Security, CoreFoundation, /usr/lib/libiconv, /usr/lib/libSystem. GotaTun comes from the fork (kaygdotorg/gotatun?rev=84b7bb28). Log: lume@mac:~/j267-evidence/build.log.
  • compute01: static x86 server, --features desktop, plus the web build. sha256 a49e75df457a52e1f70abb80bdf07d00bcb05771a0536efad23e057dd584e2f7. Log: ~claude/.cache/codex-scratch/j267/logs/build.log. The first attempt failed only because I skipped scripts/auth-toolchain (no zig, exit 127). That was my error, not a dev bug.

What the shipped binaries contain (string counts, lume@mac:~/j267-evidence/strings-check.txt):

  • hickory = 0 in the Mac binary and 0 in the Linux server binary. Mesh DNS (D327) sits behind the mesh-dns-spike feature (crates/plugins/mesh/Cargo.toml:30), and its module is Linux-only (lib.rs:71, cfg(all(feature = "mesh-dns-spike", target_os = "linux"))). No release build, Mac or Linux, can answer mesh DNS on dev. The live test confirms it below.
  • The Mac has no userspace packet filter on dev: macos_node.rs has ENFORCEMENT = "unavailable", and installed_peers installs only peers whose inbound policy is All, plus the coordinator. So D340 isn't merged yet, and the coordinator host reaches every port on the Mac, a gap the owner accepted under #265 J162 F1. The live test checks the fail-closed behaviour instead.
  • D166 scheduled WireGuard rotation isn't on dev. It's on #285 trust-285-b, which isn't merged. On dev, the Mac's only key changes are macos_key's re-registrations (enrolment change, ad-hoc keychain denial).

Baseline, plain path, Mac VM → compute01 over NetBird 10.69.69.218 (the only route between them; WAN, about 143 ms). Load on compute01 was 9.2 → 18.8, because builds were running. Data: lume@mac:~/j267-evidence/m-baseline-netbird/.

ping-idle.txt        n=300 p50=143.25 p99=178.85 max=213.10 sent/recv=300/300
ping-loaded-down.txt n=240 p50=143.10 p99=174.45 max=184.59 sent/recv=240/240
ping-loaded-up.txt   n=240 p50=143.29 p99=188.43 max=251.01 sent/recv=240/240
iperf-P1-down.json 132.4 Mbit/s retrans=138
iperf-P1-up.json    93.0 Mbit/s retrans=30
iperf-P8-down.json 374.1 Mbit/s retrans=34885
iperf-P8-up.json   161.6 Mbit/s retrans=1862

Up = Mac → Linux. Down = Linux → Mac (-R). iperf3 3.21: 12 s per run, 2 s omitted at the start.

Waiting: ~/mesh-vm.claim is still J175's (its verify fast is running). The throwaway server is staged in root@compute01:/root/j267/ and starts once the claim is free. The Mac's J80 state is snapshotted in /var/root/j267-preserve/var-lib-infraternal.tar (root-only; sha256 6103614a…efc1).

**J267 progress (05:30 IST).** Both builds are done at `9b0c731e8`: - **Mac:** `cargo build --locked --release -p infraternal`, `Finished release in 34m 12s`, sha256 `2f9863b217ba07b2c99f69403852e4194898b5f02582c176f528e9fb5f254d12`. `otool -L` shows only Security, CoreFoundation, `/usr/lib/libiconv`, `/usr/lib/libSystem`. GotaTun comes from the fork (`kaygdotorg/gotatun?rev=84b7bb28`). Log: `lume@mac:~/j267-evidence/build.log`. - **compute01:** static x86 server, `--features desktop`, plus the web build. sha256 `a49e75df457a52e1f70abb80bdf07d00bcb05771a0536efad23e057dd584e2f7`. Log: `~claude/.cache/codex-scratch/j267/logs/build.log`. The first attempt failed only because I skipped `scripts/auth-toolchain` (no zig, exit 127). That was my error, not a dev bug. **What the shipped binaries contain** (string counts, `lume@mac:~/j267-evidence/strings-check.txt`): - `hickory` = 0 in the Mac binary and 0 in the Linux server binary. Mesh DNS (D327) sits behind the `mesh-dns-spike` feature (`crates/plugins/mesh/Cargo.toml:30`), and its module is Linux-only (`lib.rs:71`, `cfg(all(feature = "mesh-dns-spike", target_os = "linux"))`). **No release build, Mac or Linux, can answer mesh DNS on dev.** The live test confirms it below. - The Mac has no userspace packet filter on dev: `macos_node.rs` has `ENFORCEMENT = "unavailable"`, and `installed_peers` installs only peers whose inbound policy is `All`, plus the coordinator. So D340 isn't merged yet, and the coordinator host reaches every port on the Mac, a gap the owner accepted under #265 J162 F1. The live test checks the fail-closed behaviour instead. - D166 scheduled WireGuard rotation isn't on dev. It's on #285 `trust-285-b`, which isn't merged. On dev, the Mac's only key changes are `macos_key`'s re-registrations (enrolment change, ad-hoc keychain denial). **Baseline, plain path, Mac VM → compute01** over NetBird `10.69.69.218` (the only route between them; WAN, about 143 ms). Load on compute01 was 9.2 → 18.8, because builds were running. Data: `lume@mac:~/j267-evidence/m-baseline-netbird/`. ``` ping-idle.txt n=300 p50=143.25 p99=178.85 max=213.10 sent/recv=300/300 ping-loaded-down.txt n=240 p50=143.10 p99=174.45 max=184.59 sent/recv=240/240 ping-loaded-up.txt n=240 p50=143.29 p99=188.43 max=251.01 sent/recv=240/240 iperf-P1-down.json 132.4 Mbit/s retrans=138 iperf-P1-up.json 93.0 Mbit/s retrans=30 iperf-P8-down.json 374.1 Mbit/s retrans=34885 iperf-P8-up.json 161.6 Mbit/s retrans=1862 ``` Up = Mac → Linux. Down = Linux → Mac (`-R`). iperf3 3.21: 12 s per run, 2 s omitted at the start. **Waiting:** `~/mesh-vm.claim` is still J175's (its `verify fast` is running). The throwaway server is staged in `root@compute01:/root/j267/` and starts once the claim is free. The Mac's J80 state is snapshotted in `/var/root/j267-preserve/var-lib-infraternal.tar` (root-only; sha256 `6103614a…efc1`).
Author
Owner

J267: measurement, Mac VM ↔ compute01 over GotaTun (dev 9b0c731e8)

Setup: a throwaway root server on compute01 (/root/j267, private data, CA and ports 45267/45268). Its embedded agent is the Linux mesh node: GotaTun, infraternal0 10.254.0.1, MTU 1380. The Mac enrolled through a key-bound invitation and agent join, then mesh up started the launchd node: utun4 10.254.0.2, MTU 1280, fork GotaTun. The only route between the two hosts is NetBird (wt0 / utun100, MTU 1280, about 143 ms RTT), so the mesh runs inside NetBird. Mesh default policy: Allow. This is a measurement, not a benchmark gate: a WAN path, shared hosts, and compute01 at load 9–19 from other jobs' builds.

Commands (Mac, under lockf /tmp/mac-bench.lock): ~/j267-evidence/measure.sh <target> <label>, which runs sudo ping -c 300 -i 0.05 idle, iperf3 -c <target> -p 45269 -t 12 -O 2 -P {1,8} [-R] -J, and during the 1-flow runs ping -c 240 -i 0.05 (loaded). The server is iperf3 -s -B <addr> -p 45269 on compute01. Up = Mac → Linux. Down = Linux → Mac.

Path 1 flow up 1 flow down 8 flows up 8 flows down idle RTT p50 / p99 loaded p99 up / down (loss)
Plain (NetBird), run 1 93.0 132.4 161.6 374.1 143.3 / 178.9 ms 188.4 / 174.5 ms (0 / 0)
Mesh (GotaTun) 119.2 0.5 125.3 33.5 144.0 / 177.4 ms 237.1 / 211.5 ms (2/240, 8/240)
Plain (NetBird), run 2, right after 63.8 145.1 297.8 529.4 143.5 / 172.6 ms 255.0 / 149.2 ms (0 / 0)

All in Mbit/s. Idle latency: the mesh adds under 1 ms. Upload is on par with the plain path. Download collapses. Evidence: lume@mac:~/j267-evidence/m-{baseline-netbird,mesh-gotatun,baseline-netbird-2}/summary.txt plus the raw JSON.

Finding F1 (P2, performance): Linux → Mac mesh TCP collapses when the underlay MTU is below the mesh MTU + overhead

  • Per-second throughput, 1 flow down: [0.0, 0.0, 0.0, 0.0, 1.08, 0.0, 1.16, 0.97, 0.0, 0.97, 0.0, 1.2, 0.96] Mbit/s, MSS 1228. A repeat with the Linux iperf3 client sending to an iperf3 server on the Mac's mesh address gave 0.2 Mbit/s, 317 retransmits (claude@compute01:~/.cache/codex-scratch/j267/evidence/l2m-mss/).
  • Cause: the mesh MTU is a constant (gotatun_tun.rs:30 MESH_MTU = 1380, macos_node.rs:49 UTUN_MTU = 1280). Nothing derives it from the route to the peer's endpoint. TCP picks MSS 1228 from the Mac's 1280, so a full inner packet is 1280 B, and the GotaTun datagram is 1280 + 32 + 8 + 20 = 1340 B, which exceeds the 1280 underlay. Every full-size packet fragments outside the tunnel.
  • UDP by size, Linux → Mac (iperf3 -u -t 8, …/evidence/l2m-udp/summary.txt):
Path, datagram, rate Loss
mesh, 1100 B (outer 1228, unfragmented), 20M / 80M 0.00% / 0.80%
mesh, 1200 B (outer 1328, fragmented), 20M ×3 37.7%, 19.4%, 19.2%
mesh, 1200 B, 80M 12.5% (sender also stalled: 14,309 of about 66k datagrams)
plain, 1200 B (1228, unfragmented), 20M / 80M 0% / 0%
plain, 1300 B (1328, fragmented), 20M ×3 0%, 0% (3.8 Mbit/s received), 69.4%
plain, 1300 B, 80M 78.2%
  • So the drops come from fragments crossing this underlay, on both paths. GotaTun itself doesn't drop anything here (unfragmented mesh traffic is clean). The product problem is that the mesh always sends packets the underlay must fragment, and Mac reassembly over this path loses them, so a mesh flow towards the Mac stalls while the plain path stays at 130+ Mbit/s. Mac → Linux (Linux reassembles) is unaffected.
  • Where it bites outside this lab: any underlay with MTU below 1340 towards a Mac, or below 1440/1460 between Linux nodes (IPv4/IPv6 outer). Examples are another VPN, some mobile links and 1280-MTU IPv6 paths. compute01's own eth0 is 1450, so even a Linux ↔ Linux mesh over IPv6 there would fragment at 1380.
  • Repro: mesh between a Mac and a Linux node whose only route crosses a 1280-MTU link, then iperf3 -c <mac mesh ip> from Linux. Expected: throughput near the plain path. Actual: under 1 Mbit/s.
  • Rejected explanations: an MTU black hole (no: 1252-byte pings, so 1280 inner, pass both ways) and GotaTun loss (no: 0% for unfragmented sizes).
  • A fix direction to decide: per-peer path MTU (probe or derive from the endpoint route) or an MSS clamp on the mesh interface. I'm not choosing; it's a foundational transport choice.

Break cases come next.

**J267: measurement, Mac VM ↔ compute01 over GotaTun (dev `9b0c731e8`)** Setup: a throwaway root server on compute01 (`/root/j267`, private data, CA and ports 45267/45268). Its embedded agent is the Linux mesh node: GotaTun, `infraternal0` 10.254.0.1, MTU 1380. The Mac enrolled through a key-bound invitation and `agent join`, then `mesh up` started the launchd node: `utun4` 10.254.0.2, MTU 1280, fork GotaTun. The only route between the two hosts is NetBird (`wt0` / `utun100`, MTU 1280, about 143 ms RTT), so the mesh runs inside NetBird. Mesh default policy: Allow. This is a measurement, not a benchmark gate: a WAN path, shared hosts, and compute01 at load 9–19 from other jobs' builds. Commands (Mac, under `lockf /tmp/mac-bench.lock`): `~/j267-evidence/measure.sh <target> <label>`, which runs `sudo ping -c 300 -i 0.05` idle, `iperf3 -c <target> -p 45269 -t 12 -O 2 -P {1,8} [-R] -J`, and during the 1-flow runs `ping -c 240 -i 0.05` (loaded). The server is `iperf3 -s -B <addr> -p 45269` on compute01. Up = Mac → Linux. Down = Linux → Mac. | Path | 1 flow up | 1 flow down | 8 flows up | 8 flows down | idle RTT p50 / p99 | loaded p99 up / down (loss) | |---|---:|---:|---:|---:|---:|---:| | Plain (NetBird), run 1 | 93.0 | 132.4 | 161.6 | 374.1 | 143.3 / 178.9 ms | 188.4 / 174.5 ms (0 / 0) | | **Mesh (GotaTun)** | **119.2** | **0.5** | **125.3** | **33.5** | 144.0 / 177.4 ms | 237.1 / 211.5 ms (2/240, 8/240) | | Plain (NetBird), run 2, right after | 63.8 | 145.1 | 297.8 | 529.4 | 143.5 / 172.6 ms | 255.0 / 149.2 ms (0 / 0) | All in Mbit/s. Idle latency: the mesh adds under 1 ms. Upload is on par with the plain path. **Download collapses.** Evidence: `lume@mac:~/j267-evidence/m-{baseline-netbird,mesh-gotatun,baseline-netbird-2}/summary.txt` plus the raw JSON. ### Finding F1 (P2, performance): Linux → Mac mesh TCP collapses when the underlay MTU is below the mesh MTU + overhead - Per-second throughput, 1 flow down: `[0.0, 0.0, 0.0, 0.0, 1.08, 0.0, 1.16, 0.97, 0.0, 0.97, 0.0, 1.2, 0.96]` Mbit/s, MSS 1228. A repeat with the Linux iperf3 client sending to an iperf3 server on the Mac's mesh address gave 0.2 Mbit/s, 317 retransmits (`claude@compute01:~/.cache/codex-scratch/j267/evidence/l2m-mss/`). - Cause: the mesh MTU is a constant (`gotatun_tun.rs:30 MESH_MTU = 1380`, `macos_node.rs:49 UTUN_MTU = 1280`). Nothing derives it from the route to the peer's endpoint. TCP picks MSS 1228 from the Mac's 1280, so a full inner packet is 1280 B, and the GotaTun datagram is 1280 + 32 + 8 + 20 = 1340 B, which exceeds the 1280 underlay. Every full-size packet fragments outside the tunnel. - UDP by size, Linux → Mac (`iperf3 -u -t 8`, `…/evidence/l2m-udp/summary.txt`): | Path, datagram, rate | Loss | |---|---| | mesh, 1100 B (outer 1228, unfragmented), 20M / 80M | 0.00% / 0.80% | | mesh, 1200 B (outer 1328, fragmented), 20M ×3 | 37.7%, 19.4%, 19.2% | | mesh, 1200 B, 80M | 12.5% (sender also stalled: 14,309 of about 66k datagrams) | | plain, 1200 B (1228, unfragmented), 20M / 80M | 0% / 0% | | plain, 1300 B (1328, fragmented), 20M ×3 | 0%, 0% (3.8 Mbit/s received), 69.4% | | plain, 1300 B, 80M | 78.2% | - So the drops come from fragments crossing this underlay, on both paths. GotaTun itself doesn't drop anything here (unfragmented mesh traffic is clean). The product problem is that the mesh always sends packets the underlay must fragment, and Mac reassembly over this path loses them, so a mesh flow towards the Mac stalls while the plain path stays at 130+ Mbit/s. Mac → Linux (Linux reassembles) is unaffected. - Where it bites outside this lab: any underlay with MTU below 1340 towards a Mac, or below 1440/1460 between Linux nodes (IPv4/IPv6 outer). Examples are another VPN, some mobile links and 1280-MTU IPv6 paths. compute01's own `eth0` is 1450, so even a Linux ↔ Linux mesh over IPv6 there would fragment at 1380. - Repro: mesh between a Mac and a Linux node whose only route crosses a 1280-MTU link, then `iperf3 -c <mac mesh ip>` from Linux. Expected: throughput near the plain path. Actual: under 1 Mbit/s. - Rejected explanations: an MTU black hole (no: 1252-byte pings, so 1280 inner, pass both ways) and GotaTun loss (no: 0% for unfragmented sizes). - A fix direction to decide: per-peer path MTU (probe or derive from the endpoint route) or an MSS clamp on the mesh interface. I'm not choosing; it's a foundational transport choice. Break cases come next.
Author
Owner

J267 progress (07:05 IST): break cases 1, 2, 4 and 5 done. Case 6 is blocked by the Mac lock.

# Case Expected Actual Evidence
1 kill -9 of the Mac mesh daemon during a 45 s upload launchd restarts it; utun, address and routes return; the flow survives; no key change Pass. pid 36534 → 38680 in about 1 s (runs 2 → 3). utun4 10.254.0.2 and both routes back. Rotation log unchanged (10 lines). Upload dipped from about 120 to 22–50 Mbit/s and recovered; 1 of 249 pings lost lume@mac:~/j267-evidence/case1-kill/
2a ifconfig utun4 down for 10 s mid-flow traffic stops while down, resumes after up, daemon untouched Pass. Same pid, no rotation. Ping gap seq 32–66. The flow resumed about 2 s after up and climbed back to 140 Mbit/s …/case2a-utun/
2b underlay en0 down for 11 s mid-flow (NetBird rebuilt utun100 too) the mesh recovers by itself Pass. Same pid, no rotation, utun4 and routes intact. Pings back about 2 s after en0 up; TCP back after its RTO backoff, ramping to about 90 Mbit/s …/case2b-en0/
2c sleep/wake – Not attempted. This Virtualization.framework VM has no reliable wake source, so 2b stands in for it –
4 Access rules, default Deny only granted ports pass, each way Mac → Linux (Linux node enforces): with no grant only the control plane 45268 passes, and 45267/45269/45271 are refused. Grant Mac→Linux tcp/45269: 45269 connects, 45271 refused. Linux → Mac, grant tcp/45270: 45270 connects; 45272 and 22 time out at the Linux egress set. The Mac itself enforces nothing. With 10.254.0.2 . 45272 and . 22 added to Linux's outgoing4_tcp (standing in for a peer that ignores the rules), the Mac accepts 45272 and its sshd on 22. This is the documented gap (macos_node.rs ENFORCEMENT="unavailable", #265 J162 F1, D340 not merged yet), confirmed live, so no new issue. Elements removed afterwards /tmp/j267-case4-bypass.txt (copied to compute01 evidence)
5 Mesh DNS from the Mac names resolve; a revoked peer's name stops Not available on dev. Nothing answers on 10.254.0.1:53 or 10.254.0.2:53 (dig times out). No /etc/resolver, no scutil resolver for internal, and Linux resolvectl reports "not found". The only cause in the code: D327 DNS is behind mesh-dns-spike, Linux-only, enabled in no release (0 hickory strings in either binary). The revoked-name half can't be tested until it ships dig output in the job log

Correction to my 05:30 comment: WireGuard rotation (#285) is on dev now. It merged at 363d95468, after my base 9b0c731e8 (origin/dev moved to 0b72f638a during this run). My statement held for the base, but D166 can now be tested, so I'm rebuilding both sides at 0b72f638a (Linux queued in build-slot). The D166 case will run on that build, against a fresh server.

Candidate P3 (setup UX): on a Mac already enrolled with another server, agent prepare-join-key <new origin> prints the old identity's key digest (remote.rs:291 prepared_key reuses identity.json). agent join then refuses that invitation on purpose (remote.rs:471, different server), with only "Remote infraternal agent operation failed". J80c lost time to the same trap (#265, 76774). The fix belongs in the CLI wording or in prepare-join-key refusing. Not filed separately yet.

Blocked now: the Mac lock (/tmp/mac-bench.lock) has been held for 16+ minutes by an idle interactive shell (netbird ssh exec … lockf -k /tmp/mac-bench.lock bash -l, pid 40239, not mine), so case 6 (revoke) is queued. The node delete already landed (revision 6, Linux sets emptied at 01:23:18 UTC); the Mac part will show whether traffic stays stopped across kill -9 and mesh down/up. Whoever holds the lock: please take it per step only.

**J267 progress (07:05 IST): break cases 1, 2, 4 and 5 done. Case 6 is blocked by the Mac lock.** | # | Case | Expected | Actual | Evidence | |---|---|---|---|---| | 1 | `kill -9` of the Mac mesh daemon during a 45 s upload | launchd restarts it; utun, address and routes return; the flow survives; no key change | **Pass.** pid 36534 → 38680 in about 1 s (`runs` 2 → 3). `utun4` 10.254.0.2 and both routes back. Rotation log unchanged (10 lines). Upload dipped from about 120 to 22–50 Mbit/s and recovered; 1 of 249 pings lost | `lume@mac:~/j267-evidence/case1-kill/` | | 2a | `ifconfig utun4 down` for 10 s mid-flow | traffic stops while down, resumes after `up`, daemon untouched | **Pass.** Same pid, no rotation. Ping gap seq 32–66. The flow resumed about 2 s after `up` and climbed back to 140 Mbit/s | `…/case2a-utun/` | | 2b | underlay `en0` down for 11 s mid-flow (NetBird rebuilt `utun100` too) | the mesh recovers by itself | **Pass.** Same pid, no rotation, `utun4` and routes intact. Pings back about 2 s after `en0` up; TCP back after its RTO backoff, ramping to about 90 Mbit/s | `…/case2b-en0/` | | 2c | sleep/wake | – | **Not attempted.** This Virtualization.framework VM has no reliable wake source, so 2b stands in for it | – | | 4 | Access rules, default **Deny** | only granted ports pass, each way | **Mac → Linux** (Linux node enforces): with no grant only the control plane 45268 passes, and 45267/45269/45271 are refused. Grant Mac→Linux tcp/45269: 45269 connects, 45271 refused. **Linux → Mac**, grant tcp/45270: 45270 connects; 45272 and 22 time out at the **Linux egress** set. **The Mac itself enforces nothing.** With `10.254.0.2 . 45272` and `. 22` added to Linux's `outgoing4_tcp` (standing in for a peer that ignores the rules), the Mac accepts 45272 and its sshd on 22. This is the documented gap (`macos_node.rs` `ENFORCEMENT="unavailable"`, #265 J162 F1, D340 not merged yet), confirmed live, so no new issue. Elements removed afterwards | `/tmp/j267-case4-bypass.txt` (copied to compute01 evidence) | | 5 | Mesh DNS from the Mac | names resolve; a revoked peer's name stops | **Not available on dev.** Nothing answers on 10.254.0.1:53 or 10.254.0.2:53 (`dig` times out). No `/etc/resolver`, no `scutil` resolver for `internal`, and Linux `resolvectl` reports "not found". The only cause in the code: D327 DNS is behind `mesh-dns-spike`, Linux-only, enabled in no release (0 `hickory` strings in either binary). The revoked-name half can't be tested until it ships | dig output in the job log | **Correction to my 05:30 comment:** WireGuard rotation (#285) **is** on dev now. It merged at `363d95468`, **after** my base `9b0c731e8` (origin/dev moved to `0b72f638a` during this run). My statement held for the base, but D166 can now be tested, so I'm rebuilding both sides at `0b72f638a` (Linux queued in build-slot). The D166 case will run on that build, against a fresh server. **Candidate P3 (setup UX):** on a Mac already enrolled with another server, `agent prepare-join-key <new origin>` prints the **old** identity's key digest (`remote.rs:291` `prepared_key` reuses `identity.json`). `agent join` then refuses that invitation on purpose (`remote.rs:471`, different server), with only "Remote infraternal agent operation failed". J80c lost time to the same trap (#265, 76774). The fix belongs in the CLI wording or in `prepare-join-key` refusing. Not filed separately yet. **Blocked now:** the Mac lock (`/tmp/mac-bench.lock`) has been held for 16+ minutes by an idle interactive shell (`netbird ssh exec … lockf -k /tmp/mac-bench.lock bash -l`, pid 40239, not mine), so case 6 (revoke) is queued. The node delete already landed (revision 6, Linux sets emptied at 01:23:18 UTC); the Mac part will show whether traffic stays stopped across `kill -9` and `mesh down/up`. Whoever holds the lock: please take it per step only.
Author
Owner

J267 final: Mac mesh break-it. This was a review/measurement job: no code changed, so the gate doesn't apply. Bases: dev 9b0c731e8 (measurement, cases 1–6), plus dev 0b72f638a for D166, because #285 merged mid-run at 363d95468.

Measurement (Mac VM ↔ compute01, NetBird underlay MTU 1280, ~143 ms; Mbit/s; full table in the "J267: measurement" comment)

Path 1 flow up / down 8 flows up / down idle RTT p99
Plain (two runs) 93.0 / 132.4 · 63.8 / 145.1 161.6 / 374.1 · 297.8 / 529.4 178.9 · 172.6 ms
GotaTun mesh 119.2 / 0.5 125.3 / 33.5 177.4 ms (adds under 1 ms)

Uploads over the mesh match the plain path. Downloads to the Mac collapse because of outer fragmentation (#381).

Break cases (Mac as the mesh node, Linux = the server's embedded agent)

# Case Result
1 kill -9 of the Mac daemon mid-transfer Pass. launchd restart in about 1 s, utun and routes back, flow survives, no key change
2a/2b utun4 down/up; underlay en0 down 11 s Pass both. Same daemon, recovery about 2 s after up. Sleep/wake not attempted (VM)
4 Access rules, default Deny Linux side: pass in both directions (granted ports pass, others are refused). The Mac enforces nothing itself: documented gap until D340, confirmed live including sshd :22, no new issue
5 Mesh DNS Not available. No release build includes it (mesh-dns-spike, Linux-only), so nothing answers. The revoked-name half can't be tested
6 Mesh node delete, then kill -9 and mesh down/up Pass. Stays cut; no auto re-join (tombstone)
6b Host revocation mid-flow Pass. 105 → 0 Mbit/s at the revoke; Linux drops the Mac within about 3 s; stays cut after kill -9 and down/up
7 Stale /run/state after a crash Linux node: fail (#382). Mac: re-enrolment forgets the old state correctly, but mesh status says "running" while cut off (#383)
D166 Rotation in a mesh with a Mac (kernel-engine Linux node, interval 120 s) Pass. Control: the Linux-only mesh rotated twice. With the Mac enrolled: no rotation for 301 s (2.5 periods), peer_unsupported. Mac deleted → rotation started within 3 s. Mixed version: a 9b0c Mac counts as non-rotating

Findings (issues filed, each with a reproducer)

  • P1: none.
  • P2: #379 dev doesn't build on macOS since the #285 merge (restart.rs SO_PEERCRED). #380 nodes built before #285 get no mesh from an upgraded server, silently (Peer.previous_active against deny_unknown_fields). #381 Linux → Mac throughput collapse from the fixed MTU. #382 stale node state refuses a new or restored server's snapshots (J255 F4; may be P1 if restore-from-backup is supported).
  • P3: #383 infraternal status says "not set up" on an enrolled Mac, and cut-off nodes look healthy. #384 prepare-join-key returns the old server's digest. #385 every completed rotation logs an ERROR at store.rs:199.
  • Noted, not filed (not reproduced cleanly in a real browser): on a fresh server, the "Unlock" toast's button was covered by div.cl-region in my headless driver and needed a JS click, and the toast said "The server restarted" on a brand-new server. Also, invitations returned 503 for a few seconds after a reported unlock.

Cleanup

  • Mac: service stopped (unloaded and launchd-disabled, as mesh down leaves it). /var/lib/infraternal and the plist restored to the J80 state from my snapshot: the same files and dates, binary 7dcc2272…, plist byte-identical. The only exception is the stale 3 Nov plugins.sock socket, which tar can't archive; the next daemon start recreates it. Hosts line, listeners, preserve dir (with throwaway keys) and worktree removed. Kept: ~/j267-evidence (1 MB).
  • compute01: throwaway servers, embedded agents and 3 orphan shims stopped by PID. infraternal0 and inet infraternal_mesh deleted (neither existed before). /run/infraternal restored to what I found: the two stale J255-F4 files, hashes checked, empty sessions. /root/j267 deleted. iperf servers, the browser driver, software-authenticator state, the target dir and the worktree removed. ~/mesh-vm.claim released. Kept: ~/.cache/codex-scratch/j267/{evidence,logs} (716 KB).
  • Process slips on my side, all fixed during the run: one pkill -f matched only my own ssh shell, and two driver instances briefly overlapped.
**J267 final: Mac mesh break-it.** This was a review/measurement job: no code changed, so the gate doesn't apply. Bases: dev `9b0c731e8` (measurement, cases 1–6), plus dev `0b72f638a` for D166, because #285 merged mid-run at `363d95468`. ### Measurement (Mac VM ↔ compute01, NetBird underlay MTU 1280, ~143 ms; Mbit/s; full table in the "J267: measurement" comment) | Path | 1 flow up / down | 8 flows up / down | idle RTT p99 | |---|---|---|---| | Plain (two runs) | 93.0 / 132.4 · 63.8 / 145.1 | 161.6 / 374.1 · 297.8 / 529.4 | 178.9 · 172.6 ms | | GotaTun mesh | **119.2 / 0.5** | **125.3 / 33.5** | 177.4 ms (adds under 1 ms) | Uploads over the mesh match the plain path. Downloads to the Mac collapse because of outer fragmentation (#381). ### Break cases (Mac as the mesh node, Linux = the server's embedded agent) | # | Case | Result | |---|---|---| | 1 | `kill -9` of the Mac daemon mid-transfer | **Pass.** launchd restart in about 1 s, utun and routes back, flow survives, no key change | | 2a/2b | `utun4` down/up; underlay `en0` down 11 s | **Pass** both. Same daemon, recovery about 2 s after up. Sleep/wake not attempted (VM) | | 4 | Access rules, default Deny | Linux side: **pass** in both directions (granted ports pass, others are refused). **The Mac enforces nothing itself**: documented gap until D340, confirmed live including sshd :22, no new issue | | 5 | Mesh DNS | **Not available.** No release build includes it (`mesh-dns-spike`, Linux-only), so nothing answers. The revoked-name half can't be tested | | 6 | Mesh node delete, then `kill -9` and `mesh down`/`up` | **Pass.** Stays cut; no auto re-join (tombstone) | | 6b | Host revocation mid-flow | **Pass.** 105 → 0 Mbit/s at the revoke; Linux drops the Mac within about 3 s; stays cut after `kill -9` and `down`/`up` | | 7 | Stale `/run`/state after a crash | Linux node: **fail** (#382). Mac: re-enrolment forgets the old state correctly, but `mesh status` says "running" while cut off (#383) | | D166 | Rotation in a mesh with a Mac (kernel-engine Linux node, interval 120 s) | **Pass.** Control: the Linux-only mesh rotated twice. With the Mac enrolled: no rotation for 301 s (2.5 periods), `peer_unsupported`. Mac deleted → rotation started within 3 s. Mixed version: a 9b0c Mac counts as non-rotating | ### Findings (issues filed, each with a reproducer) - **P1:** none. - **P2:** #379 dev doesn't build on macOS since the #285 merge (`restart.rs` `SO_PEERCRED`). #380 nodes built before #285 get no mesh from an upgraded server, silently (`Peer.previous_active` against `deny_unknown_fields`). #381 Linux → Mac throughput collapse from the fixed MTU. #382 stale node state refuses a new or restored server's snapshots (J255 F4; may be P1 if restore-from-backup is supported). - **P3:** #383 `infraternal status` says "not set up" on an enrolled Mac, and cut-off nodes look healthy. #384 `prepare-join-key` returns the old server's digest. #385 every completed rotation logs an ERROR at `store.rs:199`. - Noted, not filed (not reproduced cleanly in a real browser): on a fresh server, the "Unlock" toast's button was covered by `div.cl-region` in my headless driver and needed a JS click, and the toast said "The server restarted" on a brand-new server. Also, invitations returned 503 for a few seconds after a reported unlock. ### Cleanup - **Mac:** service stopped (unloaded and launchd-disabled, as `mesh down` leaves it). `/var/lib/infraternal` and the plist restored to the J80 state from my snapshot: the same files and dates, binary `7dcc2272…`, plist byte-identical. The only exception is the stale 3 Nov `plugins.sock` socket, which tar can't archive; the next daemon start recreates it. Hosts line, listeners, preserve dir (with throwaway keys) and worktree removed. Kept: `~/j267-evidence` (1 MB). - **compute01:** throwaway servers, embedded agents and 3 orphan shims stopped by PID. `infraternal0` and `inet infraternal_mesh` deleted (neither existed before). `/run/infraternal` restored to what I found: the two stale J255-F4 files, hashes checked, empty `sessions`. `/root/j267` deleted. iperf servers, the browser driver, software-authenticator state, the target dir and the worktree removed. `~/mesh-vm.claim` released. Kept: `~/.cache/codex-scratch/j267/{evidence,logs}` (716 KB). - Process slips on my side, all fixed during the run: one `pkill -f` matched only my own ssh shell, and two driver instances briefly overlapped.
Sign in to join this conversation.
No labels
launch-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal#375
No description provided.