resolver: store a name's CNAME once per nameserver (closes #220) #236

Merged
clawbot merged 1 commits from issue-220-cname-stored-once into next 2026-10-02 09:09:52 +02:00
Collaborator

Closes #220

What changed

  • collectAnswerRecords adds each value once per record type. For a name with a CNAME, a nameserver answers the query for each of the eight record types with that CNAME, and every copy used to be stored: git.eeqj.de showed CNAME: fsn1app1.datavi.be. eight times at each nameserver. It now shows it once.
  • State.Load keeps each record value once. A state file saved before this fix holds the repeated values; cleaning them when the file is loaded means the first check after upgrading compares single values with single values and sends no Record Change or Inconsistency notification for them. The dashboard and /api/v1/status show single values from startup, before that check.

Not visible in the diff

  • Load also sorts each list of values before removing repeats. Checks already save them sorted, so nothing else changes.
  • The load tests hold, beside the repeated CNAME, two different addresses each repeated and out of order, so a load that kept only one value per list does not pass them.
  • Tests use answers and state files built in the test; there is no new live DNS test.

Disclosures

  • Judgement call: values are made unique when the state file is loaded, not ignored when records are compared, so the stored state is clean wherever it is read (dashboard, API, the Old: line of a Record Change), and older state files stay handled in state.go, as they already are.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/dnswatcher/issues/220 **What changed** - `collectAnswerRecords` adds each value once per record type. For a name with a CNAME, a nameserver answers the query for each of the eight record types with that CNAME, and every copy used to be stored: `git.eeqj.de` showed `CNAME: fsn1app1.datavi.be.` eight times at each nameserver. It now shows it once. - `State.Load` keeps each record value once. A state file saved before this fix holds the repeated values; cleaning them when the file is loaded means the first check after upgrading compares single values with single values and sends no Record Change or Inconsistency notification for them. The dashboard and `/api/v1/status` show single values from startup, before that check. **Not visible in the diff** - Load also sorts each list of values before removing repeats. Checks already save them sorted, so nothing else changes. - The load tests hold, beside the repeated CNAME, two different addresses each repeated and out of order, so a load that kept only one value per list does not pass them. - Tests use answers and state files built in the test; there is no new live DNS test. **Disclosures** - Judgement call: values are made unique when the state file is loaded, not ignored when records are compared, so the stored state is clean wherever it is read (dashboard, API, the `Old:` line of a Record Change), and older state files stay handled in `state.go`, as they already are. Model: opus-5-5
clawbot added the needs-review label 2026-10-02 08:04:30 +02:00
clawbot self-assigned this 2026-10-02 08:04:30 +02:00
Author
Collaborator

Review failed. Findings:

  1. The branch does not rebase cleanly onto current next. internal/state/state_test.go conflicts: the CNAME address tests for #203 were added where TestLoadStateWithRepeatedValues goes. TODO.md conflicts too. Acceptable: the branch rebased onto next, keeping both sets of tests and both Completed Steps entries.

  2. Once rebased, make lint fails. goconst counts the string "CNAME" three times in the internal/watcher tests: twice in TestFirstCheckAfterRepeatedValuesLoaded (inconsistency_test.go) and once in cname_test.go, which is already on next. Acceptable: make lint is clean on the rebased branch, for example by putting the record type name in one test constant.

  3. The new load tests cannot tell keeping each value once from keeping only the first value. The state files in TestLoadStateWithRepeatedValues (internal/state/state_test.go) and TestFirstCheckAfterRepeatedValuesLoaded hold one distinct value per list. A State.Load that cut every list down to its first value would pass both. On upgrade it would drop a hostname's second A record and report that as a Record Change. Acceptable: a loaded list holding two different values, repeated and out of order, and a check that both load, once each.

Model: opus-5-5

Review failed. Findings: 1. The branch does not rebase cleanly onto current `next`. `internal/state/state_test.go` conflicts: the CNAME address tests for https://git.eeqj.de/sneak/dnswatcher/issues/203 were added where `TestLoadStateWithRepeatedValues` goes. `TODO.md` conflicts too. Acceptable: the branch rebased onto `next`, keeping both sets of tests and both Completed Steps entries. 2. Once rebased, `make lint` fails. `goconst` counts the string `"CNAME"` three times in the `internal/watcher` tests: twice in `TestFirstCheckAfterRepeatedValuesLoaded` (`inconsistency_test.go`) and once in `cname_test.go`, which is already on `next`. Acceptable: `make lint` is clean on the rebased branch, for example by putting the record type name in one test constant. 3. The new load tests cannot tell keeping each value once from keeping only the first value. The state files in `TestLoadStateWithRepeatedValues` (`internal/state/state_test.go`) and `TestFirstCheckAfterRepeatedValuesLoaded` hold one distinct value per list. A `State.Load` that cut every list down to its first value would pass both. On upgrade it would drop a hostname's second A record and report that as a Record Change. Acceptable: a loaded list holding two different values, repeated and out of order, and a check that both load, once each. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-02 08:46:29 +02:00
clawbot force-pushed issue-220-cname-stored-once from c16b3f300b to a5ae1675b7 2026-10-02 08:53:30 +02:00 Compare
Author
Collaborator

Rework for #236 (comment):

  1. Rebased onto next, keeping both sets of tests in internal/state/state_test.go and both Completed Steps entries in TODO.md.
  2. TestFirstCheckAfterRepeatedValuesLoaded puts the record type name CNAME in one test constant, as the review suggested.
  3. Both load tests now load two different addresses, each repeated and out of order, and check that both load, once each.

Model: opus-5-5

Rework for https://git.eeqj.de/sneak/dnswatcher/pulls/236#issuecomment-112262: 1. Rebased onto `next`, keeping both sets of tests in `internal/state/state_test.go` and both Completed Steps entries in `TODO.md`. 2. `TestFirstCheckAfterRepeatedValuesLoaded` puts the record type name `CNAME` in one test constant, as the review suggested. 3. Both load tests now load two different addresses, each repeated and out of order, and check that both load, once each. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-02 08:53:39 +02:00
Author
Collaborator

Review passed on a5ae167.

Model: opus-5-5

Review passed on a5ae167. Model: opus-5-5
clawbot added 1 commit 2026-10-02 09:09:40 +02:00
For a name with a CNAME, a nameserver answers a query of any type with
that CNAME, and the records of every answer were added, so the CNAME
was stored once for each of the eight record types asked for.
collectAnswerRecords now adds each value once per record type.

A state file saved before this holds the repeated values. Load keeps
each record value once, so the first check after upgrading sees no
record change and notifies nothing for them.

Model: opus-5-5
clawbot force-pushed issue-220-cname-stored-once from a5ae1675b7 to d60720816b 2026-10-02 09:09:40 +02:00 Compare
clawbot merged commit c07976a73a into next 2026-10-02 09:09:52 +02:00
clawbot deleted branch issue-220-cname-stored-once 2026-10-02 09:09:52 +02:00
clawbot removed the needs-review label 2026-10-02 09:09:53 +02:00
Sign in to join this conversation.