dns/server.go

424 lines
12 KiB
Go
Raw Normal View History

2011-02-08 20:25:01 +00:00
// Copyright 2011 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !appengine
// DNS server implementation.
2011-02-08 20:25:01 +00:00
package dns
2011-02-08 20:25:01 +00:00
import (
"net"
"sync"
2012-01-20 11:16:32 +00:00
"time"
2011-02-08 20:25:01 +00:00
)
2011-04-01 11:15:36 +00:00
type Handler interface {
2011-04-03 09:49:23 +00:00
ServeDNS(w ResponseWriter, r *Msg)
2011-04-01 11:15:36 +00:00
}
2011-04-03 09:14:54 +00:00
// A ResponseWriter interface is used by an DNS handler to
// construct an DNS response.
2011-04-02 07:22:05 +00:00
type ResponseWriter interface {
2011-07-05 19:08:22 +00:00
// RemoteAddr returns the net.Addr of the client that sent the current request.
2011-07-05 17:17:29 +00:00
RemoteAddr() net.Addr
// WriteMsg writes a reply back to the client.
WriteMsg(*Msg) error
// Write writes a raw buffer back to the client.
Write([]byte) (int, error)
2012-08-28 11:12:55 +00:00
// Close closes the connection.
Close() error
// TsigStatus returns the status of the Tsig.
2012-08-27 19:27:49 +00:00
TsigStatus() error
// TsigTimersOnly sets the tsig timers only boolean.
TsigTimersOnly(bool)
2012-08-28 17:41:23 +00:00
// Hijack lets the caller take over the connection.
// After a call to Hijack(), the DNS package will not do anything with the connection
Hijack()
2011-04-02 07:22:05 +00:00
}
type response struct {
2012-08-28 17:53:21 +00:00
hijacked bool // connection has been hijacked by handler
tsigStatus error
tsigTimersOnly bool
tsigRequestMAC string
tsigSecret map[string]string // the tsig secrets
2013-06-14 18:42:55 +00:00
udp *net.UDPConn // i/o connection if UDP was used
tcp *net.TCPConn // i/o connection if TCP was used
remoteAddr net.Addr // address of the client
2011-04-01 08:53:31 +00:00
}
2011-04-01 11:15:36 +00:00
// ServeMux is an DNS request multiplexer. It matches the
// zone name of each incoming request against a list of
2011-04-01 11:15:36 +00:00
// registered patterns add calls the handler for the pattern
2012-08-05 06:55:25 +00:00
// that most closely matches the zone name. ServeMux is DNSSEC aware, meaning
// that queries for the DS record are redirected to the parent zone (if that
2012-08-08 07:26:29 +00:00
// is also registered), otherwise the child gets the query.
2012-12-28 08:20:15 +00:00
// ServeMux is also safe for concurrent access from multiple goroutines.
2011-04-01 11:15:36 +00:00
type ServeMux struct {
z map[string]Handler
m *sync.RWMutex
2011-04-01 11:15:36 +00:00
}
2011-04-02 07:22:05 +00:00
// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux { return &ServeMux{z: make(map[string]Handler), m: new(sync.RWMutex)} }
2011-04-01 11:15:36 +00:00
2011-04-02 07:22:05 +00:00
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = NewServeMux()
2011-04-01 11:15:36 +00:00
2011-04-02 07:22:05 +00:00
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as DNS handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler object that calls f.
type HandlerFunc func(ResponseWriter, *Msg)
2011-04-01 11:15:36 +00:00
2011-07-05 19:08:22 +00:00
// ServerDNS calls f(w, r)
2011-04-02 07:22:05 +00:00
func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
2011-04-03 09:49:23 +00:00
f(w, r)
2011-04-01 11:15:36 +00:00
}
// FailedHandler returns a HandlerFunc
2012-09-03 10:54:18 +00:00
// returns SERVFAIL for every request it gets.
func HandleFailed(w ResponseWriter, r *Msg) {
2011-04-18 20:08:12 +00:00
m := new(Msg)
m.SetRcode(r, RcodeServerFailure)
2012-09-03 10:54:18 +00:00
// does not matter if this write fails
w.WriteMsg(m)
2011-04-03 11:43:46 +00:00
}
2011-04-01 11:15:36 +00:00
func failedHandler() Handler { return HandlerFunc(HandleFailed) }
2011-04-01 08:53:31 +00:00
2012-02-12 10:37:52 +00:00
// Start a server on addresss and network speficied. Invoke handler
2012-12-02 09:14:53 +00:00
// for incoming queries.
func ListenAndServe(addr string, network string, handler Handler) error {
server := &Server{Addr: addr, Net: network, Handler: handler}
2011-04-03 09:49:23 +00:00
return server.ListenAndServe()
2011-04-02 07:22:05 +00:00
}
func (mux *ServeMux) match(q string, t uint16) Handler {
mux.m.RLock()
defer mux.m.RUnlock()
2013-06-22 20:40:19 +00:00
var handler Handler
b := make([]byte, len(q)) // worst case, one label of length q
2013-06-22 20:40:19 +00:00
off := 0
end := false
for {
l := len(q[off:])
for i := 0; i < l; i++ {
2013-09-06 09:49:07 +00:00
b[i] = q[off+i] | ('a' - 'A')
}
if h, ok := mux.z[string(b[:l])]; ok { // 'causes garbage, might want to change the map key
2013-06-22 20:40:19 +00:00
if t != TypeDS {
return h
} else {
// Continue for DS to see if we have a parent too, if so delegeate to the parent
handler = h
}
2012-09-08 06:07:35 +00:00
}
2013-06-22 20:40:19 +00:00
off, end = NextLabel(q, off)
if end {
break
2012-09-08 06:07:35 +00:00
}
}
// Wildcard match, if we have found nothing try the root zone as a last resort.
2013-05-04 21:21:01 +00:00
if h, ok := mux.z["."]; ok {
return h
2012-08-05 03:35:30 +00:00
}
2013-05-04 21:21:01 +00:00
return handler
2011-04-01 11:15:36 +00:00
}
2012-05-08 12:17:17 +00:00
// Handle adds a handler to the ServeMux for pattern.
2011-04-01 11:15:36 +00:00
func (mux *ServeMux) Handle(pattern string, handler Handler) {
2011-04-03 09:49:23 +00:00
if pattern == "" {
panic("dns: invalid pattern " + pattern)
}
mux.m.Lock()
mux.z[Fqdn(pattern)] = handler
mux.m.Unlock()
2011-04-01 11:15:36 +00:00
}
2011-04-02 07:22:05 +00:00
2012-05-08 12:17:17 +00:00
// Handle adds a handler to the ServeMux for pattern.
2011-04-02 07:22:05 +00:00
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
2011-04-03 09:49:23 +00:00
mux.Handle(pattern, HandlerFunc(handler))
2011-04-02 07:22:05 +00:00
}
2012-05-08 12:17:17 +00:00
// HandleRemove deregistrars the handler specific for pattern from the ServeMux.
func (mux *ServeMux) HandleRemove(pattern string) {
if pattern == "" {
panic("dns: invalid pattern " + pattern)
}
2013-10-15 19:44:55 +00:00
// don't need a mutex here, because deleting is OK, even if the
// entry is note there.
delete(mux.z, Fqdn(pattern))
}
2011-04-02 07:22:05 +00:00
// ServeDNS dispatches the request to the handler whose
2012-09-09 21:38:01 +00:00
// 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
2012-09-09 21:38:01 +00:00
// If the request message does not have a single question in the
// question section a SERVFAIL is returned.
2011-04-02 07:22:05 +00:00
func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) {
var h Handler
if len(request.Question) != 1 {
2012-09-03 10:54:18 +00:00
h = failedHandler()
} else {
2012-08-28 11:30:59 +00:00
if h = mux.match(request.Question[0].Name, request.Question[0].Qtype); h == nil {
2012-09-03 10:54:18 +00:00
h = failedHandler()
}
2011-04-03 09:49:23 +00:00
}
h.ServeDNS(w, request)
2011-04-02 07:22:05 +00:00
}
// Handle registers the handler with the given pattern
2011-04-02 07:22:05 +00:00
// in the DefaultServeMux. The documentation for
2012-08-24 13:20:20 +00:00
// ServeMux explains how patterns are matched.
2011-04-02 07:22:05 +00:00
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
// HandleRemove deregisters the handle with the given pattern
// in the DefaultServeMux.
func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) }
2012-08-24 13:20:20 +00:00
// HandleFunc registers the handler function with the given pattern
// in the DefaultServeMux.
2011-04-02 07:22:05 +00:00
func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
2011-04-03 09:49:23 +00:00
DefaultServeMux.HandleFunc(pattern, handler)
2011-04-02 07:22:05 +00:00
}
2011-04-12 19:44:56 +00:00
// A Server defines parameters for running an DNS server.
type Server struct {
Addr string // address to listen on, ":dns" if empty
Net string // if "tcp" it will invoke a TCP listener, otherwise an UDP one
Handler Handler // handler to invoke, dns.DefaultServeMux if nil
UDPSize int // default buffer size to use to read incoming UDP messages
ReadTimeout time.Duration // the net.Conn.SetReadTimeout value for new connections
WriteTimeout time.Duration // the net.Conn.SetWriteTimeout value for new connections
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
IdleTimeout func() time.Duration // TCP idle timeout, see RFC 5966, if nil, default to 1 time.Minute
2011-04-12 19:44:56 +00:00
}
2012-05-08 12:17:17 +00:00
// ListenAndServe starts a nameserver on the configured address in *Server.
2011-11-02 22:06:54 +00:00
func (srv *Server) ListenAndServe() error {
2011-04-03 09:49:23 +00:00
addr := srv.Addr
if addr == "" {
addr = ":domain"
}
2011-04-18 20:08:12 +00:00
switch srv.Net {
2011-07-05 17:44:46 +00:00
case "tcp", "tcp4", "tcp6":
a, e := net.ResolveTCPAddr(srv.Net, addr)
2011-04-03 09:49:23 +00:00
if e != nil {
return e
}
2011-07-05 17:44:46 +00:00
l, e := net.ListenTCP(srv.Net, a)
2011-04-03 09:49:23 +00:00
if e != nil {
return e
}
2012-08-31 08:13:21 +00:00
return srv.serveTCP(l)
2011-07-05 17:44:46 +00:00
case "udp", "udp4", "udp6":
a, e := net.ResolveUDPAddr(srv.Net, addr)
2011-04-03 09:49:23 +00:00
if e != nil {
return e
}
2011-07-05 17:44:46 +00:00
l, e := net.ListenUDP(srv.Net, a)
2011-04-03 09:49:23 +00:00
if e != nil {
return e
}
2012-08-31 08:13:21 +00:00
return srv.serveUDP(l)
2011-04-03 09:49:23 +00:00
}
2013-06-20 06:27:28 +00:00
return &Error{err: "bad network"}
2011-04-02 07:22:05 +00:00
}
2012-08-31 08:13:21 +00:00
// serveTCP starts a TCP listener for the server.
2012-02-15 12:16:09 +00:00
// Each request is handled in a seperate goroutine.
2012-08-31 08:13:21 +00:00
func (srv *Server) serveTCP(l *net.TCPListener) error {
2011-04-03 09:49:23 +00:00
defer l.Close()
handler := srv.Handler
if handler == nil {
handler = DefaultServeMux
}
forever:
for {
rw, e := l.AcceptTCP()
if e != nil {
// don't bail out, but wait for a new request
continue
2011-04-03 09:49:23 +00:00
}
if srv.ReadTimeout != 0 {
2012-01-20 11:16:32 +00:00
rw.SetReadDeadline(time.Now().Add(srv.ReadTimeout))
2011-04-03 09:49:23 +00:00
}
if srv.WriteTimeout != 0 {
2012-01-20 11:16:32 +00:00
rw.SetWriteDeadline(time.Now().Add(srv.WriteTimeout))
2011-04-03 09:49:23 +00:00
}
l := make([]byte, 2)
n, err := rw.Read(l)
if err != nil || n != 2 {
continue
}
length, _ := unpackUint16(l, 0)
if length == 0 {
continue
}
m := make([]byte, int(length))
n, err = rw.Read(m[:int(length)])
if err != nil || n == 0 {
2011-04-03 09:49:23 +00:00
continue
}
i := n
for i < int(length) {
j, err := rw.Read(m[i:int(length)])
if err != nil {
continue forever
}
i += j
}
n = i
go serve(rw.RemoteAddr(), handler, m, nil, rw, srv.TsigSecret)
2011-04-03 09:49:23 +00:00
}
panic("dns: not reached")
2011-04-02 07:22:05 +00:00
}
2012-08-31 08:13:21 +00:00
// serveUDP starts a UDP listener for the server.
2012-08-21 14:52:36 +00:00
// Each request is handled in a seperate goroutine.
2012-08-31 08:13:21 +00:00
func (srv *Server) serveUDP(l *net.UDPConn) error {
2011-04-03 09:49:23 +00:00
defer l.Close()
handler := srv.Handler
if handler == nil {
handler = DefaultServeMux
}
2012-01-12 21:47:36 +00:00
if srv.UDPSize == 0 {
srv.UDPSize = MinMsgSize
2012-01-12 21:47:36 +00:00
}
2011-04-03 09:49:23 +00:00
for {
if srv.ReadTimeout != 0 {
l.SetReadDeadline(time.Now().Add(srv.ReadTimeout))
}
if srv.WriteTimeout != 0 {
l.SetWriteDeadline(time.Now().Add(srv.WriteTimeout))
}
2012-01-12 21:34:53 +00:00
m := make([]byte, srv.UDPSize)
2011-04-03 09:49:23 +00:00
n, a, e := l.ReadFromUDP(m)
if e != nil || n == 0 {
// don't bail out, but wait for a new request
continue
2011-04-03 09:49:23 +00:00
}
m = m[:n]
go serve(a, handler, m, l, nil, srv.TsigSecret)
2011-04-03 09:49:23 +00:00
}
panic("dns: not reached")
2011-04-02 07:22:05 +00:00
}
2011-04-03 09:14:54 +00:00
// Serve a new connection.
func serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, t *net.TCPConn, tsigSecret map[string]string) {
// Request has been read in serveUDP or serveTCP
w := &response{tsigSecret: tsigSecret, udp: u, tcp: t, remoteAddr: a}
req := new(Msg)
if req.Unpack(m) != nil {
// Send a format error back
x := new(Msg)
x.SetRcodeFormatError(req)
w.WriteMsg(x)
w.Close()
return
}
defer func() {
2012-08-31 13:10:43 +00:00
if w.hijacked {
2012-08-28 17:46:29 +00:00
// client takes care of the connection, i.e. calls Close()
return
2011-04-18 20:08:12 +00:00
}
w.Close()
}()
w.tsigStatus = nil
if w.tsigSecret != nil {
if t := req.IsTsig(); t != nil {
secret := t.Hdr.Name
if _, ok := tsigSecret[secret]; !ok {
w.tsigStatus = ErrKeyAlg
}
w.tsigStatus = TsigVerify(m, tsigSecret[secret], "", false)
w.tsigTimersOnly = false
w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC
}
2011-04-18 20:08:12 +00:00
}
h.ServeDNS(w, req) // this does the writing back to the client
return
2011-04-02 07:22:05 +00:00
}
// WriteMsg implements the ResponseWriter.WriteMsg method.
func (w *response) WriteMsg(m *Msg) (err error) {
var data []byte
if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check)
if t := m.IsTsig(); t != nil {
data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly)
if err != nil {
return err
}
_, err = w.Write(data)
2012-11-18 11:05:18 +00:00
return err
}
}
data, err = m.Pack()
if err != nil {
return err
}
_, err = w.Write(data)
2012-11-18 11:05:18 +00:00
return err
2011-04-03 09:49:23 +00:00
}
2011-04-03 09:14:54 +00:00
// Write implements the ResponseWriter.Write method.
func (w *response) Write(m []byte) (int, error) {
2012-08-05 19:15:15 +00:00
switch {
case w.udp != nil:
n, err := w.udp.WriteTo(m, w.remoteAddr)
2012-11-18 11:05:18 +00:00
return n, err
case w.tcp != nil:
2012-11-18 11:05:18 +00:00
lm := len(m)
2012-08-05 19:15:15 +00:00
if len(m) > MaxMsgSize {
2013-06-20 06:27:28 +00:00
return 0, &Error{err: "message too large"}
2012-08-05 19:15:15 +00:00
}
l := make([]byte, 2)
2012-11-18 11:05:18 +00:00
l[0], l[1] = packUint16(uint16(lm))
m = append(l, m...)
n, err := w.tcp.Write(m)
2012-08-05 19:15:15 +00:00
if err != nil {
2012-11-18 11:05:18 +00:00
return n, err
2012-08-05 19:15:15 +00:00
}
i := n
2012-11-18 11:05:18 +00:00
if i < lm {
j, err := w.tcp.Write(m[i:lm])
2012-08-05 19:15:15 +00:00
if err != nil {
2012-11-18 11:05:18 +00:00
return i, err
2012-08-05 19:15:15 +00:00
}
i += j
}
2012-10-10 19:09:11 +00:00
n = i
2012-11-18 11:05:18 +00:00
return i, nil
2012-08-05 19:15:15 +00:00
}
2012-11-18 11:05:18 +00:00
panic("not reached")
2012-08-05 19:15:15 +00:00
}
2012-08-08 07:26:29 +00:00
// RemoteAddr implements the ResponseWriter.RemoteAddr method.
func (w *response) RemoteAddr() net.Addr { return w.remoteAddr }
2012-02-26 20:33:50 +00:00
2012-08-08 07:26:29 +00:00
// TsigStatus implements the ResponseWriter.TsigStatus method.
2012-05-04 21:18:29 +00:00
func (w *response) TsigStatus() error { return w.tsigStatus }
2012-08-27 19:27:49 +00:00
// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method.
func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b }
2012-08-28 11:12:55 +00:00
2012-08-28 17:41:23 +00:00
// Hijack implements the ResponseWriter.Hijack method.
func (w *response) Hijack() { w.hijacked = true }
2012-08-28 11:12:55 +00:00
// Close implements the ResponseWriter.Close method
func (w *response) Close() error {
// Can't close the udp conn, as that is actually the listener.
if w.tcp != nil {
e := w.tcp.Close()
w.tcp = nil
2012-08-28 11:12:55 +00:00
return e
}
return nil
}