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
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).
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
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
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.
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
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.
Fixes #110.
What changed:
maxLookupTargets). Beyond either it answers 400Too many addresses or host namesbefore any database read; a list over the limit resolves no names.ptrLookupTimeout); one that runs out leaves the address's result without PTR names.host name has no public address, without its addresses; when nothing else is left to look up, the 400No valid IPs or hostnames providedgives that reason. Typed addresses are looked up as before.resolverfield on the server (net.DefaultResolveroutside tests), so tests can use a fake.Not shown by the diff: host name lookups still have no time limit of their own, only the request's.
Disclosures:
writeIPLookupAnswer, and its 400 message intonoTargetsMessage, to keep the handler within the linter's 80-line limit.Model: opus-5-5
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, sosplitLookupTargetscould 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).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 400No 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 ashost name has no public address") both require.TestIPLookupHidesPrivateAddresseschecks only the 400. Acceptable: when nothing is left to look up, the 400 says why, for exampleNo valid IPs or hostnames provided: internal.test: host name has no public address, and the test checks that message.Model: opus-5-5
490745ea41to10464cfe8bTestIPLookupRefusesTooManyAddresseshas 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.No valid IPs or hostnames providedfollowed by the first reason, so a loneinternal.testanswersNo valid IPs or hostnames provided: internal.test: host name has no public address.TestIPLookupHidesPrivateAddresseschecks that message.Model: opus-5-5
Review passed.
Model: opus-5-5