aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugin/auto/auto.go9
-rw-r--r--plugin/file/file.go9
-rw-r--r--plugin/file/lookup.go2
-rw-r--r--plugin/file/lookup_test.go12
-rw-r--r--test/file_upstream_test.go7
5 files changed, 35 insertions, 4 deletions
diff --git a/plugin/auto/auto.go b/plugin/auto/auto.go
index 6330621be..581004b20 100644
--- a/plugin/auto/auto.go
+++ b/plugin/auto/auto.go
@@ -82,7 +82,14 @@ func (a Auto) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
case file.Delegation:
m.Authoritative = false
case file.ServerFailure:
- return dns.RcodeServerFailure, nil
+ // If the result is SERVFAIL and the answer is non-empty, then the SERVFAIL came from an
+ // external CNAME lookup and the answer contains the CNAME with no target record. We should
+ // write the CNAME record to the client instead of sending an empty SERVFAIL response.
+ if len(m.Answer) == 0 {
+ return dns.RcodeServerFailure, nil
+ }
+ // The rcode in the response should be the rcode received from the target lookup. RFC 6604 section 3
+ m.Rcode = dns.RcodeServerFailure
}
w.WriteMsg(m)
diff --git a/plugin/file/file.go b/plugin/file/file.go
index 0834ddc4d..f50c3d091 100644
--- a/plugin/file/file.go
+++ b/plugin/file/file.go
@@ -99,7 +99,14 @@ func (f File) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
case Delegation:
m.Authoritative = false
case ServerFailure:
- return dns.RcodeServerFailure, nil
+ // If the result is SERVFAIL and the answer is non-empty, then the SERVFAIL came from an
+ // external CNAME lookup and the answer contains the CNAME with no target record. We should
+ // write the CNAME record to the client instead of sending an empty SERVFAIL response.
+ if len(m.Answer) == 0 {
+ return dns.RcodeServerFailure, nil
+ }
+ // The rcode in the response should be the rcode received from the target lookup. RFC 6604 section 3
+ m.Rcode = dns.RcodeServerFailure
}
w.WriteMsg(m)
diff --git a/plugin/file/lookup.go b/plugin/file/lookup.go
index 59c0927b5..2318af1fa 100644
--- a/plugin/file/lookup.go
+++ b/plugin/file/lookup.go
@@ -383,7 +383,7 @@ Redo:
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, Success
+ return nil, ServerFailure
}
if m == nil {
return nil, Success
diff --git a/plugin/file/lookup_test.go b/plugin/file/lookup_test.go
index 46ca68d22..2d81fbae6 100644
--- a/plugin/file/lookup_test.go
+++ b/plugin/file/lookup_test.go
@@ -117,6 +117,14 @@ var dnsTestCases = []test.Case{
},
Ns: miekAuth,
},
+ {
+ Qname: "ext-cname.miek.nl.", Qtype: dns.TypeA,
+ Answer: []dns.RR{
+ test.CNAME("ext-cname.miek.nl. 1800 IN CNAME example.com."),
+ },
+ Rcode: dns.RcodeServerFailure,
+ Ns: miekAuth,
+ },
}
const (
@@ -218,4 +226,6 @@ archive IN CNAME a
dname IN DNAME x
srv IN SRV 10 10 8080 a.miek.nl.
-mx IN MX 10 a.miek.nl.`
+mx IN MX 10 a.miek.nl.
+
+ext-cname IN CNAME example.com.`
diff --git a/test/file_upstream_test.go b/test/file_upstream_test.go
index 6b796f90d..77ffa1d6e 100644
--- a/test/file_upstream_test.go
+++ b/test/file_upstream_test.go
@@ -77,10 +77,17 @@ func TestFileUpstreamError(t *testing.T) {
},
"srvfail": {
Qname: "srvfail.example.org.", Qtype: dns.TypeA,
+ Answer: []dns.RR{
+ test.CNAME("srvfail.example.org. 3600 IN CNAME srvfail.example.net."),
+ },
Rcode: dns.RcodeServerFailure,
},
"srvfail-chain": {
Qname: "chain2.example.org.", Qtype: dns.TypeA,
+ Answer: []dns.RR{
+ test.CNAME("chain2.example.org. 3600 IN CNAME srvfail.example.org."),
+ test.CNAME("srvfail.example.org. 3600 IN CNAME srvfail.example.net."),
+ },
Rcode: dns.RcodeServerFailure,
},
"nodata": {