resolver: take a domain's NS set from its delegation (closes #200)
check / check (push) Failing after 2m2s
check / check (push) Failing after 2m2s
A domain's NS set was taken from whichever of its own servers answered first, so when they disagree (during a move between DNS providers, or with a stale secondary) the set could change between checks and send an NS change notification with nothing changed. The walk now stops at the referral to the domain from its parent zone's servers and returns that delegation, which those servers all hold alike; the domain's own servers are no longer asked for it. The NS records in an answer are still used where no such referral comes first, as from a server that holds both the parent zone and the domain. Hostnames get their zone's servers the same way. Model: opus-5-5
This commit was merged in pull request #202.
This commit is contained in:
@@ -41,8 +41,15 @@ func TestCollectIPs_FailedIsNoAnswer(t *testing.T) {
|
||||
assert.Empty(t, ips)
|
||||
}
|
||||
|
||||
// exampleCom is the zone most cases of TestUsableReply are about.
|
||||
const exampleCom = "example.com."
|
||||
const (
|
||||
// exampleCom is the zone most cases of TestUsableReply and
|
||||
// TestNSSetFrom are about, and wwwExampleCom a name in it.
|
||||
exampleCom = "example.com."
|
||||
wwwExampleCom = "www.example.com."
|
||||
|
||||
// exampleNS is the server the NS records nsRecord builds name.
|
||||
exampleNS = "ns1.example.net."
|
||||
)
|
||||
|
||||
// nsRecord builds an NS record that names a server of zone.
|
||||
func nsRecord(zone string) *dns.NS {
|
||||
@@ -50,7 +57,7 @@ func nsRecord(zone string) *dns.NS {
|
||||
Hdr: dns.RR_Header{
|
||||
Name: zone, Rrtype: dns.TypeNS, Class: dns.ClassINET,
|
||||
},
|
||||
Ns: "ns1.example.net.",
|
||||
Ns: exampleNS,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +112,7 @@ func TestUsableReply(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "com refers to example.com", resp: referralTo(exampleCom),
|
||||
zone: "com.", query: "www.example.com.", want: true,
|
||||
zone: "com.", query: wwwExampleCom, want: true,
|
||||
},
|
||||
{
|
||||
name: "referral back to the zone", resp: referralTo(exampleCom),
|
||||
@@ -132,6 +139,51 @@ func TestUsableReply(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestNSSetFrom checks which NS set a reply gives for a domain; a set
|
||||
// that is not empty ends the walk. The referral to example.com that
|
||||
// com's servers all send alike gives its delegation, so the set is the
|
||||
// same whichever of them answered, and example.com's own servers, which
|
||||
// can disagree, are not asked.
|
||||
func TestNSSetFrom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
answer := new(dns.Msg)
|
||||
answer.Authoritative = true
|
||||
answer.Answer = []dns.RR{nsRecord(exampleCom)}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
resp *dns.Msg
|
||||
domain string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "com refers to example.com", resp: referralTo(exampleCom),
|
||||
domain: exampleCom, want: []string{exampleNS},
|
||||
},
|
||||
{
|
||||
name: "com refers on, for www.example.com",
|
||||
resp: referralTo(exampleCom), domain: wwwExampleCom,
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "answer from a server that holds example.com",
|
||||
resp: answer, domain: exampleCom,
|
||||
want: []string{exampleNS},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert.ElementsMatch(t, tt.want,
|
||||
resolver.NSSetFrom(tt.resp, tt.domain),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractRecordValue_LetterCase(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user