plugin/file: Use NXDOMAIN response if CNAME target is NXDOMAIN (#4303)
* pass through nxdomain results Signed-off-by: Chris O'Haver <cohaver@infoblox.com> * return srvfail and nodata results Signed-off-by: Chris O'Haver <cohaver@infoblox.com> * add test Signed-off-by: Chris O'Haver <cohaver@infoblox.com> * cover more response cases Signed-off-by: Chris O'Haver <cohaver@infoblox.com>
This commit is contained in:
parent
5ecf23ae7b
commit
6bbb48d403
3 changed files with 145 additions and 8 deletions
|
@ -307,8 +307,9 @@ func (z *Zone) externalLookup(ctx context.Context, state request.Request, elem *
|
|||
targetName := rrs[0].(*dns.CNAME).Target
|
||||
elem, _ = z.Tree.Search(targetName)
|
||||
if elem == nil {
|
||||
rrs = append(rrs, z.doLookup(ctx, state, targetName, qtype)...)
|
||||
return rrs, z.Apex.ns(do), nil, Success
|
||||
lookupRRs, result := z.doLookup(ctx, state, targetName, qtype)
|
||||
rrs = append(rrs, lookupRRs...)
|
||||
return rrs, z.Apex.ns(do), nil, result
|
||||
}
|
||||
|
||||
i := 0
|
||||
|
@ -326,8 +327,9 @@ Redo:
|
|||
targetName := cname[0].(*dns.CNAME).Target
|
||||
elem, _ = z.Tree.Search(targetName)
|
||||
if elem == nil {
|
||||
rrs = append(rrs, z.doLookup(ctx, state, targetName, qtype)...)
|
||||
return rrs, z.Apex.ns(do), nil, Success
|
||||
lookupRRs, result := z.doLookup(ctx, state, targetName, qtype)
|
||||
rrs = append(rrs, lookupRRs...)
|
||||
return rrs, z.Apex.ns(do), nil, result
|
||||
}
|
||||
|
||||
i++
|
||||
|
@ -352,15 +354,24 @@ Redo:
|
|||
return rrs, z.Apex.ns(do), nil, Success
|
||||
}
|
||||
|
||||
func (z *Zone) doLookup(ctx context.Context, state request.Request, target string, qtype uint16) []dns.RR {
|
||||
func (z *Zone) doLookup(ctx context.Context, state request.Request, target string, qtype uint16) ([]dns.RR, Result) {
|
||||
m, e := z.Upstream.Lookup(ctx, state, target, qtype)
|
||||
if e != nil {
|
||||
return nil
|
||||
return nil, Success
|
||||
}
|
||||
if m == nil {
|
||||
return nil
|
||||
return nil, Success
|
||||
}
|
||||
return m.Answer
|
||||
if m.Rcode == dns.RcodeNameError {
|
||||
return m.Answer, NameError
|
||||
}
|
||||
if m.Rcode == dns.RcodeServerFailure {
|
||||
return m.Answer, ServerFailure
|
||||
}
|
||||
if m.Rcode == dns.RcodeSuccess && len(m.Answer) == 0 {
|
||||
return m.Answer, NoData
|
||||
}
|
||||
return m.Answer, Success
|
||||
}
|
||||
|
||||
// additionalProcessing checks the current answer section and retrieves A or AAAA records
|
||||
|
|
|
@ -58,6 +58,113 @@ www 3600 IN CNAME www.example.net.
|
|||
}
|
||||
}
|
||||
|
||||
func TestFileUpstreamError(t *testing.T) {
|
||||
cases := map[string]test.Case{
|
||||
"nxdomain": {
|
||||
Qname: "nxdomain.example.org.", Qtype: dns.TypeA,
|
||||
Answer: []dns.RR{
|
||||
test.CNAME("nxdomain.example.org. 3600 IN CNAME nxdomain.example.net"),
|
||||
},
|
||||
Rcode: dns.RcodeNameError,
|
||||
},
|
||||
"nxdomain-chain": {
|
||||
Qname: "chain1.example.org.", Qtype: dns.TypeA,
|
||||
Answer: []dns.RR{
|
||||
test.CNAME("chain1.example.org. 3600 IN CNAME nxdomain.example.org"),
|
||||
test.CNAME("nxdomain.example.org. 3600 IN CNAME nxdomain.example.net"),
|
||||
},
|
||||
Rcode: dns.RcodeNameError,
|
||||
},
|
||||
"srvfail": {
|
||||
Qname: "srvfail.example.org.", Qtype: dns.TypeA,
|
||||
Rcode: dns.RcodeServerFailure,
|
||||
},
|
||||
"srvfail-chain": {
|
||||
Qname: "chain2.example.org.", Qtype: dns.TypeA,
|
||||
Rcode: dns.RcodeServerFailure,
|
||||
},
|
||||
"nodata": {
|
||||
Qname: "nodata.example.org.", Qtype: dns.TypeA,
|
||||
Answer: []dns.RR{
|
||||
test.CNAME("nodata.example.org. 3600 IN CNAME nodata.example.net"),
|
||||
},
|
||||
Rcode: dns.RcodeSuccess,
|
||||
},
|
||||
"nodata-chain": {
|
||||
Qname: "chain3.example.org.", Qtype: dns.TypeA,
|
||||
Answer: []dns.RR{
|
||||
test.CNAME("chain3.example.org. 3600 IN CNAME nodata.example.org"),
|
||||
test.CNAME("nodata.example.org. 3600 IN CNAME nodata.example.net"),
|
||||
},
|
||||
Rcode: dns.RcodeSuccess,
|
||||
},
|
||||
}
|
||||
name, rm, err := test.TempFile(".", `$ORIGIN example.org.
|
||||
@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
|
||||
2017042745 ; serial
|
||||
7200 ; refresh (2 hours)
|
||||
3600 ; retry (1 hour)
|
||||
1209600 ; expire (2 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
3600 IN NS a.iana-servers.net.
|
||||
3600 IN NS b.iana-servers.net.
|
||||
|
||||
chain1 3600 IN CNAME nxdomain
|
||||
nxdomain 3600 IN CNAME nxdomain.example.net.
|
||||
chain2 3600 IN CNAME srvfail
|
||||
srvfail 3600 IN CNAME srvfail.example.net.
|
||||
chain3 3600 IN CNAME nodata
|
||||
nodata 3600 IN CNAME nodata.example.net.
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create zone: %s", err)
|
||||
}
|
||||
defer rm()
|
||||
|
||||
corefile := `.:0 {
|
||||
template ANY A nxdomain.example.net. {
|
||||
rcode NXDOMAIN
|
||||
}
|
||||
template ANY A srvfail.example.net. {
|
||||
rcode SERVFAIL
|
||||
}
|
||||
template ANY A nodata.example.net. {
|
||||
}
|
||||
file ` + name + ` example.org
|
||||
}`
|
||||
|
||||
i, udp, _, err := CoreDNSServerAndPorts(corefile)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get CoreDNS serving instance: %s", err)
|
||||
}
|
||||
defer i.Stop()
|
||||
|
||||
for n, tc := range cases {
|
||||
t.Run(n, func(t *testing.T) {
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(tc.Qname, tc.Qtype)
|
||||
m.SetEdns0(4096, true)
|
||||
|
||||
r, err := dns.Exchange(m, udp)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not exchange msg: %s", err)
|
||||
}
|
||||
if r.Rcode != tc.Rcode {
|
||||
t.Fatalf("expected rcode %v, got %v", tc.Rcode, r.Rcode)
|
||||
}
|
||||
if n := len(r.Answer); n != len(tc.Answer) {
|
||||
t.Fatalf("Expected %v answers, got %v", len(tc.Answer), n)
|
||||
}
|
||||
if err := test.Section(tc, test.Answer, r.Answer); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestFileUpstreamAdditional runs two CoreDNS servers that serve example.org and foo.example.org.
|
||||
// example.org contains a cname to foo.example.org; this should be resolved via upstream.Self.
|
||||
func TestFileUpstreamAdditional(t *testing.T) {
|
||||
|
|
19
test/go-test-tmpfile565156097
Normal file
19
test/go-test-tmpfile565156097
Normal file
|
@ -0,0 +1,19 @@
|
|||
$ORIGIN example.org.
|
||||
@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. (
|
||||
2017042745 ; serial
|
||||
7200 ; refresh (2 hours)
|
||||
3600 ; retry (1 hour)
|
||||
1209600 ; expire (2 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
3600 IN NS a.iana-servers.net.
|
||||
3600 IN NS b.iana-servers.net.
|
||||
|
||||
chain1 3600 IN CNAME nxdomain
|
||||
nxdomain 3600 IN CNAME nxdomain.example.net.
|
||||
chain2 3600 IN CNAME srvfail
|
||||
srvfail 3600 IN CNAME srvfail.example.net.
|
||||
chain3 3600 IN CNAME nodata
|
||||
nodata 3600 IN CNAME nodata.example.net.
|
||||
|
Loading…
Add table
Reference in a new issue