Files
hq/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/01-diagnosis.md
T
jschoubben 75c104c355 Issue 112 diagnosis: correct located-in attribution
The carried-peer record (CarriedPeer/TunnelPeer) lives in mesh-controller
internal/inventory, not internal/catalogue. internal/catalogue is the
right package for the zone-generation side of the fix (facts.go's
nodeZones), but a different concern from where the name field itself
would go. Split the two so a decision record doesn't get pointed at the
wrong package.
2026-09-24 13:54:20 +02:00

79 lines
4.4 KiB
Markdown

# Diagnosis
## 2026-09-24 — where the mesh's own record ends, and what stands beside it
Checked the mechanism first. The resolver module's config (`mesh-catalog modules/dnsmasq`) is
generated whole from `nodes.conf`, the `dnsmasq.fact-node-zones` fact `mesh-controller` computes:
one `address=/<node>.<suffix>/<address>` wildcard per node the mesh has a name for, plus
`local=/<suffix>/` — which tells dnsmasq it is *authoritative* for the whole suffix, so anything
under it that is not one of those wildcards is refused, not forwarded. That is the exact mechanism
the report describes: **the mesh does not lack an upstream to ask, it has told itself there is
nothing to ask.**
Checked whether "forward to the resolver it replaced" (the third open question, ADR 0104's shape)
is literal here the way it was for the proxy. It is not, and the difference matters: the proxy's
predecessor kept running throughout its migration, a separate process on ports the mesh's proxy did
not yet hold. DNS has one process on one port. `mesh-catalog`'s dnsmasq module, on assignment,
replaces `/etc/dnsmasq.conf` whole and restarts the one `dnsmasq.service` unit — the same unit the
predecessor's own resolver is running as, right now, on this control-node:
```
$ systemctl status dnsmasq
● dnsmasq.service ... Active: active (running) since Fri 2026-09-18 ...
```
There is no predecessor process left standing after that assignment for a forward rule to reach.
An adapter in ADR 0104's literal shape — a second thing running, written into by a first — does not
fit; whatever answers this has to be data carried across the cutover, not a live thing forwarded to
across it.
## What is actually missing, and where it already exists
The report's first open question — *should a carried peer be nameable, the operator saying which
machine a carried address is, before it enrols* — turns out not to need a guess. The predecessor's
own resolver config, still live on this control-node, already states it:
```
# /etc/dnsmasq.d/hal-dns.conf — Generated by HAL dnsmasq-app
address=/novox.internal/10.10.0.1
address=/ace.internal/10.10.0.2
address=/g14.internal/10.10.0.4
address=/shanks.internal/10.10.0.3
```
Checked against what the mesh itself recorded when it took the tunnel over (`overlay show`):
```
a peer of the tunnel (zTKYP6Sz…) 10.10.0.2 not yet enrolled
a peer of the tunnel (XT1l25Z0…) 10.10.0.3 not yet enrolled
a peer of the tunnel (mq76YPW0…) 10.10.0.4 not yet enrolled
```
`10.10.0.2`/`.3`/`.4` match `ace`/`shanks`/`g14` exactly, one for one. This is not the operator
inventing a fact under time pressure — it is the predecessor's own record, current, and it has been
correctly serving these three names for six days without correction. Recording it is transcription,
not assertion.
**located-in, tentatively:** `mesh-controller internal/inventory` (where a carried peer's record
lives today — `CarriedPeer`/`TunnelPeer` in `tunnel.go` carry a public key and an address but no
name field) and `cmd/mesh-controller` (a command to set it — nothing today lets an operator attach
a name to a carried-tunnel-peer record; `node add` is for enrolling nodes, not naming peers, and
`node public-domain <name> <d>` is the closest existing shape to model a new verb on). Separately,
`mesh-controller internal/catalogue` (`facts.go`'s `nodeZones`) would then need to emit an
`address=` wildcard for a *named carried peer* the same way it does for a node — it renders only
from the mesh's `addresses` map today, keyed by node name, and does not distinguish a named carried
peer from an unnamed one. `mesh-catalog modules/dnsmasq` itself needs no change: it already
restarts on the `node-zones` fact and would pick up the new wildcard the moment `internal/catalogue`
emits it.
## What is still open
- The mechanism for *recording* the name is not designed — a new field on the carried-peer record,
a new CLI verb, and what happens if the name later disagrees with what the peer states on
enrolling (it should win; nothing says so yet).
- Whether this generalises: the predecessor's static hosts file was the answer *here* because it
happened to be readable and correct. A migration without one still has the report's harder second
option (refuse the resolver until every peer enrols) as its fallback.
- Not implemented. This diagnosis is what the fix would touch and why the ADR 0104 framing in the
report's third option does not transfer directly — not the fix itself.