Specification §7

Internet extension and the broker.

The broker carries the inter-site data path. It does not get out of the way. The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be interpreted as described in RFC 2119.

FrogNet Specification — Draft 0.9, revision 2026-08-29. Cite a conformance claim against this revision, not against a section number alone.

1. What the broker is

Croakus: §19, §21, §22, §22b

Sites that cannot see each other on a LAN are joined by tunnels. The broker is the rendezvous that arranges them, and it carries the inter-site data path: every cross-site packet transits the tunnels it terminates.

The broker terminates two tunnels and forwards between them. Each node builds its own tunnel to the broker; the broker is the peer at the far end of each. Traffic arriving from one side is decrypted at its tunnel interface, forwarded across the seam by kernel packet-filter rules, and re-encrypted into the other side's tunnel.

site A  ==tunnel A==>  [ broker ]  ==tunnel B==>  site B
                       decrypt A
                       forward in kernel   <-- plaintext exists here
                       encrypt B

credentials for tunnel A and tunnel B are separate.
neither site holds the other's.  the broker holds both.

An implementation MUST NOT describe the broker as a stateless introducer that gets out of the way, and MUST NOT claim it cannot read what it forwards. It can. What bounds the exposure is stated in §7.7 and §12.6, and it is not the tunnel.

The broker
Holds the tunnel credentials for each sideSeparately. A site's credentials are never shared with the site on the other side of the seam.
Holds no node identity and no pond secretNot a pond member, so it has neither a node GUID in the pond's sense nor the shared secret the SAME tag is keyed on (§12.2)
Runs none of the semantic stackNo codec, no templates, no references
Forwards in the kernelPacket-filter rules across the seam, not an application
Is not a member of any pondIt holds no tuples and takes no role
Sees inter-site traffic in plaintextBetween decryption on one interface and encryption on the other. Assume it is owned, and see §12.6 for what that yields.

The broker MUST NOT be confused with SotF's media relay (§1.3, §15), which is a different component solving a different problem.

2. Enrolment

A node registers with the broker under its GUID (§3.2.1) and its tunnel public key. The broker revives a returning node's row on a matching GUID and retires one only on explicit rotation, so a returning node reclaims what it was rather than accumulating ghosts.

Enrolment MUST NOT be a precondition of installation. A gateway configured at install may have no upstream, no name service, or an unreachable broker; the configuration is written, enrolment is left pending, and every merge retries it (§3.5.6, §4a.4.0). The retry MUST be sentinel-gated so it stops on its own, and MUST NOT be re-armed as a timer.

Broker calls carry a group token and MUST be bounded by a timeout. A broker call that can block indefinitely blocks the merge that made it.

3. The channel list is authoritative for existence

The broker tells a node which channels it should have. That list, and nothing else, decides whether a tunnel exists (§5.6):

QuestionAnswered by
Should this tunnel exist?The broker's channel list
Which route serves this destination?Observations (§5.4)

A channel the broker lists MUST stay up even where a non-tunnel observation beat it this merge. Only a channel that is up in the kernel and absent from the broker's list is an orphan, and only an orphan is torn down [BROKER_TEARDOWN_V1].

4. Teardown

This is the section's most expensive rule and it MUST be implemented as stated.

Evidence about this node's own control plane is not evidence about a peer. A failed connectivity check, a single uplink scan, or one unsuccessful broker fetch describes this node at this instant. None of them proves any peer became unreachable, and an implementation MUST NOT tear down established tunnels on any of them [TRANSIENT_GUARD_V1].

On 2026-06-05 a one-shot failure of one such check tore down three tunnels that had handshaken and carried data for three hours, cutting two remote sites until a later merge rebuilt them.

A recent handshake is positive, on-wire proof that a path works, and MUST protect a tunnel from control-plane blips:

PersistentKeepalive       25 s
rekey                   ~120 s
HANDSHAKE_LIVE_SEC       180 s   — a handshake newer than this means a
                                  live session; the tunnel is protected
                                  (env FROGNET_HANDSHAKE_LIVE_SEC)

The window is derived from the keepalive and rekey intervals, not chosen: it is the shortest span in which a live session is certain to have handshaken. An implementation that shortens it below the rekey interval will tear down working tunnels.

5. Transit advertisement

A gateway advertises transit for its downstream subtree (§3.3). The subnets it publishes are the winners it actually installed, read from its own committed state — not the subnets it hopes to serve. A node MUST advertise what it committed, and MUST NOT advertise a subnet it has not installed a route for.

Each node fetches the transit map from the broker on its poll and uses it to know which remote subnets are reachable through which channel. The map is broker state about the overlay; it is not a topology view (§2d) and MUST NOT be substituted for local observation when planning routes.

6. Address allocation

Each tunnel takes a carrier block from a reserved transit range. The allocation is per tunnel, tunnels in a full mesh grow as the square of the nodes, and the resulting node ceiling and its arithmetic are stated in §17.4. Two properties matter here:

The transit range holds no node identities and MUST NOT be walked as a discovery target (§4.2), and a discovered route MUST NOT be sourced from a transit block (§3.2.2, §5.7).

A broker serving more than one pond divides the band between them, so the single-pond ceiling does not hold on a shared broker (§17.4). An implementation MUST NOT assume it does.

7. Trust

The broker terminates both tunnels, so it sees the inter-site data path in plaintext at IP level: addresses, ports, timing, volumes, and the bytes themselves. It is inside the encryption boundary, not outside it, and an implementation MUST plan on that rather than on the tunnel.

What remains between an owned broker and the meaning of the traffic is the semantic layer, and only that. The wire carries verdicts against templates the broker does not hold, because the templates live in each node's local cache and were learned once from a FULL the broker may never have seen (§12.4). That bound is real and it is bounded: an observer present from the first exchange of a structure learns the template in the same act the endpoints do (§12.4.1). An owned broker is exactly such an observer if it is owned early enough.

What an owned broker cannot do is forge the semantic layer's own authentication. The SAME tag is keyed on a secret held by pond members, and the broker is not one (§12.2). It can read, drop, delay and inject at IP level; it cannot mint a token that a member will accept as proof that a response was asserted for a request.

An implementation MUST NOT place a node credential, a tuple, or a role on the broker in order to simplify rendezvous. Every such placement converts a transit point into a member, and a member is inside the one boundary the broker is currently outside.

An operator requiring confidentiality across the seam MUST supply it above the tunnel — a cipher on the payload, or an end-to-end bearer between the endpoints themselves — because the tunnel terminates at the broker by construction (§12.5).

8. Non-goals

The broker is not a controller: it distributes no topology and elects nothing (§2d, §8). It is not a directory of tuples. It is not required for a pond to function — a single-site pond needs no broker at all, and a pond that loses its broker keeps carrying traffic on established tunnels, suspending only new introductions (§13.2).

9. References

Specification §2d, §3.2, §4, §5.6, §8, §12 (Security), §13, §17.4. Source: internet_tunnels_v3/broker.py, poll.py, peer.py, wg.py, config.py. Build manual: Croakus §19, §21, §22, Appendix K (Known Limits).