The Network
LAN discovery with mDNS
Lesson 5 of 10
What you'll learn
- Understand what mDNS is and why it needs no central server
- See how nodes announce themselves and discover peers on a LAN
- Know why presence needs heartbeats and a prune timeout
When two of your machines are on the same Wi-Fi, they shouldn't need the internet — or any configured server — to find each other. mDNS (multicast DNS) is how. It's the same protocol behind "your printer just shows up": a node multicasts "I'm here, I'm quorum._tcp at 192.168.1.42:32768" to a group address every machine on the LAN is listening to. No registry, no config, no cloud.
Quorum advertises a service over mDNS and simultaneously browses for others advertising the same service. Discovery is symmetric: every node is both announcer and listener, so a new machine appears to the whole subnet within seconds of launching.
Announce and browse
// apps/desktop/internal/discovery — using a zeroconf/mDNS library
server, _ := zeroconf.Register(
nodeID, // instance name
"_quorum._tcp", // service type
"local.", // domain
32768, // port
[]string{"id=" + nodeID, "v=0.8.5"}, // TXT metadata
nil,
)
defer server.Shutdown()
// Browse for peers advertising the same service.
entries := make(chan *zeroconf.ServiceEntry)
go resolver.Browse(ctx, "_quorum._tcp", "local.", entries)
for e := range entries {
cluster.Add(peerFrom(e)) // AddrIPv4, Port, TXT records
}
Discovery only tells you a peer exists. Knowing it's still alive is a separate job. Machines sleep, drop off Wi-Fi, and quit without a goodbye. So each node sends periodic heartbeats, and every node prunes peers it hasn't heard from within a timeout — Quorum uses a few retries with backoff and a five-minute prune window, so a brief blip doesn't evict a healthy node.
Prefer the LAN IP, not the VPN one
A machine often has several addresses — its real LAN IP plus a Tailscale or VPN address. Advertising the wrong one makes peers unreachable. Quorum prefers RFC 1918 LAN ranges (192.168.x, 10.x) over VPN interfaces so same-network peers connect directly.
The challenge models a presence registry: peers announce (refreshing a timestamp), and a prune step drops anyone whose last-seen is older than the timeout.
Run it. Two peers announce; one stops. After the timeout, prune() evicts the silent one.
Why isn't an mDNS announcement enough to keep a peer in the cluster?
Next: reaching peers that aren't on your LAN — the WebSocket relay.
Saved on this device. Sign in to sync your progress everywhere.