aboutsummaryrefslogtreecommitdiff
path: root/middleware/file/lookup.go
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2016-03-27 07:37:23 +0100
committerGravatar Miek Gieben <miek@miek.nl> 2016-03-28 10:15:05 +0100
commit5387c162c994d7d81ccf21c8c8f9d9959ed27240 (patch)
treef10c1777f3cd96a42c67b8c955c737c88aa58744 /middleware/file/lookup.go
parent9eeb2b02595664e861ae639933555b3ed507c93d (diff)
downloadcoredns-5387c162c994d7d81ccf21c8c8f9d9959ed27240.tar.gz
coredns-5387c162c994d7d81ccf21c8c8f9d9959ed27240.tar.zst
coredns-5387c162c994d7d81ccf21c8c8f9d9959ed27240.zip
Implement a DNS zone
Full implementation, DNS (and in the future DNSSEC). Returns answer in a hopefully standards compliant way. Testing with my miek.nl zone are included as well. This should correctly handle nodata, nxdomain and cnames.
Diffstat (limited to 'middleware/file/lookup.go')
-rw-r--r--middleware/file/lookup.go75
1 files changed, 75 insertions, 0 deletions
diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go
new file mode 100644
index 000000000..2798b0b23
--- /dev/null
+++ b/middleware/file/lookup.go
@@ -0,0 +1,75 @@
+package file
+
+import "github.com/miekg/dns"
+
+// Result is the result of a Lookup
+type Result int
+
+const (
+ Success Result = iota
+ NameError
+ NoData // aint no offical NoData return code.
+)
+
+// 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)
+ } else {
+ rr = mk()
+ }
+ if qtype == dns.TypeSOA {
+ return z.lookupSOA(do)
+ }
+
+ rr.Header().Name = qname
+ elem := z.Tree.Get(rr)
+ if elem == nil {
+ return []dns.RR{z.SOA}, nil, 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
+ }
+
+ rrs = elem.Types(qtype)
+ if len(rrs) == 0 {
+ return []dns.RR{z.SOA}, nil, NoData
+ }
+ // 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) {
+ return []dns.RR{z.SOA}, nil, Success
+}
+
+// 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
+ }
+ sigs := []dns.RR{}
+ for _, sig := range rrs {
+ if s, ok := sig.(*dns.RRSIG); ok {
+ if s.TypeCovered == subtype {
+ sigs = append(sigs, s)
+ }
+ }
+ }
+ return sigs
+}