BuildBot

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.

Presence registry with pruning (JS model)

Run it. Two peers announce; one stops. After the timeout, prune() evicts the silent one.

Loading editor…
Knowledge check

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.