diff --git a/middleware/file/closest.go b/middleware/file/closest.go index 2ee14e6d8..172242669 100644 --- a/middleware/file/closest.go +++ b/middleware/file/closest.go @@ -6,7 +6,7 @@ import ( "github.com/miekg/dns" ) -// ClosestEncloser returns the closest encloser for rr. +// ClosestEncloser returns the closest encloser for qname. func (z *Zone) ClosestEncloser(qname string) (*tree.Elem, bool) { offset, end := dns.NextLabel(qname, 0) diff --git a/middleware/file/dnssec_test.go b/middleware/file/dnssec_test.go index 63099afb4..7f4a0916b 100644 --- a/middleware/file/dnssec_test.go +++ b/middleware/file/dnssec_test.go @@ -29,6 +29,17 @@ var dnssecTestCases = []test.Case{ }, Extra: []dns.RR{test.OPT(4096, true)}, }, + { + Qname: "miek.nl.", Qtype: dns.TypeNS, Do: true, + Answer: []dns.RR{ + test.NS("miek.nl. 1800 IN NS ext.ns.whyscream.net."), + test.NS("miek.nl. 1800 IN NS linode.atoom.net."), + test.NS("miek.nl. 1800 IN NS ns-ext.nlnetlabs.nl."), + test.NS("miek.nl. 1800 IN NS omval.tednet.nl."), + test.RRSIG("miek.nl. 1800 IN RRSIG NS 8 2 1800 20160426031301 20160327031301 12051 miek.nl. ZLtsQhwaz+lHfNpztFoR1Vxs="), + }, + Extra: []dns.RR{test.OPT(4096, true)}, + }, { Qname: "miek.nl.", Qtype: dns.TypeMX, Do: true, Answer: []dns.RR{ diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go index 16325d3e9..95cd02e73 100644 --- a/middleware/file/lookup.go +++ b/middleware/file/lookup.go @@ -146,7 +146,9 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, // Haven't found the original name. + // Found wildcard. if wildElem != nil { + auth := []dns.RR{} if rrs := wildElem.Types(dns.TypeCNAME, qname); len(rrs) > 0 { return z.searchCNAME(rrs, qtype, do) @@ -154,26 +156,29 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, rrs := wildElem.Types(qtype, qname) - // NODATA + // NODATA response. if len(rrs) == 0 { ret := z.soa(do) if do { - // Do we need to add closest encloser here as well. - // closest encloser - // ce, _ := z.ClosestEncloser(qname) - // println("CLOSEST ENCLOSER", ce.Name()) // need to add this too. nsec := z.typeFromElem(wildElem, dns.TypeNSEC, do) ret = append(ret, nsec...) } return nil, ret, nil, Success } + if do { + // An NSEC is needed to say no longer name exists under this wildcard. + if deny, found := z.Tree.Prev(qname); found { + nsec := z.typeFromElem(deny, dns.TypeNSEC, do) + auth = append(auth, nsec...) + } + sigs := wildElem.Types(dns.TypeRRSIG, qname) sigs = signatureForSubType(sigs, qtype) rrs = append(rrs, sigs...) } - return rrs, nil, nil, Success + return rrs, auth, nil, Success } rcode := NameError @@ -289,9 +294,9 @@ func signatureForSubType(rrs []dns.RR, subtype uint16) []dns.RR { // Glue returns any potential glue records for nsrrs. func (z *Zone) Glue(nsrrs []dns.RR) []dns.RR { glue := []dns.RR{} - for _, ns := range nsrrs { - if dns.IsSubDomain(ns.Header().Name, ns.(*dns.NS).Ns) { - glue = append(glue, z.searchGlue(ns.(*dns.NS).Ns)...) + for _, rr := range nsrrs { + if ns, ok := rr.(*dns.NS); ok && dns.IsSubDomain(ns.Header().Name, ns.Ns) { + glue = append(glue, z.searchGlue(ns.Ns)...) } } return glue diff --git a/middleware/file/wildcard_test.go b/middleware/file/wildcard_test.go index b3bd5915b..4acc21bde 100644 --- a/middleware/file/wildcard_test.go +++ b/middleware/file/wildcard_test.go @@ -31,6 +31,10 @@ var wildcardTestCases = []test.Case{ test.RRSIG("wild.dnssex.nl. 1800 IN RRSIG TXT 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. FUZSTyvZfeuuOpCm"), test.TXT(`wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`), }, + Ns: []dns.RR{ + test.NSEC("a.dnssex.nl. 14400 IN NSEC www.dnssex.nl. A AAAA RRSIG NSEC"), + test.RRSIG("a.dnssex.nl. 14400 IN RRSIG NSEC 8 3 14400 20160428190224 20160329190224 14460 dnssex.nl. S+UMs2ySgRaaRY"), + }, Extra: []dns.RR{test.OPT(4096, true)}, }, { @@ -39,6 +43,10 @@ var wildcardTestCases = []test.Case{ test.RRSIG("a.wild.dnssex.nl. 1800 IN RRSIG TXT 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. FUZSTyvZfeuuOpCm"), test.TXT(`a.wild.dnssex.nl. 1800 IN TXT "Doing It Safe Is Better"`), }, + Ns: []dns.RR{ + test.NSEC("a.dnssex.nl. 14400 IN NSEC www.dnssex.nl. A AAAA RRSIG NSEC"), + test.RRSIG("a.dnssex.nl. 14400 IN RRSIG NSEC 8 3 14400 20160428190224 20160329190224 14460 dnssex.nl. S+UMs2ySgRaaRY"), + }, Extra: []dns.RR{test.OPT(4096, true)}, }, // nodata responses