The live route tables (internal/database/schema.sql) are unique on prefix, origin AS and peer, and UpsertLiveRouteBatch and DeleteLiveRouteBatch (internal/database/database.go) match on all three. In BGP a peer has one route per prefix: a new announcement replaces the old one whatever its origin, and a withdrawal removes it.
HandleMessage in internal/routewatch/prefixhandler.go gives each withdrawal the origin AS of the message's path. A withdrawal-only message has no path, so its delete matches on prefix and peer and works. A message that announces some prefixes and withdraws others gives the withdrawals the origin of the announced path, and the delete matches nothing.
Failure scenarios, confirmed with a throwaway test:
docs/message-examples.json, recorded from the live feed, has peer 194.68.123.136 announcing 200.155.182.0/24 (origin AS11432) and withdrawing 41.220.80.0/20 and four other prefixes in one message. Those five routes stay in the table for good. Such messages are routine: two of that file's roughly 1,000.
A peer announces 198.51.100.0/24 with origin AS64500, then with origin AS64501. Two rows remain for that peer: the prefix pages list an origin the peer no longer announces, and the IP lookup, which takes the first matching row, can answer with the old one.
These rows are never removed.
Severity: critical
Definition of done
A test, failing before the fix, through PrefixHandler into a real database: a mixed message whose path ends in another AS removes the withdrawn route; a second announcement from the same peer with a new origin leaves one route, with the new origin.
The live route tables hold at most one route per prefix and peer; an announcement replaces it and a withdrawal deletes it by prefix and peer.
The in-memory route counts and prefix distribution stay exact (the existing counts tests pass).
make check passes.
Model: opus-5-5
The live route tables (`internal/database/schema.sql`) are unique on prefix, origin AS and peer, and `UpsertLiveRouteBatch` and `DeleteLiveRouteBatch` (`internal/database/database.go`) match on all three. In BGP a peer has one route per prefix: a new announcement replaces the old one whatever its origin, and a withdrawal removes it.
`HandleMessage` in `internal/routewatch/prefixhandler.go` gives each withdrawal the origin AS of the message's path. A withdrawal-only message has no path, so its delete matches on prefix and peer and works. A message that announces some prefixes and withdraws others gives the withdrawals the origin of the announced path, and the delete matches nothing.
Failure scenarios, confirmed with a throwaway test:
- `docs/message-examples.json`, recorded from the live feed, has peer `194.68.123.136` announcing `200.155.182.0/24` (origin AS11432) and withdrawing `41.220.80.0/20` and four other prefixes in one message. Those five routes stay in the table for good. Such messages are routine: two of that file's roughly 1,000.
- A peer announces `198.51.100.0/24` with origin AS64500, then with origin AS64501. Two rows remain for that peer: the prefix pages list an origin the peer no longer announces, and the IP lookup, which takes the first matching row, can answer with the old one.
These rows are never removed.
Severity: critical
## Definition of done
- A test, failing before the fix, through `PrefixHandler` into a real database: a mixed message whose path ends in another AS removes the withdrawn route; a second announcement from the same peer with a new origin leaves one route, with the new origin.
- The live route tables hold at most one route per prefix and peer; an announcement replaces it and a withdrawal deletes it by prefix and peer.
- The in-memory route counts and prefix distribution stay exact (the existing counts tests pass).
- `make check` passes.
Model: opus-5-5
clawbot
self-assigned this 2026-10-14 14:50:30 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The live route tables (
internal/database/schema.sql) are unique on prefix, origin AS and peer, andUpsertLiveRouteBatchandDeleteLiveRouteBatch(internal/database/database.go) match on all three. In BGP a peer has one route per prefix: a new announcement replaces the old one whatever its origin, and a withdrawal removes it.HandleMessageininternal/routewatch/prefixhandler.gogives each withdrawal the origin AS of the message's path. A withdrawal-only message has no path, so its delete matches on prefix and peer and works. A message that announces some prefixes and withdraws others gives the withdrawals the origin of the announced path, and the delete matches nothing.Failure scenarios, confirmed with a throwaway test:
docs/message-examples.json, recorded from the live feed, has peer194.68.123.136announcing200.155.182.0/24(origin AS11432) and withdrawing41.220.80.0/20and four other prefixes in one message. Those five routes stay in the table for good. Such messages are routine: two of that file's roughly 1,000.198.51.100.0/24with origin AS64500, then with origin AS64501. Two rows remain for that peer: the prefix pages list an origin the peer no longer announces, and the IP lookup, which takes the first matching row, can answer with the old one.These rows are never removed.
Severity: critical
Definition of done
PrefixHandlerinto a real database: a mixed message whose path ends in another AS removes the withdrawn route; a second announcement from the same peer with a new origin leaves one route, with the new origin.make checkpasses.Model: opus-5-5
Duplicate of #55, filed in error by a parallel review; closing.
Model: opus-5-5