Fix closest encloser
This commit is contained in:
parent
bf6d90600b
commit
8feef98188
4 changed files with 58 additions and 17 deletions
|
@ -8,10 +8,10 @@ import (
|
||||||
|
|
||||||
// Less returns <0 when a is less than b, 0 when they are equal and
|
// Less returns <0 when a is less than b, 0 when they are equal and
|
||||||
// >0 when a is larger than b.
|
// >0 when a is larger than b.
|
||||||
// The function order names in DNSSEC canonical order.
|
// The function orders names in DNSSEC canonical order: RFC 4034s section-6.1
|
||||||
//
|
//
|
||||||
// See http://bert-hubert.blogspot.co.uk/2015/10/how-to-do-fast-canonical-ordering-of.html
|
// See http://bert-hubert.blogspot.co.uk/2015/10/how-to-do-fast-canonical-ordering-of.html
|
||||||
// for a blog article on how we do this. And https://tools.ietf.org/html/rfc4034#section-6.1 .
|
// for a blog article on this implementation:
|
||||||
func Less(a, b string) int {
|
func Less(a, b string) int {
|
||||||
i := 1
|
i := 1
|
||||||
aj := len(a)
|
aj := len(a)
|
||||||
|
|
|
@ -4,13 +4,19 @@ import "github.com/miekg/dns"
|
||||||
|
|
||||||
// ClosestEncloser returns the closest encloser for rr.
|
// ClosestEncloser returns the closest encloser for rr.
|
||||||
func (z *Zone) ClosestEncloser(rr dns.RR) string {
|
func (z *Zone) ClosestEncloser(rr dns.RR) string {
|
||||||
elem := z.Tree.Prev(rr)
|
// tree/tree.go does not store a parent *Node pointer, so we can't
|
||||||
if elem == nil {
|
// just follow up the tree. TODO(miek): fix.
|
||||||
// SOA?
|
|
||||||
return ""
|
offset, end := dns.NextLabel(rr.Header().Name, 0)
|
||||||
|
for !end {
|
||||||
|
elem := z.Tree.Get(rr)
|
||||||
|
if elem != nil {
|
||||||
|
return elem.Name()
|
||||||
|
}
|
||||||
|
rr.Header().Name = rr.Header().Name[offset:]
|
||||||
|
|
||||||
|
offset, end = dns.NextLabel(rr.Header().Name, offset)
|
||||||
}
|
}
|
||||||
for _, r := range elem.All() {
|
|
||||||
return r.Header().Name
|
return z.SOA.Header().Name
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,12 @@ func TestClosestEncloser(t *testing.T) {
|
||||||
in, out string
|
in, out string
|
||||||
}{
|
}{
|
||||||
{"miek.nl.", "miek.nl."},
|
{"miek.nl.", "miek.nl."},
|
||||||
|
{"www.miek.nl.", "www.miek.nl."},
|
||||||
|
|
||||||
{"blaat.miek.nl.", "miek.nl."},
|
{"blaat.miek.nl.", "miek.nl."},
|
||||||
{"blaat.blaat.miek.nl.", "miek.nl."},
|
{"blaat.www.miek.nl.", "www.miek.nl."},
|
||||||
{"blaat.a.miek.nl.", "archive.miek.nl."},
|
{"www.blaat.miek.nl.", "miek.nl."},
|
||||||
|
{"blaat.a.miek.nl.", "a.miek.nl."},
|
||||||
}
|
}
|
||||||
|
|
||||||
mk, _ := dns.TypeToRR[dns.TypeA]
|
mk, _ := dns.TypeToRR[dns.TypeA]
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// Heavily modified by Miek Gieben for use in DNS zones.
|
// Heavily modified by Miek Gieben for use in DNS zones.
|
||||||
package tree
|
package tree
|
||||||
|
|
||||||
// TODO(miek): locking? lockfree
|
// TODO(miek): locking? lockfree would be nice. Will probably go for fine grained locking on the name level.
|
||||||
// TODO(miek): fix docs
|
// TODO(miek): fix docs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -64,6 +64,14 @@ func (e *Elem) All() []dns.RR {
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the domain name for this element.
|
||||||
|
func (e *Elem) Name() string {
|
||||||
|
for _, rrs := range e.m {
|
||||||
|
return rrs[0].Header().Name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// Insert inserts rr into e. If rr is equal to existing rrs this is a noop.
|
// Insert inserts rr into e. If rr is equal to existing rrs this is a noop.
|
||||||
func (e *Elem) Insert(rr dns.RR) {
|
func (e *Elem) Insert(rr dns.RR) {
|
||||||
t := rr.Header().Rrtype
|
t := rr.Header().Rrtype
|
||||||
|
@ -112,10 +120,7 @@ func (e *Elem) Delete(rr dns.RR) (empty bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Less(a *Elem, rr dns.RR) int {
|
func Less(a *Elem, rr dns.RR) int {
|
||||||
for _, ar := range a.m { // Get first element in a
|
return middleware.Less(rr.Header().Name, a.Name())
|
||||||
return middleware.Less(ar[0].Header().Name, rr.Header().Name)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assuming the same type and name this will check if the rdata is equal as well.
|
// Assuming the same type and name this will check if the rdata is equal as well.
|
||||||
|
@ -539,6 +544,33 @@ func (n *Node) ceil(rr dns.RR) *Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do performs fn on all values stored in the tree. A boolean is returned indicating whether the
|
||||||
|
// Do traversal was interrupted by an Operation returning true. If fn alters stored values' sort
|
||||||
|
// relationships, future tree operation behaviors are undefined.
|
||||||
|
func (t *Tree) Do(fn func(e *Elem) bool) bool {
|
||||||
|
if t.Root == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return t.Root.do(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) do(fn func(e *Elem) bool) (done bool) {
|
||||||
|
if n.Left != nil {
|
||||||
|
done = n.Left.do(fn)
|
||||||
|
if done {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done = fn(n.Elem)
|
||||||
|
if done {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if n.Right != nil {
|
||||||
|
done = n.Right.do(fn)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright ©2012 The bíogo Authors. All rights reserved.
|
Copyright ©2012 The bíogo Authors. All rights reserved.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue