middleware/file: Support delegations (#124)

Return a delegation when seeing one while traversing the tree in
search of an answer.

Put the SOA and NS record in the zone.Apex as these are to be handled
somewhat special.

Lowercase record on insert to make compares easier. This lowercases
all RR that have domain names in their rdata as well.
This commit is contained in:
Miek Gieben
2016-04-16 16:16:52 +01:00
parent f783634174
commit e294c95582
14 changed files with 288 additions and 70 deletions

View File

@@ -12,6 +12,7 @@ type Result int
const (
Success Result = iota
NameError
Delegation
NoData
ServerFailure
)
@@ -22,6 +23,9 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR,
if qtype == dns.TypeSOA {
return z.lookupSOA(do)
}
if qtype == dns.TypeNS && qname == z.origin {
return z.lookupNS(do)
}
elem, res := z.Tree.Search(qname, qtype)
if elem == nil {
@@ -30,6 +34,21 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR,
}
return z.nameError(qname, qtype, do)
}
if res == tree.Delegation {
rrs := elem.Types(dns.TypeNS)
glue := []dns.RR{}
for _, ns := range rrs {
if dns.IsSubDomain(ns.Header().Name, ns.(*dns.NS).Ns) {
// even with Do, this should be unsigned.
elem, res := z.Tree.SearchGlue(ns.(*dns.NS).Ns)
if res == tree.Found {
glue = append(glue, elem.Types(dns.TypeAAAA)...)
glue = append(glue, elem.Types(dns.TypeA)...)
}
}
}
return nil, rrs, glue, Delegation
}
rrs := elem.Types(dns.TypeCNAME)
if len(rrs) > 0 { // should only ever be 1 actually; TODO(miek) check for this?
@@ -87,9 +106,9 @@ func (z *Zone) nameError(qname string, qtype uint16, do bool) ([]dns.RR, []dns.R
}
// name error
ret := []dns.RR{z.SOA}
ret := []dns.RR{z.Apex.SOA}
if do {
ret = append(ret, z.SIG...)
ret = append(ret, z.Apex.SIGSOA...)
ret = append(ret, z.nameErrorProof(qname, qtype)...)
}
return nil, ret, nil, NameError
@@ -97,10 +116,18 @@ func (z *Zone) nameError(qname string, qtype uint16, do bool) ([]dns.RR, []dns.R
func (z *Zone) lookupSOA(do bool) ([]dns.RR, []dns.RR, []dns.RR, Result) {
if do {
ret := append([]dns.RR{z.SOA}, z.SIG...)
ret := append([]dns.RR{z.Apex.SOA}, z.Apex.SIGSOA...)
return ret, nil, nil, Success
}
return []dns.RR{z.SOA}, nil, nil, Success
return []dns.RR{z.Apex.SOA}, nil, nil, Success
}
func (z *Zone) lookupNS(do bool) ([]dns.RR, []dns.RR, []dns.RR, Result) {
if do {
ret := append(z.Apex.NS, z.Apex.SIGNS...)
return ret, nil, nil, Success
}
return z.Apex.NS, nil, nil, Success
}
// lookupNSEC looks up nsec and sigs.