From ce0287dd2d87b39f0a6deb5766e6bd4044dc8392 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 12 Nov 2026 18:06:41 +0100 Subject: [PATCH] Keep design 50 to what ADR 0678 asks, and hold the wait at 3 s per try A restart of resolved and a timed ask at the own resolver answered in 44-46 ms with the first mesh resolver silent, so no read catches the pass today: the value stays ADR 0678's until a read of resolved's server switches exists, and the proof is the Go build steps at the next silence. The phases table and the as-built notes go back to main: a to-be design states no live state. --- .../01-to-be/50-milestones/resolver-wait.md | 16 +++++------- ...plit-dns-on-a-machine-with-a-vpn-client.md | 25 +++++++++---------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/03-DESIGN/01-to-be/50-milestones/resolver-wait.md b/03-DESIGN/01-to-be/50-milestones/resolver-wait.md index 93c38736..1e85f68d 100644 --- a/03-DESIGN/01-to-be/50-milestones/resolver-wait.md +++ b/03-DESIGN/01-to-be/50-milestones/resolver-wait.md @@ -47,16 +47,12 @@ check passes against the other's main, whichever merges first. `timeout:1 attempts:2 edns0` it asserts today (ADR 0678, *How it is checked*). The reason: a test literal of another repository's template fails one repository's check on whichever merges first, the kind issue 1748's note of 2026-11-10 met. -4. **The pass is measured, and the value follows it.** After the delivery, on the workstation first and then the - laptop: `/node-reads.read` of `/etc/resolv.conf` shows the one server and §1's line. At the next time the - machine's first mesh resolver is silent (its machine unreachable, raised in `mesh-conditions.conditions`), the - worker of issue 1748 restarts resolved with `/node-service-manager.restart` and at once asks a mesh name with - `/netcheck.netcheck_dns`, `server` the machine's private address and `timeout_ms` 30000; the time it answers - in is the pass. The restart comes first because resolved keeps asking the server it passed to, so only the first - lookup after it starts meets the pass (the 42 ms answer read on 2026-11-12 with the first mesh resolver silent); - the machine has no names for the moment of the restart. A pass under 6 s leaves design 50 §2 as it is; a pass of - 6 s or more raises §2's timeout to the next whole second above the pass, the attempts staying two, and §1 is - delivered again. The measured time is written on issue 1748 as a note by its worker. +4. **The value stays 3 s per try until the pass can be read.** design 50 §2's `timeout:3 attempts:2` stays ADR + 0678's starting value until a read of resolved's own server switches exists. A restart of resolved and lookups + at the own resolver with its first mesh resolver silent answered in 44 to 46 ms (the lead's reading of + 2026-11-12 18:05 CET, issue 1748), so a restart and a timed ask do not catch the pass. After the delivery, on the + workstation first and then the laptop, `/node-reads.read` of `/etc/resolv.conf` shows the one server and + §1's line; the proof that the wait outlasts the pass is §5's. 5. **The live proof.** At the next silence of the first mesh resolver, `mesh-build-go.build_go_steps` lists no Go build step on a machine holding `node-resolver` failed with `i/o timeout` at that machine's own address. Issue 1748 is resolved once §4's read of the file holds, naming this line as where the proof will show, and reopened diff --git a/03-DESIGN/01-to-be/50-split-dns-on-a-machine-with-a-vpn-client.md b/03-DESIGN/01-to-be/50-split-dns-on-a-machine-with-a-vpn-client.md index f5317239..cdbd0f38 100644 --- a/03-DESIGN/01-to-be/50-split-dns-on-a-machine-with-a-vpn-client.md +++ b/03-DESIGN/01-to-be/50-split-dns-on-a-machine-with-a-vpn-client.md @@ -74,9 +74,8 @@ not share a machine. (ADR 0678 §1): `options timeout:3 attempts:2 edns0`, a total wait of 6 s, the timeout times the attempts, where ADR 0223's `timeout:1 attempts:2` gave about 2 s. Its program asks only the own resolver, so it waits on that pass; a file that lists the mesh's resolvers keeps `timeout:1 attempts:2`, because its programs try the second - after one second (ADR 0678 §2, design 08 §2). The value holds while the pass, measured on such a machine with its - first mesh resolver silent, is shorter than the total; a pass of 6 s or more raises the timeout by whole seconds, - in this line, the attempts staying two as design 08 §2 gives every file (milestone resolver-wait §4). + after one second (ADR 0678 §2, design 08 §2). The value stays ADR 0678's 3 s per try until a read of resolved's + own server switches exists, since no read today catches the pass (milestone resolver-wait §4). - **The uplink's holder steps back** from that path on that machine, by the controller's rule. It does not write the file and lose a race; it is never given the file to write. - **resolved** is given every mesh resolver as its global servers, with `~.` so they answer every name no @@ -146,22 +145,22 @@ resolver's hold, and is therefore raised. A VPN that tells resolved its link's D | the own resolver module's manifest test: its file names one server, the machine's private address, with §2's options | ADR 0247 §6, ADR 0678 §1 | | the node-engine's test that composes the catalog's own resolver on a machine reads the options from the catalog's template, not a literal, and its names check bounds each ask by the file's `timeout:` | ADR 0678 §1 | | the test over every uplink's resolver file: both mesh resolvers, `timeout:1 attempts:2` | ADR 0678 §2, design 08 §2 | -| live, on a machine holding `node-resolver` with its first mesh resolver silent: a timed lookup at the own resolver answers within the file's total wait; at the next silence no Go build step there fails on `i/o timeout` | ADR 0678 §1 | +| live, on a machine holding `node-resolver`: at the next silence of its first mesh resolver no Go build step there fails on `i/o timeout` (milestone resolver-wait §5); a timed lookup waits for a read of resolved's own server switches (§4) | ADR 0678 §1 | | each phase's *Done when* below | ADR 0247 | -## Milestones +## Phases -| Milestone | Repository | Delivers | Done when | State | -|---|---|---|---|---| -| A — the seat | mesh-controller | `node-resolver` and its verbs; the uplink stepping back | its tests pass; the controller is running on the mesh | running: the seat is held on the laptop and the workstation (read 2026-11-12, issue 1748); no as-is design yet | -| B — the resolver | mesh-catalog `systemd-resolved` | the module, its guard and verbs | its tests pass; assigned to every machine that runs the VPN client's module, each one's file names its own address, `routes` answers | running: each holder's file names its own address and `routes` answers (read 2026-11-12, issue 1748) | -| C — the adapter | mesh-catalog `forticlient` | `split-dns` required; the adapter | its tests pass; on the laptop, connected, a company name and a mesh name both resolve and no rewrite stays raised | running: the adapter's service runs beside the resolver on the workstation (issue 1748, 2026-11-10); its connected test is not recorded here | -| resolver-wait | mesh-catalog `systemd-resolved`, `mesh-host` | §2's options (ADR 0678), under issue 1748 | the live check above | designed; its part is [`50-milestones/resolver-wait.md`](50-milestones/resolver-wait.md) | +| Phase | Repository | Delivers | Done when | +|---|---|---|---| +| A — the seat | mesh-controller | `node-resolver` and its verbs; the uplink stepping back | its tests pass; the controller is running on the mesh | +| B — the resolver | mesh-catalog `systemd-resolved` | the module, its guard and verbs | its tests pass; assigned to every machine that runs the VPN client's module, each one's file names its own address, `routes` answers | +| C — the adapter | mesh-catalog `forticlient` | `split-dns` required; the adapter | its tests pass; on the laptop, connected, a company name and a mesh name both resolve and no rewrite stays raised | +| resolver-wait | mesh-catalog `systemd-resolved`, `mesh-host` | design 50 §2's options (ADR 0678), under issue 1748; its part is [`50-milestones/resolver-wait.md`](50-milestones/resolver-wait.md) | its tests pass; *How it is checked*'s live row holds | ## As built -One pull request in mesh-controller (phase A), and two in mesh-catalog (B, then C on top of it). What the -build chose where ADR 0247 left it open: +One pull request in mesh-controller (phase A), and two in mesh-catalog (B, then C on top of it). None is +merged. What the build chose where ADR 0247 left it open: - **The kept copy.** The mesh renders the module's file twice, at `/etc/resolv.conf` and beside resolved's configuration. The guard compares the live file with the copy and puts the copy back, so it needs nothing