resolver: look up every nameserver a referral gives no address for (closes #221)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
Looking up a nameserver's own address followed only the addresses a referral gave, so a nameserver whose zone is delegated without them, such as a.ntpns.org of pool.ntp.org, never resolved. The walk to a name's nameservers looked addresses up only when a referral gave none, so when it gave some it asked only those. Both now ask every nameserver a referral names, looking up the addresses it lacks. A lookup can start further lookups; maxLookupDepth stops them two deep, so zones delegated to each other's nameservers, as desec.io and desec.org are, still end. A referral that gives addresses for only some nameservers now costs one lookup per nameserver without one. Model: opus-5-5
This commit is contained in:
@@ -162,6 +162,109 @@ func TestResolveNSIPs_EveryNameserver(t *testing.T) {
|
||||
assert.ElementsMatch(t, want, got)
|
||||
}
|
||||
|
||||
// TestResolveNSIPs_ZoneDelegatedWithoutAddresses looks up the address
|
||||
// of a.ntpns.org, a nameserver of pool.ntp.org. The org servers delegate
|
||||
// ntpns.org to nameservers in other zones and give none of their
|
||||
// addresses, so those are looked up on the way.
|
||||
func TestResolveNSIPs_ZoneDelegatedWithoutAddresses(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := newTestResolver(t)
|
||||
ips := liveResolveNSIPs(t, r, []string{"a.ntpns.org."}, 1)
|
||||
|
||||
for _, ip := range ips {
|
||||
assert.NotNil(t, net.ParseIP(ip), "should be valid IP: %s", ip)
|
||||
}
|
||||
}
|
||||
|
||||
// TestResolveNSIPs_DelegationsPointAtEachOther looks up the address of
|
||||
// ns1.desec.io. The io servers delegate desec.io to ns1.desec.io, with
|
||||
// its address, and to ns2.desec.org, without; the org servers delegate
|
||||
// desec.org to ns2.desec.org, with its address, and to ns1.desec.io,
|
||||
// without. Looking up either address starts a lookup of the other, and
|
||||
// the lookup must still end.
|
||||
func TestResolveNSIPs_DelegationsPointAtEachOther(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := newTestResolver(t)
|
||||
ips := liveResolveNSIPs(t, r, []string{"ns1.desec.io."}, 1)
|
||||
|
||||
for _, ip := range ips {
|
||||
assert.NotNil(t, net.ParseIP(ip), "should be valid IP: %s", ip)
|
||||
}
|
||||
}
|
||||
|
||||
// givenAddresses returns the IPv4 addresses that resp, a referral,
|
||||
// gives for the nameservers it names.
|
||||
func givenAddresses(resp *dns.Msg) []string {
|
||||
var ips []string
|
||||
|
||||
for _, rr := range resp.Extra {
|
||||
if a, ok := rr.(*dns.A); ok {
|
||||
ips = append(ips, a.A.String())
|
||||
}
|
||||
}
|
||||
|
||||
return ips
|
||||
}
|
||||
|
||||
// TestReferralServers_SomeWithoutAddresses asks the org servers about
|
||||
// ntp.org, as the walk to a name under ntp.org does. Their referral
|
||||
// names four nameservers and gives an address for ns1.everett.org
|
||||
// alone. The addresses of the other three are looked up, so that the
|
||||
// walk can ask them too.
|
||||
func TestReferralServers_SomeWithoutAddresses(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
r := newTestResolver(t)
|
||||
|
||||
var referral *dns.Msg
|
||||
|
||||
livednstest.Retry(
|
||||
t,
|
||||
"referral for ntp.org from the org servers",
|
||||
func(ctx context.Context) error {
|
||||
fromRoot, err := r.QueryServers(
|
||||
ctx, resolver.RootServerList(), ".", "ntp.org.",
|
||||
dns.TypeNS,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
referral, err = r.QueryServers(
|
||||
ctx, givenAddresses(fromRoot), "org.", "ntp.org.",
|
||||
dns.TypeNS,
|
||||
)
|
||||
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
given := givenAddresses(referral)
|
||||
require.NotEmpty(t, given, "the referral gives no addresses")
|
||||
|
||||
var servers []string
|
||||
|
||||
livednstest.Retry(
|
||||
t,
|
||||
"ReferralServers(referral for ntp.org)",
|
||||
func(ctx context.Context) error {
|
||||
servers = r.ReferralServers(ctx, referral)
|
||||
if len(servers) <= len(given) {
|
||||
return fmt.Errorf(
|
||||
"%w: %d addresses, the referral gives %d",
|
||||
livednstest.ErrNoAnswer, len(servers), len(given),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
assert.Subset(t, servers, given)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// QueryNameserver tests
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user