Specification §7

Internet extension and the broker.

The broker carries the inter-site data path. It does not get out of the way. Key words are as defined in §1.2 [RFC2119] [RFC8174].

Author commentary

The author walking through this material on camera. It is commentary, not specification: where the video and this document disagree, this document governs (§18.8). The full series is at watch.

The broker joins two independent FrogNets

Current implementation clauses: October 12, 2026

RAM manager

The member opens an outbound session to the region manager. The manager holds current participants and mappings. It is an authority for that region’s membership state.

Hub

fdf-hub forwards ordinary packet traffic over WireGuard legs and derives its current peers and allowed prefixes from the graph and verified mappings. It is a relay, with a plaintext forwarding seam between tunnel legs.

Application service

The Communicator’s RAM and media hosts are separate application services advertised by identity. They are not automatically the membership manager or hub.

Broker cleanup

The broker-era runtime and installer dependencies remain in the reviewed tree. The October 12 plan removes them after key-generation and packaging corrections. That plan is not reported as an implemented cleanup.

Related current material.

FD&F · Programming · Memory contract · Evidence · Source baseline

The detailed clauses, rationale, source citations and author commentary below remain the mechanism reference. Where the added region or modern Ribbit contract differs, use the implementation-specific scope stated above; the local and broker paths remain separately identified.

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

Architecture-model note. The broker’s position in the packet path does not make it an application server, a topology authority, a Memory authority, or a control plane. It solves reachability between regions that cannot directly reach one another. Moving application coordination onto the broker would create exactly the central dependency the rest of FrogNet is designed not to require.

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 identity of its own, 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). It does store identities. A registration row per node, keyed on the node's GUID and unique on (pond, name) (§3.2), so an owned broker yields the roster of every node registered with it. Rotation MUST retire the old GUID there before a new one is written
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 plaintext, and holds no context to interpret itBetween decryption on one interface and encryption on the other. It decodes the tunnel, re-encodes it, and passes the frames through: it runs none of the semantic stack and holds no templates, no learned structure and no cache, so a frame is a difference against state it does not have. Capture and interpretation are separate problems. Assume it is owned, and see §12.6 for what each 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.

4a. A stale handshake is refreshed before it is torn down

§7.4 says a fresh handshake protects a tunnel. A stale one does not condemn it. [STALE_HANDSHAKE_PURGE_V2]

A channel recorded as up carries only the claim that the interface was created and handshook at some point. The peer may since have rotated keys, restarted, changed endpoint or gone offline; in each case the interface is still up locally with stale crypto and every probe through it times out. An implementation MUST establish that a channel is presently working before treating it as already up.

The refresh MUST be attempted in place first. Toggling the keepalive forces the kernel to initiate a new handshake on the existing interface: no interface goes down and no routes are removed. Only where that fails to produce a fresh handshake within the refresh wait may the destructive teardown be used.

An implementation MUST NOT unconditionally tear down a stale interface. Bringing one down drops every route on that device in a single syscall. On a forwarder carrying several per-peer scope-link routes per interface, doing so at the start of each merge emptied the routing table mid-merge and blanked monitoring until the commit stage ran at the end. The destructive path is the fallback, not the mechanism.

Each channel touched MUST be recorded with its reason — refreshed in place, purged, or skipped as unhealthy where no interface exists — and all three MUST appear in the run’s summary, so an operator can see which tunnels were touched and why rather than inferring it from a route diff.

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).

← §6 Pond Formation Index §8 Service Discovery and Election →