Retry a WHOIS lookup that failed instead of storing it as complete (closes #105)
check / check (push) Canceled after 0s

A lookup whose RIR query failed, or whose RIR answer carried none of the
WHOIS fields (a refusal of service, for one), returned IANA's answer as
a success. The fetcher stored it as complete with blank fields, did not
look the AS up again for 30 days, and shortened its interval. Such a
lookup is now an error: the fetcher backs off and leaves the row as it
was. The fields are read from the RIR's answer alone. An AS IANA refers
to no RIR is stored with no WHOIS data, so it is not looked up again
until it is stale, counting as neither a success nor a failure. Tests
reach fake WHOIS servers through the client's DialContext.

Model: opus-5-5
This commit was merged in pull request #127.
This commit is contained in:
2026-10-20 00:02:34 +02:00
parent a173f4d159
commit abdc327c4c
4 changed files with 416 additions and 52 deletions
+17 -1
View File
@@ -264,7 +264,10 @@ func (f *ASNFetcher) fetchNextStale(ctx context.Context) {
}
// fetchAndUpdate performs a WHOIS lookup and updates the database.
// Returns true if successful.
// Returns true if successful. A failed lookup leaves the AS's row as it was,
// so the AS stays stale. An AS IANA refers to no RIR is stored with no
// WHOIS data, so it is not looked up again until it is stale; that counts
// as neither a success nor a failure.
func (f *ASNFetcher) fetchAndUpdate(ctx context.Context, asn int) bool {
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
@@ -272,6 +275,19 @@ func (f *ASNFetcher) fetchAndUpdate(ctx context.Context, asn int) bool {
f.logger.Info("Fetching WHOIS data", "asn", asn)
info, err := f.whoisClient.LookupASN(ctx, asn)
if errors.Is(err, whois.ErrNoReferral) {
f.logger.Info("IANA refers the AS to no RIR", "asn", asn)
err = f.db.UpdateASNWHOIS(ctx, &database.ASNWHOISUpdate{ASN: asn})
if err != nil {
f.logger.Error("Failed to update ASN WHOIS data",
"asn", asn, "error", err)
f.recordFailure()
}
return false
}
if err != nil {
f.logger.Error("WHOIS lookup failed", "asn", asn, "error", err)
f.recordFailure()