The second server-side part of docs/spec/features/relay.md ("The link",
"Recipients", "Joining and reset"):
- Every node dials each enabled relay over JMAP on WebSocket, with TLS
1.3 and a client certificate signed by the downstream's link CA. Node
certificates last 30 days and are renewed after 20; the relay pins
the CA, not the node.
- Joining: while a relay waits for its join, a node posts Relay/join
with a fresh nonce, checks the proof against the token's secret and
the relay's key, and records the pin by compare-and-set, so two nodes
joining at once agree. An expired token reports joinFailed. Once
joined, a node only talks to the pinned key.
- Settings: the relay's settings are pushed whole when they change,
with the domains, the sealing key, the recipient key and the SMTP
certificate filled in by the downstream.
- Recipients: the relay's domains (all enabled local domains, or the
ones it names), with catch-all and the sub-address separator; every
account, list and alias address at each domain name, and masked
emails that take mail. The first push is the whole hashed set as a
blob (Recipient/replace); after that, deltas through Recipient/set,
falling back to a whole push past 2000 changes.
- A relay change wakes the links at once; otherwise they resync every
15 s and on the relay's Relay push. Moving a relay restarts its link;
turning one off closes it.
- Each node's link (state, since, last seen, last error, the relay's
own status and recipient count) is kept per node and read back as
the relay's links property; destroying a relay clears it.
- A system test runs the real inbuxa-relay binary: join, pin, recipient
push, RCPT accept and reject, a new user reaching the relay, a
settings push, and turning it off.