Bound the IP lookup's address list and name lookups (closes #110) #134

Merged
clawbot merged 1 commits from issue-110-ip-lookup-bounds into next 2026-10-20 02:23:50 +02:00
Collaborator

Fixes #110.

What changed:

  • An IP lookup may list at most 10 addresses and host names, and have at most 10 addresses once the names are resolved (maxLookupTargets). Beyond either it answers 400 Too many addresses or host names before any database read; a list over the limit resolves no names.
  • Each PTR lookup gets its own 2 seconds (ptrLookupTimeout); one that runs out leaves the address's result without PTR names.
  • Of the addresses a host name resolves to, only public ones are kept. A name with none is reported as host name has no public address, without its addresses; when nothing else is left to look up, the 400 No valid IPs or hostnames provided gives that reason. Typed addresses are looked up as before.
  • DNS lookups go through a resolver field on the server (net.DefaultResolver outside tests), so tests can use a fake.
  • README "API v1" gives the limits.

Not shown by the diff: host name lookups still have no time limit of their own, only the request's.

Disclosures:

  • Deviation: Go's "global unicast" includes the private ranges, so the check is "global unicast and not private". Shared address space (100.64.0.0/10) still counts as public.
  • Judgement call: the handler's last step moved into writeIPLookupAnswer, and its 400 message into noTargetsMessage, to keep the handler within the linter's 80-line limit.
  • Judgement call: the limit test sends 11 addresses and 11 host names in place of the issue's 50, and checks that 10 are still accepted.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/routewatch/issues/110. What changed: - An IP lookup may list at most 10 addresses and host names, and have at most 10 addresses once the names are resolved (`maxLookupTargets`). Beyond either it answers 400 `Too many addresses or host names` before any database read; a list over the limit resolves no names. - Each PTR lookup gets its own 2 seconds (`ptrLookupTimeout`); one that runs out leaves the address's result without PTR names. - Of the addresses a host name resolves to, only public ones are kept. A name with none is reported as `host name has no public address`, without its addresses; when nothing else is left to look up, the 400 `No valid IPs or hostnames provided` gives that reason. Typed addresses are looked up as before. - DNS lookups go through a `resolver` field on the server (`net.DefaultResolver` outside tests), so tests can use a fake. - README "API v1" gives the limits. Not shown by the diff: host name lookups still have no time limit of their own, only the request's. Disclosures: - Deviation: Go's "global unicast" includes the private ranges, so the check is "global unicast and not private". Shared address space (100.64.0.0/10) still counts as public. - Judgement call: the handler's last step moved into `writeIPLookupAnswer`, and its 400 message into `noTargetsMessage`, to keep the handler within the linter's 80-line limit. - Judgement call: the limit test sends 11 addresses and 11 host names in place of the issue's 50, and checks that 10 are still accepted. Model: opus-5-5
clawbot added the needs-review label 2026-10-20 02:02:46 +02:00
clawbot self-assigned this 2026-10-20 02:02:46 +02:00
Author
Collaborator
  1. internal/server/handlers_internal_test.go, TestIPLookupRefusesTooManyAddresses: nothing tests the limit on how many entries a list may have. The over-limit list in the test is 11 typed addresses, which the limit on addresses after resolution refuses by itself, so splitLookupTargets could accept any number of entries and every test would still pass. That limit is the only thing that stops a list of thousands of host names from being resolved one by one, the DNS half of #110. Acceptable: a case listing 11 host names that answers 400 with the resolver asked zero times (for example a fake resolver that counts its host name lookups).

  2. internal/server/handlers.go, handleIPInfo: a lookup of a single host name whose only address is private, the case the issue describes (the container's own host name), answers 400 No valid IPs or hostnames provided. The answer says the name is not valid instead of reporting it as having no public address, which the definition of done and the new README sentence ("a name with none ... is reported as host name has no public address") both require. TestIPLookupHidesPrivateAddresses checks only the 400. Acceptable: when nothing is left to look up, the 400 says why, for example No valid IPs or hostnames provided: internal.test: host name has no public address, and the test checks that message.

Model: opus-5-5

1. `internal/server/handlers_internal_test.go`, `TestIPLookupRefusesTooManyAddresses`: nothing tests the limit on how many entries a list may have. The over-limit list in the test is 11 typed addresses, which the limit on addresses after resolution refuses by itself, so `splitLookupTargets` could accept any number of entries and every test would still pass. That limit is the only thing that stops a list of thousands of host names from being resolved one by one, the DNS half of https://git.eeqj.de/sneak/routewatch/issues/110. Acceptable: a case listing 11 host names that answers 400 with the resolver asked zero times (for example a fake resolver that counts its host name lookups). 2. `internal/server/handlers.go`, `handleIPInfo`: a lookup of a single host name whose only address is private, the case the issue describes (the container's own host name), answers 400 `No valid IPs or hostnames provided`. The answer says the name is not valid instead of reporting it as having no public address, which the definition of done and the new README sentence ("a name with none ... is reported as `host name has no public address`") both require. `TestIPLookupHidesPrivateAddresses` checks only the 400. Acceptable: when nothing is left to look up, the 400 says why, for example `No valid IPs or hostnames provided: internal.test: host name has no public address`, and the test checks that message. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-20 02:10:05 +02:00
clawbot added 1 commit 2026-10-20 02:17:06 +02:00
An IP lookup took any number of addresses and host names, gave each PTR
lookup until the request's 30-second limit, and looked up and named
every address a host name resolved to. It now answers 400 for more than
10 entries, or more than 10 addresses once the names are resolved,
before reading the database. Each PTR lookup gets 2 seconds; one that
runs out leaves the address's result without PTR names. Of a host
name's addresses only public ones are kept: global unicast and not
private. A name with none is reported as having no public address. The
tests give the server a fake resolver.

Model: opus-5-5
clawbot force-pushed issue-110-ip-lookup-bounds from 490745ea41 to 10464cfe8b 2026-10-20 02:17:06 +02:00 Compare
Author
Collaborator
  1. TestIPLookupRefusesTooManyAddresses has a case listing 11 host names that answers 400 with the database read zero times and the fake resolver, which now counts its host name lookups, asked zero times; every case checks that count.
  2. When nothing is left to look up, the 400 now reads No valid IPs or hostnames provided followed by the first reason, so a lone internal.test answers No valid IPs or hostnames provided: internal.test: host name has no public address. TestIPLookupHidesPrivateAddresses checks that message.

Model: opus-5-5

1. `TestIPLookupRefusesTooManyAddresses` has a case listing 11 host names that answers 400 with the database read zero times and the fake resolver, which now counts its host name lookups, asked zero times; every case checks that count. 2. When nothing is left to look up, the 400 now reads `No valid IPs or hostnames provided` followed by the first reason, so a lone `internal.test` answers `No valid IPs or hostnames provided: internal.test: host name has no public address`. `TestIPLookupHidesPrivateAddresses` checks that message. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-20 02:17:35 +02:00
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit c7f2e5db1d into next 2026-10-20 02:23:50 +02:00
clawbot deleted branch issue-110-ip-lookup-bounds 2026-10-20 02:23:50 +02: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#134