aboutsummaryrefslogtreecommitdiff
path: root/middleware/file/lookup.go
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/file/lookup.go')
-rw-r--r--middleware/file/lookup.go67
1 files changed, 49 insertions, 18 deletions
diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go
index 2798b0b23..20ec1ce00 100644
--- a/middleware/file/lookup.go
+++ b/middleware/file/lookup.go
@@ -14,16 +14,17 @@ const (
// Lookup looks up qname and qtype in the zone, when do is true DNSSEC are included as well.
// Two sets of records are returned, one for the answer and one for the additional section.
func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR, Result) {
- // TODO(miek): implement DNSSEC
var rr dns.RR
mk, known := dns.TypeToRR[qtype]
if !known {
- return nil, nil, NameError
- // Uhm...?
- // rr = new(RFC3597)
+ an, ad, _ := z.lookupSOA(do)
+ return an, ad, NameError
+ // Uhm...? rr = new(RFC3597) ??
} else {
rr = mk()
}
+ rr.Header().Rrtype = qtype // this is pretty nonobvious
+
if qtype == dns.TypeSOA {
return z.lookupSOA(do)
}
@@ -31,38 +32,68 @@ func (z *Zone) Lookup(qname string, qtype uint16, do bool) ([]dns.RR, []dns.RR,
rr.Header().Name = qname
elem := z.Tree.Get(rr)
if elem == nil {
- return []dns.RR{z.SOA}, nil, NameError
+ an, ad, _ := z.lookupSOA(do)
+ return an, ad, NameError
}
+
rrs := elem.Types(dns.TypeCNAME)
if len(rrs) > 0 { // should only ever be 1 actually; TODO(miek) check for this?
- // lookup target from the cname
rr.Header().Name = rrs[0].(*dns.CNAME).Target
- elem := z.Tree.Get(rr)
- if elem == nil {
- return rrs, nil, Success
- }
- return rrs, elem.All(), Success
+ return z.lookupCNAME(rrs, rr, do)
}
rrs = elem.Types(qtype)
if len(rrs) == 0 {
- return []dns.RR{z.SOA}, nil, NoData
+ an, ad, _ := z.lookupSOA(do)
+ return an, ad, NoData
+ }
+ if do {
+ sigs := elem.Types(dns.TypeRRSIG)
+ sigs = signatureForSubType(sigs, qtype)
+ if len(sigs) > 0 {
+ rrs = append(rrs, sigs...)
+ }
}
- // Need to check sub-type on RRSIG records to only include the correctly
- // typed ones.
return rrs, nil, Success
}
func (z *Zone) lookupSOA(do bool) ([]dns.RR, []dns.RR, Result) {
+ if do {
+ ret := append([]dns.RR{z.SOA}, z.SIG...)
+ return ret, nil, Success
+ }
return []dns.RR{z.SOA}, nil, Success
}
+func (z *Zone) lookupCNAME(rrs []dns.RR, rr dns.RR, do bool) ([]dns.RR, []dns.RR, Result) {
+ elem := z.Tree.Get(rr)
+ if elem == nil {
+ return rrs, nil, Success
+ }
+ extra := cnameForType(elem.All(), rr.Header().Rrtype)
+ if do {
+ sigs := elem.Types(dns.TypeRRSIG)
+ sigs = signatureForSubType(sigs, rr.Header().Rrtype)
+ if len(sigs) > 0 {
+ extra = append(extra, sigs...)
+ }
+ }
+ return rrs, extra, Success
+}
+
+func cnameForType(targets []dns.RR, origQtype uint16) []dns.RR {
+ ret := []dns.RR{}
+ for _, target := range targets {
+ if target.Header().Rrtype == origQtype {
+ ret = append(ret, target)
+ }
+ }
+ return ret
+}
+
// signatureForSubType range through the signature and return the correct
// ones for the subtype.
-func (z *Zone) signatureForSubType(rrs []dns.RR, subtype uint16, do bool) []dns.RR {
- if !do {
- return nil
- }
+func signatureForSubType(rrs []dns.RR, subtype uint16) []dns.RR {
sigs := []dns.RR{}
for _, sig := range rrs {
if s, ok := sig.(*dns.RRSIG); ok {