Expand description
Is our mDNS service really announced on an IPv4 interface?
mdns-sd builds one socket per interface when its daemon is created. For
IPv4 that is a bind to 0.0.0.0:5353, a multicast-group join and a test
packet; if any step fails the crate logs at debug! and skips that
interface (mdns-sd’s service daemon, “bind a socket to {}: {}. Skipped.”). The
daemon still starts and LAN discovery started (mDNS) is still logged, so a
host can hear its peers (over IPv6) and never be heard. That is exactly what
happened on Area54 on 2026-10-01 (SPEC_LAN_FIREWALL_SETUP_2026_10_01.md 8.1).
The daemon already says which interfaces it announced on: its monitor
channel emits DaemonEvent::Announce(fullname, addresses) only for
interfaces that have a working socket. This module turns that into a health
verdict. It opens no socket of its own: a second receiver on UDP 5353
would compete with the daemon it is checking (Codex P1 on #4133), and
mdns-sd always answers by multicast, so a legacy-unicast probe from an
ephemeral port would never get an answer.
Structs§
- Watchdog
- Decides, tick by tick, when an undiscoverable verdict justifies a rebuild.
Enums§
Constants§
- GRACE
- How long after start the daemon gets to announce before “nothing announced” counts as a verdict. Probing plus the first announcement takes well under a second on a healthy host.
- MAX_
DOWN_ RETRIES - Ticks the watchdog will keep trying to bring the daemon back when LAN is wanted but no daemon is running (a rebuild whose new daemon failed to start). Without this a transient failure inside a rebuild would leave LAN dead until the user toggled it (ReAgent P2 on #4148).
- RETRY_
AFTER_ TICKS - Ticks to wait after rebuild attempt k (1-based) before attempt k+1; the last value repeats for ever. At the 15 s tick that is 30 s, 1 min, 2 min, 5 min, then every 10 min. There is NO cap on the number of attempts.
- STRIKES_
BEFORE_ REBUILD - Consecutive undiscoverable verdicts, one per watchdog tick, required before the daemon is rebuilt. One miss can be a slow start, not a fault.
Functions§
- evaluate
- The verdict. Only addresses we expected count: an announcement on an address
we do not listen on proves nothing about the ones we do.
missingnames one address (the lowest) per uncovered interface. - expected_
by_ interface - The IPv4 addresses a LAN peer could reach us on, grouped by interface: not loopback, unspecified, link-local (169.254/16), multicast or broadcast.
- ipv4_in
- Every IPv4 address written in
payload.mdns-sd0.12 formats the address part ofDaemonEvent::Announcetwo ways (a debug-formatted list at registration,host:addron later announcements), so this scans for dotted quads and does not depend on either shape. IPv6 is ignored: only the IPv4 socket was ever missing. - should_
publish - Whether this verdict should be sent to the windows on this tick.
- verdict
- The verdict for a daemon of a given age.