Keep a trailing AS set out of the origin and the peerings (closes #75)
check / check (push) Canceled after 0s

A path ending in an AS set, such as [64496, 64497, [64498, 64499]], was
flattened into the sequence, so the route was stored as originated by the
last set member and the peering handler recorded peerings the path does not
show. ASPath now keeps the sequence and a trailing set of several members
apart; Origin() gives the last AS of the sequence, or 0 (no known origin)
for such a set. The handlers use it; peerings come from the sequence only.
The pages show origin 0 as no known origin, and the IP lookup asks no WHOIS
lookup for it. Empty paths are unchanged.

Model: opus-5-5
This commit was merged in pull request #91.
This commit is contained in:
2026-10-19 12:50:05 +02:00
parent 8742f1b44d
commit 2712183f21
14 changed files with 395 additions and 60 deletions
+4 -3
View File
@@ -2141,11 +2141,12 @@ func (d *Database) GetIPInfoContext(
info.FirstSeen = prefixFirstSeen.Time
}
// Check if WHOIS data needs refresh (never fetched or older than 30 days)
// Check if WHOIS data needs refresh (never fetched or older than 30 days).
// A route with origin 0 has no known origin, so no AS to look up.
const staleThreshold = 30 * 24 * time.Hour
info.NeedsWHOISRefresh = !whoisUpdatedAt.Valid ||
time.Since(whoisUpdatedAt.Time) > staleThreshold
info.NeedsWHOISRefresh = info.ASN != 0 && (!whoisUpdatedAt.Valid ||
time.Since(whoisUpdatedAt.Time) > staleThreshold)
return info, nil
}
@@ -213,6 +213,33 @@ func TestGetIPInfoIgnoresShortRoutes(t *testing.T) {
lookup("2001:db8::1", "2001:db8::/32", 64502)
}
// TestGetIPInfoNeedsNoWHOISRefreshForOriginZero checks that the IP lookup asks
// for no WHOIS lookup when the address's route has origin 0, no known origin,
// and still asks for one when its origin AS has no WHOIS data.
func TestGetIPInfoNeedsNoWHOISRefreshForOriginZero(t *testing.T) {
t.Parallel()
db, err := New(&config.Config{StateDir: t.TempDir()}, logger.New())
if err != nil {
t.Fatalf("failed to create database: %v", err)
}
defer func() { _ = db.Close() }()
writeOriginRoutes(t, db, map[string]int{"10.0.0.0/8": 0, "11.0.0.0/8": 64500})
for ip, want := range map[string]bool{"10.0.0.1": false, "11.0.0.1": true} {
info, err := db.GetIPInfo(ip)
if err != nil {
t.Fatalf("GetIPInfo(%s): %v", ip, err)
}
if info.NeedsWHOISRefresh != want {
t.Errorf("GetIPInfo(%s) asks for a WHOIS lookup of AS%d: %t, want %t",
ip, info.ASN, info.NeedsWHOISRefresh, want)
}
}
}
// TestLiveRouteTablesHoldOneRoutePerPrefixAndPeer checks that each live route
// table refuses a second route from a peer for a prefix, even with another
// origin AS. An upsert updates the peer's route before it would insert one, so