adapt to v2 radix tree impl.

This commit is contained in:
Miek Gieben 2012-09-09 23:38:01 +02:00
parent 288bb6f812
commit d5e6aaba0b
2 changed files with 28 additions and 24 deletions

View File

@ -174,27 +174,21 @@ func (mux *ServeMux) match(zone string, t uint16) Handler {
if h, e := mux.m.Find(zone); e { if h, e := mux.m.Find(zone); e {
// If we got queried for a DS record, we must see if we // 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. // if we also serve the parent. We then redirect the query to it.
// TODO(mg): grandparents works too?
if t != TypeDS { if t != TypeDS {
return h.Value.(Handler) return h.Value.(Handler)
} }
if d := h.Up(); d != nil { if d := h.Up(); d != nil {
return d.Value.(Handler) return d.Value.(Handler)
} }
// No parent zone found, let the original handler take care of it
return h.Value.(Handler)
} else { } else {
if h == nil { if h == nil {
return nil return nil
} }
// Not an exact match and h may be nil and h.Value may be nil return h.Value.(Handler)
if h.Value != nil {
return h.Value.(Handler)
}
if d := h.Up(); d != nil {
return d.Value.(Handler)
}
} }
// Nothing found at all panic("dns: not reached")
return nil
} }
// Handle adds a handler to the ServeMux for pattern. // 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 // ServeDNS dispatches the request to the handler whose
// pattern most closely matches the request message. For DS queries // pattern most closely matches the request message. If DefaultServeMux
// a parent zone is sought. // 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 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) { func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) {
var h Handler var h Handler
if len(request.Question) != 1 { if len(request.Question) != 1 {

31
zone.go
View File

@ -68,7 +68,8 @@ type ZoneData struct {
RR map[uint16][]RR // Map of the RR type to the RR 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 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 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 // 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 // Find looks up the ownername s in the zone and returns the
// data when found or nil when nothing is found. // data and true when an exact match is found. If an exact find isn't
// We can do better here, and include NXDOMAIN also. Much more efficient, only // possible the first parent node with a non-nil Value is returned and
// 1 tree walk. // the boolean is false.
func (z *Zone) Find(s string) *ZoneData { func (z *Zone) Find(s string) (*ZoneData, bool) {
z.mutex.RLock() z.mutex.RLock()
defer z.mutex.RUnlock() defer z.mutex.RUnlock()
zd, e := z.Radix.Find(toRadixName(s)) zd, e := z.Radix.Find(toRadixName(s))
if !e { if zd == nil {
return nil return nil, false
} }
return zd.Value.(*ZoneData) return zd.Value.(*ZoneData), e
} }
// Predecessor searches the zone for a name shorter than s. // Up bla bla
func (z *Zone) Predecessor(s string) *ZoneData { func (z *Zone) Up(s string) *ZoneData {
z.mutex.RLock() z.mutex.RLock()
defer z.mutex.RUnlock() 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 { if zd == nil {
return 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) // Sign (re)signes the zone z. It adds keys to the zone (if not already there)