From d5e6aaba0bfc1f03bd9e11ceb64edeb986a7ad8b Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 9 Sep 2012 23:38:01 +0200 Subject: [PATCH] adapt to v2 radix tree impl. --- server.go | 21 +++++++++------------ zone.go | 31 +++++++++++++++++++------------ 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/server.go b/server.go index f7af9f71..34a58338 100644 --- a/server.go +++ b/server.go @@ -174,27 +174,21 @@ func (mux *ServeMux) match(zone string, t uint16) Handler { if h, e := mux.m.Find(zone); e { // If we got queried for a DS record, we must see if we // if we also serve the parent. We then redirect the query to it. - // TODO(mg): grandparents works too? if t != TypeDS { return h.Value.(Handler) } if d := h.Up(); d != nil { return d.Value.(Handler) } + // No parent zone found, let the original handler take care of it + return h.Value.(Handler) } else { if h == nil { return nil } - // Not an exact match and h may be nil and h.Value may be nil - if h.Value != nil { - return h.Value.(Handler) - } - if d := h.Up(); d != nil { - return d.Value.(Handler) - } + return h.Value.(Handler) } - // Nothing found at all - return nil + panic("dns: not reached") } // Handle adds a handler to the ServeMux for pattern. @@ -220,9 +214,12 @@ func (mux *ServeMux) HandleRemove(pattern string) { } // ServeDNS dispatches the request to the handler whose -// pattern most closely matches the request message. For DS queries -// a parent zone is sought. +// pattern most closely matches the request message. If DefaultServeMux +// is used the correct thing for DS queries is done: a possible parent +// is sought. // If no handler is found a standard SERVFAIL message is returned +// If the request message does not have a single question in the +// question section a SERVFAIL is returned. func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) { var h Handler if len(request.Question) != 1 { diff --git a/zone.go b/zone.go index ad7ac404..50ed0d55 100644 --- a/zone.go +++ b/zone.go @@ -68,7 +68,8 @@ type ZoneData struct { RR map[uint16][]RR // Map of the RR type to the RR Signatures map[uint16][]*RR_RRSIG // DNSSEC signatures for the RRs, stored under type covered NonAuth bool // Always false, except for NSsets that differ from z.Origin - mutex *sync.RWMutex + mutex *sync.RWMutex // For locking + radix *radix.Radix // The actual radix node belonging to this value } // newZoneData creates a new zone data element @@ -199,28 +200,34 @@ func (z *Zone) Remove(r RR) error { } // Find looks up the ownername s in the zone and returns the -// data when found or nil when nothing is found. -// We can do better here, and include NXDOMAIN also. Much more efficient, only -// 1 tree walk. -func (z *Zone) Find(s string) *ZoneData { +// data and true when an exact match is found. If an exact find isn't +// possible the first parent node with a non-nil Value is returned and +// the boolean is false. +func (z *Zone) Find(s string) (*ZoneData, bool) { z.mutex.RLock() defer z.mutex.RUnlock() zd, e := z.Radix.Find(toRadixName(s)) - if !e { - return nil + if zd == nil { + return nil, false } - return zd.Value.(*ZoneData) + return zd.Value.(*ZoneData), e } -// Predecessor searches the zone for a name shorter than s. -func (z *Zone) Predecessor(s string) *ZoneData { +// Up bla bla +func (z *Zone) Up(s string) *ZoneData { z.mutex.RLock() defer z.mutex.RUnlock() - zd := z.Radix.Predecessor(toRadixName(s)) + // Another find... + zd, _ := z.Radix.Find(toRadixName(s)) + // TODO(mg): what about exact?? if zd == nil { return nil } - return zd.Value.(*ZoneData) + zd1 := zd.Up() + if zd1 == nil { + return nil + } + return zd1.Value.(*ZoneData) } // Sign (re)signes the zone z. It adds keys to the zone (if not already there)