From b740ce932166ffdc027db54cd7a0390aec250671 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 9 Oct 2026 14:14:19 +0200 Subject: [PATCH] Connectivity: walk the five contexts through the network layers, so a reader can see which layer each one acts at and read a failure from the bottom up --- 03-DESIGN/01-to-be/08-connectivity.md | 111 +++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/03-DESIGN/01-to-be/08-connectivity.md b/03-DESIGN/01-to-be/08-connectivity.md index a3fe273e..286bdb25 100644 --- a/03-DESIGN/01-to-be/08-connectivity.md +++ b/03-DESIGN/01-to-be/08-connectivity.md @@ -22,8 +22,10 @@ code: - mesh-host internal/apply (the service that reflects a rule set; a whole file handed to its new owner) - mesh-controller cmd/mesh-controller/nodes.go (a token issued for a machine's tunnel key, ADR 0169) - mesh-host cmd/mesh-host/join_tunnel.go (a machine joins through the tunnel, ADR 0169) -updated: 2026-10-08 +updated: 2026-10-09 decisions: + - 02-DECISIONS/0241-a-machine-says-how-its-network-is-and-an-outside-writer-of-a-mesh-file-is-a-finding.md + - 02-DECISIONS/0117-a-machines-uplink-is-a-seat.md - 02-DECISIONS/0247-a-machine-with-a-vpn-client-routes-names-by-domain-through-a-resolver-of-its-own.md - 02-DECISIONS/0226-the-private-network-is-assigned-by-its-own-name-and-the-proxy-names-its-public-issuer.md - 02-DECISIONS/0223-the-mesh-has-two-resolvers-and-a-machine-lists-only-them.md @@ -1105,6 +1107,113 @@ against today's behaviour, where both are always composed; an unrouted endpoint named; an assignment naming an endpoint the module does not declare refused where it is said; and a silent assignment rendering byte-identically to today. +## The five through the network layers + +*2026-10-09. A reading aid: it decides nothing and states no rule. Each claim names the section or the +record that decided it.* + +The OSI model is the standard seven-layer picture of a network: every layer wraps what the layer above +hands it, and the receiving side unwraps in reverse. The five contexts of this document act at +different layers, and seeing which explains why they fail independently. A resolver that stopped +answering leaves the private network working, and a tunnel that cannot handshake leaves every name +resolving to an address nothing can reach. + +| Layer | What it carries | Where the mesh acts there | +|---|---|---| +| 7 Application | the message itself | the bus ([ADR 0106](../../02-DECISIONS/0106-the-bus-is-nats.md)); resolution (§2); exposure, where the proxy chooses a route by the name a request asks for (§3) | +| 6 Presentation | how what is said is encoded and encrypted | certificates (§5): TLS, which is usually drawn between 4 and 7 and placed here by the book | +| 5 Session | a conversation kept open | a node's link to the bus, opened once and reopened after the machine sleeps | +| 4 Transport | ports, TCP and UDP | filtering (§4), which opens a port to a source; the private network itself travels as UDP | +| 3 Network | addresses and the path between them | the private network (§1): every node's address, the peer graph, the hub relaying | +| 2 Data link | frames on one network segment | the machine's own uplink ([ADR 0117](../../02-DECISIONS/0117-a-machines-uplink-is-a-seat.md)), on the underlay | +| 1 Physical | cable, fibre, radio | nothing of the mesh's | + +### Two networks, one inside the other + +**The private network is a layer 3 network carried at layer 4 of the underlay.** A packet for another +node's private address is encrypted whole and becomes the payload of a UDP datagram addressed to a +peer's underlay address. Every hop on the underlay reads only the outer envelope, up to its layer 3, +and never sees inside. + +``` + underlay │ L1 radio │ L2 frame │ L3 to the hub's public address │ L4 UDP │ ▓▓ encrypted ▓▓ │ + │ + decrypted at the hub │ + ┌────────────────────────────────────────────────┘ + ▼ + private network │ L3 to a private address │ L4 TCP │ L5–L7 a message on the bus │ +``` + +### The shape the layers are drawn on + +The shape is §1's: a hub, direct peering between nodes at the same site, and a roaming node that goes +through the hub only. In a small mesh one node is both the anchor and the hub, and holds the bus. + +``` + ┌──────────────────────────────────────────┐ + │ hub and anchor — reachable from outside │ + │ holds the bus │ + └─────▲──────────────────▲─────────────▲───┘ + │ │ │ + │ each tunnel is dialled out by the node below it + │ │ │ + ┌─────┴─────┐ ┌──────┴──────┐ ┌────┴────────┐ + │ laptop │ │ home-server │ │ home-server │ + │ no site: │ └──────▲──────┘ └──────▲──────┘ + │ hub only │ └──── direct ───┘ + └───────────┘ same site, peered +``` + +**Every arrow points at the hub.** A node with no public address still has a tunnel, because it dials +out and the hub answers; only the hub's tunnel must be dialable, at a stable address +([ADR 0169](../../02-DECISIONS/0169-a-machine-joins-through-the-tunnel-and-the-bus-is-never-public.md)). + +### One tool call, from the laptop to a home-server + +The laptop wraps the call one layer at a time: + +| Layer | On the laptop | +|---|---| +| 7 | a message on the bus naming the tool and its arguments | +| 6 | the message encoded for the wire | +| 5 | the laptop's link to the bus, already open | +| 4 | TCP to the bus at its private address | +| 3 | a packet from the laptop's private address to the bus's | +| 3 inside 4 | the tunnel: that packet encrypted, in a UDP datagram to the hub's public address | +| 2 | a frame to the gateway of whatever network the laptop is on | +| 1 | radio | + +**At the hub the outer envelope comes off** — frame, packet, datagram — and the tunnel decrypts what was +inside. The inner packet is addressed to the bus, which is on this node, so the hub keeps unwrapping up +to layer 7. The bus finds the home-server's subscription and sends the message down the home-server's +own link, which that node opened earlier through its own tunnel. Neither spoke ever accepted a +connection; both dialled the hub. + +**How far the hub unwraps depends on what the packet is for.** A packet addressed to a home-server's +private address, not to the bus, is opened only to layer 3: the hub relays it, encrypted again for the +home-server's tunnel. That is the whole of the glossary's *a hub relays for nodes that cannot reach +each other directly*. Two home-servers at one site skip the hub: their tunnel crosses the home network +at layer 2, and nothing of theirs reaches the hub at all. + +**Why a roaming node has one path is a layer 3 fact.** A more specific route to an endpoint that is +gone takes the packets and drops them; it does not fall back (§1). A laptop that moves between networks +therefore has exactly one route, the hub's. + +### Reading a failure by layer + +The machine's own network checks +([ADR 0241](../../02-DECISIONS/0241-a-machine-says-how-its-network-is-and-an-outside-writer-of-a-mesh-file-is-a-finding.md)) +each look at one layer: + +| Check | Layer | Failing alone means | +|---|---|---| +| **route** — a default route | 3, underlay | the machine has no way out; nothing above can work | +| **tunnel** — a handshake with the hub within five minutes | 3 carried at 4 | the underlay works and the private network does not: a key, the hub's address, or a filter on the way | +| **bus** — the link is open | 5 to 7 | the private network works and the bus, or the node's account on it, does not | +| **resolv-conf** and **names** | 7 | addresses work and names do not, as when a VPN client rewrites the machine's resolver file | + +Read them from the bottom. A layer that fails explains every failure above it, and never one below it. + ## What this removes The list is worth having in one place, because it is most of the argument: