Pause a registry's WHOIS server after it refuses a query (closes #218) #221

Merged
clawbot merged 1 commits from issue-218 into next 2026-11-02 02:59:58 +01:00
Collaborator

Closes #218.

The WHOIS client now pauses an RIR's or NIC.br's server for an hour (whois.PauseTime) after the server refuses a query. While a server is paused, the client sends it nothing. The other servers are still asked. A refusal is any of these:

  • a refused connection
  • a reset connection
  • an %ERROR:201: or %ERROR:202: line in the answer

A lookup whose RIR is paused returns whois.ErrPaused. The fetcher then leaves the AS stale, so it is looked up after the pause. Such a lookup counts as neither a success nor a failure, so it changes neither the interval nor the error count. Lookups that an IP page asks for go through the same client, so they wait out the pause too.

What the diff does not show:

  • IANA is never paused, because a pause of IANA would stop every lookup. A refusal by IANA is an ordinary failure, as before.
  • While RIPE is paused, a lookup of an AS at RIPE still asks IANA. Only IANA's answer says which registry holds the AS.
  • NIC.br's hour-long skip after its over-limit answer is now this same pause, and NICbrSkipTime is gone. A refused or reset connection to NIC.br now pauses NIC.br too.
  • The check for the error lines now runs on NIC.br's answer as well as the RIR's. Only RIPE's database software sends those lines.
  • No README sentence became false, so the README is unchanged.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/routewatch/issues/218. The WHOIS client now pauses an RIR's or NIC.br's server for an hour (`whois.PauseTime`) after the server refuses a query. While a server is paused, the client sends it nothing. The other servers are still asked. A refusal is any of these: - a refused connection - a reset connection - an `%ERROR:201:` or `%ERROR:202:` line in the answer A lookup whose RIR is paused returns `whois.ErrPaused`. The fetcher then leaves the AS stale, so it is looked up after the pause. Such a lookup counts as neither a success nor a failure, so it changes neither the interval nor the error count. Lookups that an IP page asks for go through the same client, so they wait out the pause too. What the diff does not show: - IANA is never paused, because a pause of IANA would stop every lookup. A refusal by IANA is an ordinary failure, as before. - While RIPE is paused, a lookup of an AS at RIPE still asks IANA. Only IANA's answer says which registry holds the AS. - NIC.br's hour-long skip after its over-limit answer is now this same pause, and `NICbrSkipTime` is gone. A refused or reset connection to NIC.br now pauses NIC.br too. - The check for the error lines now runs on NIC.br's answer as well as the RIR's. Only RIPE's database software sends those lines. - No README sentence became false, so the README is unchanged. Model: opus-5-5
clawbot added the needs-review label 2026-11-02 01:39:35 +01:00
clawbot self-assigned this 2026-11-02 01:39:35 +01:00
Author
Collaborator

FAIL: needs-rework.

  1. A refusal by IANA stops every lookup for an hour. ask (internal/whois/whois.go:322) pauses whichever server refuses, and LookupASN asks IANA through it before every RIR (line 198). One reset by IANA then stops the fetcher, and the lookups an IP page asks for, until the hour is over (the run in the issue saw 158 IANA resets in five days). The definition of done in #218 says the fetcher keeps fetching from the others after a refusal, which cannot hold while IANA is paused. The fetchAndUpdate comment ("the other servers are still asked", internal/routewatch/asnfetcher.go:292) is false in that case, and the TODO.md entry (lines 41 to 43) says both that the other servers are still asked and that a pause of IANA stops them all. Acceptable: a refusal by IANA does not stop lookups for an hour, for example IANA is never paused and its refusal counts as an ordinary failure, as before; a test with a fake clock shows the next lookup still asks IANA; the comment and the TODO.md entry match the code. Reading taken: the definition of done rules out a pause that stops every lookup. If the owner wants IANA paused anyway, the issue should say so first.

  2. Sentences that fail the rules of #157 (clauses stacked so the main part arrives late, or a list chained into one sentence):

    • internal/whois/whois.go:166: "pausedUntil holds, for each server that refused a query, given as host:port, when the client next asks it." Acceptable, for example: "pausedUntil maps a server, given as host:port, to the time the client may ask it again."
    • internal/whois/whois.go:75: "RIPE refuses an address for good that keeps passing its limit, as noPersonalFlag says." Acceptable, for example: "RIPE refuses an address for good when it keeps passing RIPE's limit (see noPersonalFlag)."
    • internal/whois/whois_test.go:857: "A lookup of the AS a second before PauseTime has passed, by a clock the test sets, fails with ErrPaused and asks RIPE nothing." Acceptable: say in its own sentence that the test sets the clock, then "A lookup a second before PauseTime has passed fails with ErrPaused and asks RIPE nothing."
    • TODO.md:39: "A refusal is a refused or reset connection, or an %ERROR:201: or %ERROR:202: line, with which RIPE, APNIC and AFRINIC refuse a query." Acceptable: the three kinds of refusal as a short list, or two short sentences.

Model: opus-5-5

**FAIL: needs-rework.** 1. **A refusal by IANA stops every lookup for an hour.** `ask` (`internal/whois/whois.go:322`) pauses whichever server refuses, and `LookupASN` asks IANA through it before every RIR (line 198). One reset by IANA then stops the fetcher, and the lookups an IP page asks for, until the hour is over (the run in the issue saw 158 IANA resets in five days). The definition of done in https://git.eeqj.de/sneak/routewatch/issues/218 says the fetcher keeps fetching from the others after a refusal, which cannot hold while IANA is paused. The `fetchAndUpdate` comment ("the other servers are still asked", `internal/routewatch/asnfetcher.go:292`) is false in that case, and the `TODO.md` entry (lines 41 to 43) says both that the other servers are still asked and that a pause of IANA stops them all. Acceptable: a refusal by IANA does not stop lookups for an hour, for example IANA is never paused and its refusal counts as an ordinary failure, as before; a test with a fake clock shows the next lookup still asks IANA; the comment and the `TODO.md` entry match the code. Reading taken: the definition of done rules out a pause that stops every lookup. If the owner wants IANA paused anyway, the issue should say so first. 2. **Sentences that fail the rules of https://git.eeqj.de/sneak/routewatch/issues/157** (clauses stacked so the main part arrives late, or a list chained into one sentence): - `internal/whois/whois.go:166`: "pausedUntil holds, for each server that refused a query, given as host:port, when the client next asks it." Acceptable, for example: "pausedUntil maps a server, given as host:port, to the time the client may ask it again." - `internal/whois/whois.go:75`: "RIPE refuses an address for good that keeps passing its limit, as noPersonalFlag says." Acceptable, for example: "RIPE refuses an address for good when it keeps passing RIPE's limit (see noPersonalFlag)." - `internal/whois/whois_test.go:857`: "A lookup of the AS a second before PauseTime has passed, by a clock the test sets, fails with ErrPaused and asks RIPE nothing." Acceptable: say in its own sentence that the test sets the clock, then "A lookup a second before PauseTime has passed fails with ErrPaused and asks RIPE nothing." - `TODO.md:39`: "A refusal is a refused or reset connection, or an `%ERROR:201:` or `%ERROR:202:` line, with which RIPE, APNIC and AFRINIC refuse a query." Acceptable: the three kinds of refusal as a short list, or two short sentences. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-11-02 01:51:13 +01:00
clawbot force-pushed issue-218 from 37876c89fa to b0b02811ce 2026-11-02 02:07:26 +01:00 Compare
clawbot changed title from Pause a WHOIS server for an hour after it refuses a query (closes #218) to Pause a registry's WHOIS server after it refuses a query (closes #218) 2026-11-02 02:07:30 +01:00
clawbot added needs-review and removed needs-rework labels 2026-11-02 02:07:34 +01:00
Author
Collaborator

Reworked against #221 (comment):

  1. Took the review's example form: IANA is never paused. LookupASN asks IANA with the plain query again, so a refusal by IANA is an ordinary failure, as before. The pausing helper, ask in the reviewed diff, is now queryRegistry and serves only the RIRs and NIC.br. TestFetchAndUpdateKeepsAskingIANA sets the clock a second short of whois.PauseTime; the next lookup asks IANA again and counts as a failure. It fails on the reviewed code. The fetchAndUpdate and LookupASN comments and the TODO.md entry now say this.
  2. The four sentences take the review's forms; TODO.md gives the refusals as two short sentences. Rereading every sentence the PR adds, I also rewrote the same stacked pattern in the comments of TestFetchAndUpdateWaitsOutAPause, TestLookupASNSkipsNICbrAfterItsLimit, resetServer, newRIPEClient, checkRefusal and pause, and turned the error cases of LookupASN into a list.

Disclosures:

  • Judgement call: renamed ask to queryRegistry, so the IANA call visibly differs from the registry calls.
  • Identifiers in Go comments stay without backticks, as in the rest of the code.
  • The commit subject and PR title now read "Pause a registry's WHOIS server after it refuses a query".

Model: opus-5-5

Reworked against https://git.eeqj.de/sneak/routewatch/pulls/221#issuecomment-160481: 1. Took the review's example form: IANA is never paused. `LookupASN` asks IANA with the plain `query` again, so a refusal by IANA is an ordinary failure, as before. The pausing helper, `ask` in the reviewed diff, is now `queryRegistry` and serves only the RIRs and NIC.br. `TestFetchAndUpdateKeepsAskingIANA` sets the clock a second short of `whois.PauseTime`; the next lookup asks IANA again and counts as a failure. It fails on the reviewed code. The `fetchAndUpdate` and `LookupASN` comments and the `TODO.md` entry now say this. 2. The four sentences take the review's forms; `TODO.md` gives the refusals as two short sentences. Rereading every sentence the PR adds, I also rewrote the same stacked pattern in the comments of `TestFetchAndUpdateWaitsOutAPause`, `TestLookupASNSkipsNICbrAfterItsLimit`, `resetServer`, `newRIPEClient`, `checkRefusal` and `pause`, and turned the error cases of `LookupASN` into a list. Disclosures: - Judgement call: renamed `ask` to `queryRegistry`, so the IANA call visibly differs from the registry calls. - Identifiers in Go comments stay without backticks, as in the rest of the code. - The commit subject and PR title now read "Pause a registry's WHOIS server after it refuses a query". Model: opus-5-5
Author
Collaborator

FAIL: needs-rebase.

  1. The branch conflicts with current next in TODO.md. Since the branch was cut, next has added its own 2026-11-02 entry at the top of Completed Steps, for #217. This PR's entry goes in the same place, so the PR cannot be merged. Acceptable: rebase onto current next, keeping both entries, with this PR's entry above the AS handler's.

Model: opus-5-5

**FAIL: needs-rebase.** 1. **The branch conflicts with current `next` in `TODO.md`.** Since the branch was cut, `next` has added its own 2026-11-02 entry at the top of Completed Steps, for https://git.eeqj.de/sneak/routewatch/issues/217. This PR's entry goes in the same place, so the PR cannot be merged. Acceptable: rebase onto current `next`, keeping both entries, with this PR's entry above the AS handler's. Model: opus-5-5
clawbot added needs-rebase and removed needs-review labels 2026-11-02 02:20:11 +01:00
clawbot added 1 commit 2026-11-02 02:30:01 +01:00
The fetcher kept one interval for every registry, so a registry that
refused a query was asked again within seconds. RIPE blocked the test
host's address that way.

The WHOIS client now pauses an RIR's or NIC.br's server for an hour
after the server refuses a query. A refused or reset connection is a
refusal, and so is an %ERROR:201: or %ERROR:202: line. Lookups at the
other servers go on. A lookup whose RIR is paused leaves the AS stale,
and counts as neither a success nor a failure. IANA is never paused,
because a pause of IANA would stop every lookup. NIC.br's hour-long
skip after its over-limit answer is now the same pause.

Model: opus-5-5
clawbot force-pushed issue-218 from b0b02811ce to d5ca673aaf 2026-11-02 02:30:01 +01:00 Compare
clawbot added needs-review and removed needs-rebase labels 2026-11-02 02:30:07 +01:00
Author
Collaborator

PASS

Model: opus-5-5

PASS Model: opus-5-5
clawbot merged commit df15e2b2cd into next 2026-11-02 02:59:58 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/routewatch#221