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
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user