Remove the radix.Radix dependency

Put everything in maps. This removes to a major dependency and
makes Go DNS only depend on the core Go packages. This will
probably also be faster than the current setup -- although this
needs to be benchmarked.
This commit is contained in:
Miek Gieben 2013-05-04 22:28:44 +02:00
parent cb4c191bd3
commit 45775dff76
1 changed files with 38 additions and 26 deletions

View File

@ -7,7 +7,6 @@
package dns
import (
"github.com/miekg/radix"
"net"
"sync"
"time"
@ -56,12 +55,12 @@ type response struct {
// is also registered), otherwise the child gets the query.
// ServeMux is also safe for concurrent access from multiple goroutines.
type ServeMux struct {
r *radix.Radix
z map[string]Handler
m *sync.RWMutex
}
// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux { return &ServeMux{r: radix.New(), m: new(sync.RWMutex)} }
func NewServeMux() *ServeMux { return &ServeMux{z: make(map[string]Handler), m: new(sync.RWMutex)} }
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = NewServeMux()
@ -70,7 +69,7 @@ var DefaultServeMux = NewServeMux()
var Authors = []string{"Miek Gieben", "Ask Bjørn Hansen", "Dave Cheney", "Dusty Wilson", "Peter van Dijk"}
// Version holds the current version.
var Version = "v1.0"
var Version = "v1.1"
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as DNS handlers. If f is a function
@ -165,28 +164,41 @@ func ListenAndServe(addr string, network string, handler Handler) error {
return server.ListenAndServe()
}
func (mux *ServeMux) match(zone string, t uint16) Handler {
func (mux *ServeMux) match(q string, t uint16) Handler {
mux.m.RLock()
defer mux.m.RUnlock()
if h, e := mux.r.Find(toRadixName(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.
var (
handler Handler
lastdot int
lastbyte byte
seendot bool = true
)
// TODO(mg): check for .
for i := 0; i < len(q); i++ {
if seendot {
if h, ok := mux.z[q[lastdot:]]; ok {
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)
return h
} else {
if h == nil {
// Continue for DS to see if we have a parent too, if so delegeate to the parent
handler = h
}
}
}
if q[i] == '.' && lastbyte != '\\' {
lastdot = i
seendot = true
} else {
seendot = false
}
lastbyte = q[i]
}
if handler != nil {
return handler
}
return nil
}
return h.Value.(Handler)
}
panic("dns: not reached")
}
// Handle adds a handler to the ServeMux for pattern.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
@ -194,7 +206,7 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
panic("dns: invalid pattern " + pattern)
}
mux.m.Lock()
mux.r.Insert(toRadixName(Fqdn(pattern)), handler)
mux.z[Fqdn(pattern)] = handler
mux.m.Unlock()
}
@ -209,7 +221,7 @@ func (mux *ServeMux) HandleRemove(pattern string) {
panic("dns: invalid pattern " + pattern)
}
mux.m.Lock()
mux.r.Remove(toRadixName(Fqdn(pattern)))
delete(mux.z, Fqdn(pattern))
mux.m.Unlock()
}