From bf6d90600be7eac782e076b7c5f334e83ba9dea0 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Wed, 30 Mar 2016 16:45:02 +0000 Subject: [PATCH] add closest encloser stuff --- middleware/canonical.go | 7 +++++-- middleware/file/closest.go | 16 ++++++++++++++++ middleware/file/closest_test.go | 34 +++++++++++++++++++++++++++++++++ middleware/file/dnssec_test.go | 3 ++- middleware/file/lookup.go | 1 + middleware/file/tree/tree.go | 19 ++++-------------- 6 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 middleware/file/closest.go create mode 100644 middleware/file/closest_test.go diff --git a/middleware/canonical.go b/middleware/canonical.go index 5d51231c2..b8953f655 100644 --- a/middleware/canonical.go +++ b/middleware/canonical.go @@ -17,8 +17,11 @@ func Less(a, b string) int { aj := len(a) bj := len(b) for { - ai, _ := dns.PrevLabel(a, i) - bi, _ := dns.PrevLabel(b, i) + ai, oka := dns.PrevLabel(a, i) + bi, okb := dns.PrevLabel(b, i) + if oka && okb { + return 0 + } // sadly this []byte will allocate... ab := []byte(a[ai:aj]) toLowerAndDDD(ab) diff --git a/middleware/file/closest.go b/middleware/file/closest.go new file mode 100644 index 000000000..daee27314 --- /dev/null +++ b/middleware/file/closest.go @@ -0,0 +1,16 @@ +package file + +import "github.com/miekg/dns" + +// ClosestEncloser returns the closest encloser for rr. +func (z *Zone) ClosestEncloser(rr dns.RR) string { + elem := z.Tree.Prev(rr) + if elem == nil { + // SOA? + return "" + } + for _, r := range elem.All() { + return r.Header().Name + } + return "" +} diff --git a/middleware/file/closest_test.go b/middleware/file/closest_test.go new file mode 100644 index 000000000..643e4943f --- /dev/null +++ b/middleware/file/closest_test.go @@ -0,0 +1,34 @@ +package file + +import ( + "strings" + "testing" + + "github.com/miekg/dns" +) + +func TestClosestEncloser(t *testing.T) { + z, err := Parse(strings.NewReader(dbMiekNL), testzone, "stdin") + if err != nil { + t.Fatalf("expect no error when reading zone, got %q", err) + } + + tests := []struct { + in, out string + }{ + {"miek.nl.", "miek.nl."}, + {"blaat.miek.nl.", "miek.nl."}, + {"blaat.blaat.miek.nl.", "miek.nl."}, + {"blaat.a.miek.nl.", "archive.miek.nl."}, + } + + mk, _ := dns.TypeToRR[dns.TypeA] + rr := mk() + for _, tc := range tests { + rr.Header().Name = tc.in + ce := z.ClosestEncloser(rr) + if ce != tc.out { + t.Errorf("expected ce to be %s for %s, got %s", tc.out, tc.in, ce) + } + } +} diff --git a/middleware/file/dnssec_test.go b/middleware/file/dnssec_test.go index 96eff6660..ed8b6a607 100644 --- a/middleware/file/dnssec_test.go +++ b/middleware/file/dnssec_test.go @@ -61,9 +61,10 @@ var dnssecTestCases = []coretest.Case{ }, }, { - Qname: "b.miek.nl.", Qtype: dns.TypeA, // Do: true, // need sorting first + Qname: "b.miek.nl.", Qtype: dns.TypeA, Do: true, Rcode: dns.RcodeNameError, Ns: []dns.RR{ + coretest.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="), coretest.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"), }, }, diff --git a/middleware/file/lookup.go b/middleware/file/lookup.go index 3d3de9679..10f308cf1 100644 --- a/middleware/file/lookup.go +++ b/middleware/file/lookup.go @@ -2,6 +2,7 @@ package file import ( "github.com/miekg/coredns/middleware/file/tree" + "github.com/miekg/dns" ) diff --git a/middleware/file/tree/tree.go b/middleware/file/tree/tree.go index 342bcefa8..05dfdfa7d 100644 --- a/middleware/file/tree/tree.go +++ b/middleware/file/tree/tree.go @@ -17,8 +17,7 @@ package tree // TODO(miek): fix docs import ( - "strings" - + "github.com/miekg/coredns/middleware" "github.com/miekg/dns" ) @@ -112,21 +111,11 @@ func (e *Elem) Delete(rr dns.RR) (empty bool) { return } -// TODO(miek): need case ignore compare that is more efficient. func Less(a *Elem, rr dns.RR) int { - aname := "" - for _, ar := range a.m { - aname = strings.ToLower(ar[0].Header().Name) - break + for _, ar := range a.m { // Get first element in a + return middleware.Less(ar[0].Header().Name, rr.Header().Name) } - rname := strings.ToLower(rr.Header().Name) - if aname == rname { - return 0 - } - if aname < rname { - return -1 - } - return 1 + return 0 } // Assuming the same type and name this will check if the rdata is equal as well.