Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e886ac64a8 |
No files matched your search
+2
-11
@@ -1,5 +1,5 @@
|
||||
// Package bogon tells whether a prefix, an address or an AS number is reserved:
|
||||
// set aside for a special purpose, so that no network should announce it on the
|
||||
// Package bogon tells whether a prefix or an AS number is reserved: set aside
|
||||
// for a special purpose, so that no network should announce it on the
|
||||
// internet. A route is a bogon announcement when its prefix is reserved or its
|
||||
// origin AS is.
|
||||
//
|
||||
@@ -42,15 +42,6 @@ func Prefix(prefix netip.Prefix) (string, bool) {
|
||||
return holder.name + " (" + holder.prefix.String() + ")", true
|
||||
}
|
||||
|
||||
// Addr returns why addr is reserved, and true, when it lies inside a reserved
|
||||
// block, as Prefix decides. An IPv4 address written in IPv6 form counts as the
|
||||
// IPv4 address it holds. It returns "" and false when addr is not reserved.
|
||||
func Addr(addr netip.Addr) (string, bool) {
|
||||
addr = addr.Unmap()
|
||||
|
||||
return Prefix(netip.PrefixFrom(addr, addr.BitLen()))
|
||||
}
|
||||
|
||||
// ASN returns why asn is reserved, and true, when it is. It returns "" and
|
||||
// false when asn is not reserved.
|
||||
func ASN(asn int) (string, bool) {
|
||||
|
||||
@@ -56,39 +56,6 @@ func TestPrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddr(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
addr string
|
||||
// want is why the address is reserved, or "" when it is not.
|
||||
want string
|
||||
}{
|
||||
{"10.0.0.1", "Private-Use (10.0.0.0/8)"},
|
||||
{"fd00::1", "Unique-Local (fc00::/7)"},
|
||||
// An IPv4 address written in IPv6 form counts as the IPv4 address.
|
||||
{"::ffff:10.0.0.1", "Private-Use (10.0.0.0/8)"},
|
||||
{"::ffff:8.8.8.8", ""},
|
||||
// An address that may be announced, inside a reserved block.
|
||||
{"192.0.0.9", ""},
|
||||
// Addresses anyone may announce.
|
||||
{"8.8.8.8", ""},
|
||||
{"2001:4860:4860::8888", ""},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.addr, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
reason, reserved := bogon.Addr(netip.MustParseAddr(tc.addr))
|
||||
if reason != tc.want || reserved != (tc.want != "") {
|
||||
t.Errorf("Addr(%s) = %q, %v; want %q", tc.addr, reason,
|
||||
reserved, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestASN(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -95,12 +95,14 @@ func (c *Cache) LookupAddr(ctx context.Context, addr string) ([]string, error) {
|
||||
return nil, fmt.Errorf("parsing the address: %w", err)
|
||||
}
|
||||
|
||||
_, reserved := bogon.Addr(parsed)
|
||||
parsed = parsed.Unmap()
|
||||
|
||||
_, reserved := bogon.Prefix(netip.PrefixFrom(parsed, parsed.BitLen()))
|
||||
if reserved {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
address := parsed.Unmap().String()
|
||||
address := parsed.String()
|
||||
|
||||
cached, ok := c.current(address)
|
||||
if ok {
|
||||
|
||||
@@ -1003,14 +1003,16 @@ func ipLookupFlags(ip string, listings []iplist.Listing) IPLookupFlags {
|
||||
}
|
||||
}
|
||||
|
||||
// isBogon says whether the address ip is reserved, as package bogon tells.
|
||||
// isBogon says whether the address ip is reserved. An IPv4 address written in
|
||||
// IPv6 form counts as the IPv4 address it holds.
|
||||
func isBogon(ip string) bool {
|
||||
addr, err := netip.ParseAddr(ip)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
_, reserved := bogon.Addr(addr)
|
||||
addr = addr.Unmap()
|
||||
_, reserved := bogon.Prefix(netip.PrefixFrom(addr, addr.BitLen()))
|
||||
|
||||
return reserved
|
||||
}
|
||||
|
||||
@@ -1253,19 +1253,16 @@ func TestIPLookupAnswers500WhenDatabaseReadFails(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// errNoSuchHost is what fakeResolver answers a host name lookup it has no
|
||||
// addresses for with.
|
||||
// errNoSuchHost is what fakeResolver answers a lookup it has no answer for
|
||||
// with.
|
||||
var errNoSuchHost = errors.New("no such host")
|
||||
|
||||
// fakeResolver answers a host name lookup with the addresses hosts lists for
|
||||
// the name. It answers a PTR lookup with the names ptrs lists for the address,
|
||||
// and with no names and no error, as the real one does, when ptrs lists none.
|
||||
// When ptrNeverAnswers is set, a PTR lookup fails after ptr.LookupTimeout, as
|
||||
// the real one does when no resolver answers. hostLookups counts the host name
|
||||
// lookups.
|
||||
// the name, and a PTR lookup with no names or, when ptrNeverAnswers is set,
|
||||
// with a failure after ptr.LookupTimeout, as the real one does when no
|
||||
// resolver answers. hostLookups counts the host name lookups.
|
||||
type fakeResolver struct {
|
||||
hosts map[string][]string
|
||||
ptrs map[string][]string
|
||||
ptrNeverAnswers bool
|
||||
|
||||
hostLookups atomic.Int64
|
||||
@@ -1282,7 +1279,7 @@ func (r *fakeResolver) LookupHost(_ context.Context, host string) ([]string, err
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
func (r *fakeResolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
|
||||
func (r *fakeResolver) LookupAddr(ctx context.Context, _ string) ([]string, error) {
|
||||
if r.ptrNeverAnswers {
|
||||
ctx, cancel := context.WithTimeout(ctx, ptr.LookupTimeout)
|
||||
defer cancel()
|
||||
@@ -1292,7 +1289,7 @@ func (r *fakeResolver) LookupAddr(ctx context.Context, addr string) ([]string, e
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
|
||||
return r.ptrs[addr], nil
|
||||
return nil, errNoSuchHost
|
||||
}
|
||||
|
||||
// useFakeResolver makes r answer the server's host name and PTR lookups.
|
||||
@@ -1404,10 +1401,9 @@ const addrInTestPrefixV4 = "192.0.2.1"
|
||||
|
||||
// TestIPLookupKeepsRouteWhenPTRLookupDoesNotAnswer looks up a routed address
|
||||
// with a resolver that never answers its PTR lookup. Once the PTR lookup's own
|
||||
// limit passes, the lookup answers 200 with the route and an empty ptr. Before
|
||||
// the fix the PTR lookup ran until the request's time limit, and the lookup
|
||||
// answered 504 without the route
|
||||
// (https://git.eeqj.de/sneak/routewatch/issues/110).
|
||||
// limit passes, the lookup answers 200 with the route. Before the fix the PTR
|
||||
// lookup ran until the request's time limit, and the lookup answered 504
|
||||
// without the route (https://git.eeqj.de/sneak/routewatch/issues/110).
|
||||
func TestIPLookupKeepsRouteWhenPTRLookupDoesNotAnswer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -1439,10 +1435,6 @@ func TestIPLookupKeepsRouteWhenPTRLookupDoesNotAnswer(t *testing.T) {
|
||||
*body.Data.Results[0].Netblock != testPrefixV4 {
|
||||
t.Errorf("answer %s, want one result in %s", rec.Body, testPrefixV4)
|
||||
}
|
||||
|
||||
if !strings.Contains(rec.Body.String(), `"ptr":[]`) {
|
||||
t.Errorf("answer %s, want an empty ptr list", rec.Body)
|
||||
}
|
||||
}
|
||||
|
||||
// addrInTestPrefixV6 is an address in testPrefixV6, which
|
||||
@@ -1765,32 +1757,6 @@ func TestIPLookupOfAnAddressWithoutPTRNamesOrStoredNetblock(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestIPLookupGivesPTRNamesWithoutTrailingDots looks up an address whose PTR
|
||||
// name the resolver gives fully qualified. The result's ptr holds the name
|
||||
// without its trailing dot.
|
||||
func TestIPLookupGivesPTRNamesWithoutTrailingDots(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
s := newServerWithTestRoutes(t)
|
||||
useFakeResolver(s, &fakeResolver{ptrs: map[string][]string{
|
||||
addrInTestPrefixV4: {"host.example.com."},
|
||||
}})
|
||||
|
||||
path := "/api/v1/ip/" + addrInTestPrefixV4
|
||||
|
||||
results := resultFields(t, get(t, s, path).Body.Bytes())
|
||||
if len(results) != 1 {
|
||||
t.Fatalf("%s: %d results, want 1", path, len(results))
|
||||
}
|
||||
|
||||
got := string(results[0]["ptr"])
|
||||
|
||||
want := `["host.example.com"]`
|
||||
if got != want {
|
||||
t.Errorf("%s: ptr is %s, want %s", path, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestIPLookupAnswersMayBeCached checks the Cache-Control header of the IP
|
||||
// lookup answers. Caches may keep them for the IP lists' shortest interval,
|
||||
// and only the caller's own browser may keep the answer about the caller's
|
||||
|
||||
@@ -58,8 +58,8 @@ type dnsResolver interface {
|
||||
LookupHost(ctx context.Context, host string) ([]string, error)
|
||||
}
|
||||
|
||||
// PTRResolver looks up the PTR names of addresses, as *ptr.Cache does.
|
||||
type PTRResolver interface {
|
||||
// ptrResolver looks up the PTR names of addresses, as *ptr.Cache does.
|
||||
type ptrResolver interface {
|
||||
LookupAddr(ctx context.Context, addr string) ([]string, error)
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ type Server struct {
|
||||
resolver dnsResolver
|
||||
|
||||
// ptrResolver looks up the IP lookup's PTR names. SetPTRResolver sets it.
|
||||
ptrResolver PTRResolver
|
||||
ptrResolver ptrResolver
|
||||
|
||||
// cards is the copy of the home page's cards that the pages serve, nil
|
||||
// until the server first works them out
|
||||
@@ -205,7 +205,7 @@ func (s *Server) Stop(ctx context.Context) error {
|
||||
|
||||
// SetPTRResolver sets what looks up the IP lookup's PTR names. Call it before
|
||||
// Start: the handlers read it without a lock.
|
||||
func (s *Server) SetPTRResolver(resolver PTRResolver) {
|
||||
func (s *Server) SetPTRResolver(resolver ptrResolver) {
|
||||
s.ptrResolver = resolver
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user