Files
AuraVPN/crates/aura-tunnel/src
xah30 7c2080321b feat(cli,tunnel): v3.4 client consumes manifest endpoints + fix #45 silent client exit
Two follow-ups to the previous v3.4 commit (ba8d6b7):

## #49 — client uses BridgeEndpoint ports as authoritative

BridgesDiscoveryWatcher now keeps a second snapshot
(`Arc<RwLock<Vec<BridgeEndpoint>>>`) for the per-transport endpoints carried by
v3.4 manifests, alongside the existing flat-bridges snapshot for v3.3
compatibility. `endpoints_snapshot()` and `primary_endpoint()` expose it to the
client.

In `client::run`, immediately after the watcher loads, the primary endpoint's
per-transport ports override the dial-time `dial_cfg.endpoints.{tcp,quic,udp}`
*ports*. The IP stays whatever the dialer already resolved (server_addr /
bridge list). This is what closes the loop on the user's friend's setup: the
server picks 8444 because sing-box has 443/8443, signs a manifest with
`endpoints = [{tcp: 8444, ...}]`, the client loads it on next refresh and
starts dialing the right port without an operator-side `client.toml` edit.

When the manifest has no `endpoints` field (old v3.3 format, or operator
chose not to publish per-transport ports), no override is applied and the
client.toml `[transport] *_port` values are used as before.

## #45 — silent client exit on broken connection

Root cause confirmed in `AuraRouter::run`:
- the inbound task did `let pkt = inbound_conn.recv_packet().await?;`, so any
  recv error returned silently via `?`
- the `to_tun_tx` channel sender dropped, `to_tun_rx.recv()` returned `None`
- the outbound `select!` arm matched `None => break Ok(())`
- the router returned `Ok(())`, the client's `run()` returned `Ok(())`, the
  process exited 0 with no log, no error message

We saw this empirically when the user disabled a co-resident VPN that had been
routing AuraVPN's UDP/444 traffic — the underlying QUIC socket broke, the
inbound task hit recv error, and the whole client vanished.

Fix:
- Inbound task now logs the error at `error` level with the underlying
  `recv_packet` cause before exiting.
- The outbound `select!`'s `None` arm now returns an Err (not Ok(())) so the
  caller knows the tunnel died and `aura client` exits non-zero — which is
  what a supervisor (systemd, launchd, or a future auto-redial loop) wants to
  see.
- The router waits up to 200ms for the inbound task to land cleanly before
  returning, so its error / panic is logged instead of being swallowed by
  `abort()`.

Existing tests still pass (12/12 in aura-tunnel router tests). Tested
manually: with the fix, killing the underlying transport now produces a
"peer connection broke (recv_packet failed): …" error line and a non-zero
exit, instead of silent process disappearance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 17:22:10 +03:00
..