Print the allocated IPv4 address in tun-setup

The overlay IPv4 address is not derived from the keys: it is allocated at
run time and signed, so on a fresh state directory there is nothing for
tun-setup to print. Once the agent has run, the claim is in state.sqlite,
and reading it back takes no directory lock, so tun-setup can show the
`ip address add` line while the agent is running. Records are verified on
the way out; the database is not a trust boundary.

The line needs no keep_addr_on_down and no nodad, unlike its IPv6
counterpart: Linux keeps IPv4 addresses on an interface that has lost
carrier, and IPv4 has no duplicate address detection to stall.

Also fix a race in the four-agent test. A peer counts as connected once
its session authenticates, which can precede the announcement carrying
its hostname, so reading the hostnames straight away occasionally saw
only two. It now waits for them like every other success condition.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
tsunagi
2026-09-21 14:04:44 +01:00
co-authored by Claude Opus 5
parent 8b333455f1
commit 944d98389f
4 changed files with 80 additions and 16 deletions
+7 -1
View File
@@ -271,7 +271,13 @@ async fn main() -> Result<()> {
attached it has no carrier, and Linux then flushes its IPv6 addresses. The
setup printed by `tsunagi tun-setup` sets it; the agent checks the address is
present *and usable* — not tentative, not DAD-failed — before attaching, and
reports what it actually found.
reports what it actually found. This applies to IPv6 only: IPv4 addresses
survive carrier loss, so the overlay IPv4 address is added once and stays.
* **The overlay IPv4 address is not derivable, so `tun-setup` cannot print it
on a fresh state directory.** It is allocated and signed at run time, so the
first `tsunagi up` is what names it; afterwards `tun-setup` reads it back
from `state.sqlite` — a read that takes no directory lock and so does not
disturb a running agent — and includes the `ip address add` line.
* **The agent cannot assign the overlay address itself.** The `tun` crate sets
addresses through an IPv4-only ioctl, so the IPv6 overlay address must come
from `ip -6 address add` or an equivalent. The agent verifies the address is