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.
79 lines
4.4 KiB
Markdown
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.
|