2011-03-28 08:01:10 +00:00
|
|
|
// DNS server implementation.
|
2011-02-08 20:25:01 +00:00
|
|
|
|
2011-02-08 20:26:40 +00:00
|
|
|
package dns
|
2011-02-08 20:25:01 +00:00
|
|
|
|
|
|
|
import (
|
2018-09-13 13:36:28 +00:00
|
|
|
"context"
|
2016-01-08 13:26:13 +00:00
|
|
|
"crypto/tls"
|
2016-06-08 15:38:42 +00:00
|
|
|
"encoding/binary"
|
2018-09-10 10:42:54 +00:00
|
|
|
"errors"
|
2014-01-03 23:19:35 +00:00
|
|
|
"io"
|
2011-02-08 20:25:01 +00:00
|
|
|
"net"
|
2018-09-10 10:42:54 +00:00
|
|
|
"strings"
|
2012-12-28 08:19:37 +00:00
|
|
|
"sync"
|
2012-01-20 11:16:32 +00:00
|
|
|
"time"
|
2011-02-08 20:25:01 +00:00
|
|
|
)
|
|
|
|
|
2018-05-14 19:12:20 +00:00
|
|
|
// Default maximum number of TCP queries before we close the socket.
|
2015-08-31 16:40:56 +00:00
|
|
|
const maxTCPQueries = 128
|
|
|
|
|
2018-09-13 13:36:28 +00:00
|
|
|
// aLongTimeAgo is a non-zero time, far in the past, used for
|
2023-01-14 07:19:09 +00:00
|
|
|
// immediate cancellation of network operations.
|
2018-09-13 13:36:28 +00:00
|
|
|
var aLongTimeAgo = time.Unix(1, 0)
|
|
|
|
|
2015-02-19 09:58:33 +00:00
|
|
|
// Handler is implemented by any value that implements ServeDNS.
|
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
|
|
|
}
|
|
|
|
|
2018-09-26 09:20:48 +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)
|
|
|
|
|
|
|
|
// ServeDNS calls f(w, r).
|
|
|
|
func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
|
|
|
|
f(w, r)
|
|
|
|
}
|
|
|
|
|
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 {
|
2014-07-27 17:43:07 +00:00
|
|
|
// LocalAddr returns the net.Addr of the server
|
|
|
|
LocalAddr() net.Addr
|
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
|
2012-11-18 11:21:02 +00:00
|
|
|
// 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
|
2013-05-04 20:28:44 +00:00
|
|
|
// 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.
|
2014-08-18 21:06:29 +00:00
|
|
|
// After a call to Hijack(), the DNS package will not do anything with the connection.
|
2012-08-28 17:41:23 +00:00
|
|
|
Hijack()
|
2011-04-02 07:22:05 +00:00
|
|
|
}
|
|
|
|
|
2018-09-22 17:34:55 +00:00
|
|
|
// A ConnectionStater interface is used by a DNS Handler to access TLS connection state
|
|
|
|
// when available.
|
|
|
|
type ConnectionStater interface {
|
|
|
|
ConnectionState() *tls.ConnectionState
|
|
|
|
}
|
|
|
|
|
2011-04-02 07:22:05 +00:00
|
|
|
type response struct {
|
2018-11-03 09:44:07 +00:00
|
|
|
closed bool // connection has been closed
|
2012-08-28 17:53:21 +00:00
|
|
|
hijacked bool // connection has been hijacked by handler
|
2012-03-04 20:00:09 +00:00
|
|
|
tsigTimersOnly bool
|
Fix dominikh/go-tools nits (#758)
* Remove unused functions and consts
* Address gosimple nits
* Address staticcheck nits
This excludes several that were intentional or weren't actual errors.
* Reduce size of lex struct
This reduces the size of the lex struct by 8 bytes from:
lex.token string: 0-16 (size 16, align 8)
lex.tokenUpper string: 16-32 (size 16, align 8)
lex.length int: 32-40 (size 8, align 8)
lex.err bool: 40-41 (size 1, align 1)
lex.value uint8: 41-42 (size 1, align 1)
padding: 42-48 (size 6, align 0)
lex.line int: 48-56 (size 8, align 8)
lex.column int: 56-64 (size 8, align 8)
lex.torc uint16: 64-66 (size 2, align 2)
padding: 66-72 (size 6, align 0)
lex.comment string: 72-88 (size 16, align 8)
to:
lex.token string: 0-16 (size 16, align 8)
lex.tokenUpper string: 16-32 (size 16, align 8)
lex.length int: 32-40 (size 8, align 8)
lex.err bool: 40-41 (size 1, align 1)
lex.value uint8: 41-42 (size 1, align 1)
lex.torc uint16: 42-44 (size 2, align 2)
padding: 44-48 (size 4, align 0)
lex.line int: 48-56 (size 8, align 8)
lex.column int: 56-64 (size 8, align 8)
lex.comment string: 64-80 (size 16, align 8)
* Reduce size of response struct
This reduces the size of the response struct by 8 bytes from:
response.msg []byte: 0-24 (size 24, align 8)
response.hijacked bool: 24-25 (size 1, align 1)
padding: 25-32 (size 7, align 0)
response.tsigStatus error: 32-48 (size 16, align 8)
response.tsigTimersOnly bool: 48-49 (size 1, align 1)
padding: 49-56 (size 7, align 0)
response.tsigRequestMAC string: 56-72 (size 16, align 8)
response.tsigSecret map[string]string: 72-80 (size 8, align 8)
response.udp *net.UDPConn: 80-88 (size 8, align 8)
response.tcp net.Conn: 88-104 (size 16, align 8)
response.udpSession *github.com/tmthrgd/dns.SessionUDP: 104-112 (size 8, align 8)
response.writer github.com/tmthrgd/dns.Writer: 112-128 (size 16, align 8)
response.wg *sync.WaitGroup: 128-136 (size 8, align 8)
to:
response.msg []byte: 0-24 (size 24, align 8)
response.hijacked bool: 24-25 (size 1, align 1)
response.tsigTimersOnly bool: 25-26 (size 1, align 1)
padding: 26-32 (size 6, align 0)
response.tsigStatus error: 32-48 (size 16, align 8)
response.tsigRequestMAC string: 48-64 (size 16, align 8)
response.tsigSecret map[string]string: 64-72 (size 8, align 8)
response.udp *net.UDPConn: 72-80 (size 8, align 8)
response.tcp net.Conn: 80-96 (size 16, align 8)
response.udpSession *github.com/tmthrgd/dns.SessionUDP: 96-104 (size 8, align 8)
response.writer github.com/tmthrgd/dns.Writer: 104-120 (size 16, align 8)
response.wg *sync.WaitGroup: 120-128 (size 8, align 8)
2018-09-26 18:32:05 +00:00
|
|
|
tsigStatus error
|
2012-03-04 20:00:09 +00:00
|
|
|
tsigRequestMAC string
|
2022-02-05 00:23:49 +00:00
|
|
|
tsigProvider TsigProvider
|
|
|
|
udp net.PacketConn // i/o connection if UDP was used
|
|
|
|
tcp net.Conn // i/o connection if TCP was used
|
|
|
|
udpSession *SessionUDP // oob data to get egress interface right
|
|
|
|
pcSession net.Addr // address to use when writing to a generic net.PacketConn
|
|
|
|
writer Writer // writer to output the raw DNS bits
|
2011-04-01 08:53:31 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 06:41:45 +00:00
|
|
|
// handleRefused returns a HandlerFunc that returns REFUSED for every request it gets.
|
|
|
|
func handleRefused(w ResponseWriter, r *Msg) {
|
|
|
|
m := new(Msg)
|
|
|
|
m.SetRcode(r, RcodeRefused)
|
|
|
|
w.WriteMsg(m)
|
|
|
|
}
|
|
|
|
|
2015-02-19 09:58:33 +00:00
|
|
|
// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets.
|
2020-08-20 06:41:45 +00:00
|
|
|
// Deprecated: This function is going away.
|
2012-09-03 10:54:18 +00:00
|
|
|
func HandleFailed(w ResponseWriter, r *Msg) {
|
2011-04-18 20:08:12 +00:00
|
|
|
m := new(Msg)
|
2012-08-03 15:38:41 +00:00
|
|
|
m.SetRcode(r, RcodeServerFailure)
|
2012-09-03 10:54:18 +00:00
|
|
|
// does not matter if this write fails
|
2012-11-18 11:21:02 +00:00
|
|
|
w.WriteMsg(m)
|
2011-04-03 11:43:46 +00:00
|
|
|
}
|
2011-04-01 11:15:36 +00:00
|
|
|
|
2016-01-08 15:20:22 +00:00
|
|
|
// ListenAndServe Starts a server on address and network specified Invoke handler
|
2012-12-02 09:14:53 +00:00
|
|
|
// for incoming queries.
|
2012-01-27 07:45:33 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2016-01-11 10:40:14 +00:00
|
|
|
// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in
|
|
|
|
// http://golang.org/pkg/net/http/#ListenAndServeTLS
|
2016-01-08 15:20:22 +00:00
|
|
|
func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
|
|
|
|
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
config := tls.Config{
|
|
|
|
Certificates: []tls.Certificate{cert},
|
|
|
|
}
|
|
|
|
|
|
|
|
server := &Server{
|
|
|
|
Addr: addr,
|
|
|
|
Net: "tcp-tls",
|
|
|
|
TLSConfig: &config,
|
|
|
|
Handler: handler,
|
|
|
|
}
|
|
|
|
|
|
|
|
return server.ListenAndServe()
|
|
|
|
}
|
|
|
|
|
2014-07-27 19:38:11 +00:00
|
|
|
// ActivateAndServe activates a server with a listener from systemd,
|
2014-07-22 07:27:59 +00:00
|
|
|
// l and p should not both be non-nil.
|
2014-07-21 14:24:55 +00:00
|
|
|
// If both l and p are not nil only p will be used.
|
2014-07-27 19:38:11 +00:00
|
|
|
// Invoke handler for incoming queries.
|
2014-07-21 14:24:55 +00:00
|
|
|
func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error {
|
|
|
|
server := &Server{Listener: l, PacketConn: p, Handler: handler}
|
|
|
|
return server.ActivateAndServe()
|
2014-07-18 19:32:17 +00:00
|
|
|
}
|
|
|
|
|
2015-08-06 21:55:37 +00:00
|
|
|
// Writer writes raw DNS messages; each call to Write should send an entire message.
|
2015-08-04 05:17:14 +00:00
|
|
|
type Writer interface {
|
|
|
|
io.Writer
|
|
|
|
}
|
|
|
|
|
2015-08-06 21:55:37 +00:00
|
|
|
// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message.
|
2015-08-04 05:17:14 +00:00
|
|
|
type Reader interface {
|
2015-08-06 21:55:37 +00:00
|
|
|
// ReadTCP reads a raw message from a TCP connection. Implementations may alter
|
2015-08-04 13:04:40 +00:00
|
|
|
// connection properties, for example the read-deadline.
|
2016-01-08 13:26:13 +00:00
|
|
|
ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error)
|
2015-08-06 21:55:37 +00:00
|
|
|
// ReadUDP reads a raw message from a UDP connection. Implementations may alter
|
2015-08-04 13:04:40 +00:00
|
|
|
// connection properties, for example the read-deadline.
|
2015-08-04 05:17:14 +00:00
|
|
|
ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error)
|
|
|
|
}
|
|
|
|
|
2020-10-24 15:53:01 +00:00
|
|
|
// PacketConnReader is an optional interface that Readers can implement to support using generic net.PacketConns.
|
|
|
|
type PacketConnReader interface {
|
|
|
|
Reader
|
|
|
|
|
|
|
|
// ReadPacketConn reads a raw message from a generic net.PacketConn UDP connection. Implementations may
|
|
|
|
// alter connection properties, for example the read-deadline.
|
|
|
|
ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// defaultReader is an adapter for the Server struct that implements the Reader and
|
|
|
|
// PacketConnReader interfaces using the readTCP, readUDP and readPacketConn funcs
|
|
|
|
// of the embedded Server.
|
2015-08-04 05:17:14 +00:00
|
|
|
type defaultReader struct {
|
|
|
|
*Server
|
|
|
|
}
|
|
|
|
|
2020-10-24 15:53:01 +00:00
|
|
|
var _ PacketConnReader = defaultReader{}
|
|
|
|
|
2019-01-04 08:09:23 +00:00
|
|
|
func (dr defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
|
2015-08-04 05:17:14 +00:00
|
|
|
return dr.readTCP(conn, timeout)
|
|
|
|
}
|
|
|
|
|
2019-01-04 08:09:23 +00:00
|
|
|
func (dr defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
|
2015-08-04 05:17:14 +00:00
|
|
|
return dr.readUDP(conn, timeout)
|
|
|
|
}
|
|
|
|
|
2020-10-24 15:53:01 +00:00
|
|
|
func (dr defaultReader) ReadPacketConn(conn net.PacketConn, timeout time.Duration) ([]byte, net.Addr, error) {
|
|
|
|
return dr.readPacketConn(conn, timeout)
|
|
|
|
}
|
|
|
|
|
2015-08-04 13:04:40 +00:00
|
|
|
// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader.
|
|
|
|
// Implementations should never return a nil Reader.
|
2020-10-24 15:56:19 +00:00
|
|
|
// Readers should also implement the optional PacketConnReader interface.
|
|
|
|
// PacketConnReader is required to use a generic net.PacketConn.
|
2015-08-04 13:04:40 +00:00
|
|
|
type DecorateReader func(Reader) Reader
|
2015-08-04 05:17:14 +00:00
|
|
|
|
2015-08-04 13:04:40 +00:00
|
|
|
// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer.
|
|
|
|
// Implementations should never return a nil Writer.
|
|
|
|
type DecorateWriter func(Writer) Writer
|
2015-08-04 05:17:14 +00:00
|
|
|
|
2011-04-12 19:44:56 +00:00
|
|
|
// A Server defines parameters for running an DNS server.
|
|
|
|
type Server struct {
|
2014-01-05 14:14:19 +00:00
|
|
|
// Address to listen on, ":dns" if empty.
|
|
|
|
Addr string
|
2016-01-08 13:26:13 +00:00
|
|
|
// if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one
|
2014-01-05 14:14:19 +00:00
|
|
|
Net string
|
2014-07-21 14:24:55 +00:00
|
|
|
// TCP Listener to use, this is to aid in systemd's socket activation.
|
|
|
|
Listener net.Listener
|
2016-01-08 13:26:13 +00:00
|
|
|
// TLS connection configuration
|
|
|
|
TLSConfig *tls.Config
|
2014-07-21 14:24:55 +00:00
|
|
|
// UDP "Listener" to use, this is to aid in systemd's socket activation.
|
|
|
|
PacketConn net.PacketConn
|
2014-01-05 14:14:19 +00:00
|
|
|
// Handler to invoke, dns.DefaultServeMux if nil.
|
|
|
|
Handler Handler
|
|
|
|
// Default buffer size to use to read incoming UDP messages. If not set
|
|
|
|
// it defaults to MinMsgSize (512 B).
|
|
|
|
UDPSize int
|
2014-08-18 21:14:29 +00:00
|
|
|
// The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second.
|
2014-01-05 14:14:19 +00:00
|
|
|
ReadTimeout time.Duration
|
2014-08-18 21:14:29 +00:00
|
|
|
// The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second.
|
2014-01-05 14:14:19 +00:00
|
|
|
WriteTimeout time.Duration
|
|
|
|
// TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
|
|
|
|
IdleTimeout func() time.Duration
|
2022-02-05 00:23:49 +00:00
|
|
|
// An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
|
|
|
|
TsigProvider TsigProvider
|
2017-11-17 13:17:47 +00:00
|
|
|
// Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2).
|
2014-01-05 14:14:19 +00:00
|
|
|
TsigSecret map[string]string
|
2015-08-09 14:34:29 +00:00
|
|
|
// If NotifyStartedFunc is set it is called once the server has started listening.
|
2014-12-12 12:17:39 +00:00
|
|
|
NotifyStartedFunc func()
|
2015-08-06 21:55:37 +00:00
|
|
|
// DecorateReader is optional, allows customization of the process that reads raw DNS messages.
|
2015-08-04 13:04:40 +00:00
|
|
|
DecorateReader DecorateReader
|
2015-08-06 21:55:37 +00:00
|
|
|
// DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
|
2015-08-04 13:04:40 +00:00
|
|
|
DecorateWriter DecorateWriter
|
2018-05-14 19:12:20 +00:00
|
|
|
// Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1).
|
|
|
|
MaxTCPQueries int
|
2018-09-10 10:42:54 +00:00
|
|
|
// Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address.
|
|
|
|
// It is only supported on go1.11+ and when using ListenAndServe.
|
|
|
|
ReusePort bool
|
2018-11-28 18:37:11 +00:00
|
|
|
// AcceptMsgFunc will check the incoming message and will reject it early in the process.
|
|
|
|
// By default DefaultMsgAcceptFunc will be used.
|
2018-11-27 10:43:01 +00:00
|
|
|
MsgAcceptFunc MsgAcceptFunc
|
2017-11-09 21:01:09 +00:00
|
|
|
|
2017-11-10 10:33:17 +00:00
|
|
|
// Shutdown handling
|
2018-09-13 13:36:28 +00:00
|
|
|
lock sync.RWMutex
|
|
|
|
started bool
|
|
|
|
shutdown chan struct{}
|
|
|
|
conns map[net.Conn]struct{}
|
2018-09-08 16:15:17 +00:00
|
|
|
|
|
|
|
// A pool for UDP message buffers.
|
|
|
|
udpPool sync.Pool
|
2011-04-12 19:44:56 +00:00
|
|
|
}
|
|
|
|
|
2022-02-05 00:23:49 +00:00
|
|
|
func (srv *Server) tsigProvider() TsigProvider {
|
|
|
|
if srv.TsigProvider != nil {
|
|
|
|
return srv.TsigProvider
|
|
|
|
}
|
|
|
|
if srv.TsigSecret != nil {
|
|
|
|
return tsigSecretProvider(srv.TsigSecret)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-07-28 12:47:30 +00:00
|
|
|
func (srv *Server) isStarted() bool {
|
|
|
|
srv.lock.RLock()
|
|
|
|
started := srv.started
|
|
|
|
srv.lock.RUnlock()
|
|
|
|
return started
|
|
|
|
}
|
|
|
|
|
2018-09-08 16:15:17 +00:00
|
|
|
func makeUDPBuffer(size int) func() interface{} {
|
|
|
|
return func() interface{} {
|
|
|
|
return make([]byte, size)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (srv *Server) init() {
|
2018-09-13 13:36:28 +00:00
|
|
|
srv.shutdown = make(chan struct{})
|
|
|
|
srv.conns = make(map[net.Conn]struct{})
|
|
|
|
|
2018-09-08 16:15:17 +00:00
|
|
|
if srv.UDPSize == 0 {
|
|
|
|
srv.UDPSize = MinMsgSize
|
|
|
|
}
|
2018-11-27 10:43:01 +00:00
|
|
|
if srv.MsgAcceptFunc == nil {
|
2019-03-07 07:02:29 +00:00
|
|
|
srv.MsgAcceptFunc = DefaultMsgAcceptFunc
|
2018-11-27 10:43:01 +00:00
|
|
|
}
|
2019-03-10 11:14:57 +00:00
|
|
|
if srv.Handler == nil {
|
|
|
|
srv.Handler = DefaultServeMux
|
|
|
|
}
|
2018-09-08 16:15:17 +00:00
|
|
|
|
|
|
|
srv.udpPool.New = makeUDPBuffer(srv.UDPSize)
|
|
|
|
}
|
|
|
|
|
2018-08-10 21:50:48 +00:00
|
|
|
func unlockOnce(l sync.Locker) func() {
|
|
|
|
var once sync.Once
|
|
|
|
return func() { once.Do(l.Unlock) }
|
|
|
|
}
|
|
|
|
|
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 {
|
2018-08-10 21:50:48 +00:00
|
|
|
unlock := unlockOnce(&srv.lock)
|
2017-11-09 21:01:09 +00:00
|
|
|
srv.lock.Lock()
|
2018-08-10 21:50:48 +00:00
|
|
|
defer unlock()
|
|
|
|
|
2017-11-09 21:01:09 +00:00
|
|
|
if srv.started {
|
|
|
|
return &Error{err: "server already started"}
|
|
|
|
}
|
2018-05-09 15:44:32 +00:00
|
|
|
|
2011-04-03 09:49:23 +00:00
|
|
|
addr := srv.Addr
|
|
|
|
if addr == "" {
|
|
|
|
addr = ":domain"
|
|
|
|
}
|
2018-09-08 16:15:17 +00:00
|
|
|
|
|
|
|
srv.init()
|
|
|
|
|
2011-04-18 20:08:12 +00:00
|
|
|
switch srv.Net {
|
2011-07-05 17:44:46 +00:00
|
|
|
case "tcp", "tcp4", "tcp6":
|
2018-09-10 10:42:54 +00:00
|
|
|
l, err := listenTCP(srv.Net, addr, srv.ReusePort)
|
2016-06-09 06:00:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2011-04-03 09:49:23 +00:00
|
|
|
}
|
2015-04-17 22:14:19 +00:00
|
|
|
srv.Listener = l
|
2017-11-09 21:01:09 +00:00
|
|
|
srv.started = true
|
2018-08-10 21:50:48 +00:00
|
|
|
unlock()
|
|
|
|
return srv.serveTCP(l)
|
2016-01-08 13:26:13 +00:00
|
|
|
case "tcp-tls", "tcp4-tls", "tcp6-tls":
|
2018-09-10 10:42:54 +00:00
|
|
|
if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) {
|
|
|
|
return errors.New("dns: neither Certificates nor GetCertificate set in Config")
|
2016-01-08 13:26:13 +00:00
|
|
|
}
|
2018-09-10 10:42:54 +00:00
|
|
|
network := strings.TrimSuffix(srv.Net, "-tls")
|
|
|
|
l, err := listenTCP(network, addr, srv.ReusePort)
|
2016-06-09 06:00:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2016-01-08 13:26:13 +00:00
|
|
|
}
|
2018-09-10 10:42:54 +00:00
|
|
|
l = tls.NewListener(l, srv.TLSConfig)
|
2016-01-08 13:26:13 +00:00
|
|
|
srv.Listener = l
|
2017-11-09 21:01:09 +00:00
|
|
|
srv.started = true
|
2018-08-10 21:50:48 +00:00
|
|
|
unlock()
|
|
|
|
return srv.serveTCP(l)
|
2011-07-05 17:44:46 +00:00
|
|
|
case "udp", "udp4", "udp6":
|
2018-09-10 10:42:54 +00:00
|
|
|
l, err := listenUDP(srv.Net, addr, srv.ReusePort)
|
2016-06-09 06:00:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2011-04-03 09:49:23 +00:00
|
|
|
}
|
2018-09-10 10:42:54 +00:00
|
|
|
u := l.(*net.UDPConn)
|
|
|
|
if e := setUDPSocketOptions(u); e != nil {
|
2021-02-25 08:24:39 +00:00
|
|
|
u.Close()
|
2014-07-07 15:16:42 +00:00
|
|
|
return e
|
|
|
|
}
|
2015-04-17 22:14:19 +00:00
|
|
|
srv.PacketConn = l
|
2017-11-09 21:01:09 +00:00
|
|
|
srv.started = true
|
2018-08-10 21:50:48 +00:00
|
|
|
unlock()
|
2018-09-10 10:42:54 +00:00
|
|
|
return srv.serveUDP(u)
|
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
|
|
|
}
|
|
|
|
|
2014-07-21 14:24:55 +00:00
|
|
|
// ActivateAndServe starts a nameserver with the PacketConn or Listener
|
2014-07-22 07:27:59 +00:00
|
|
|
// configured in *Server. Its main use is to start a server from systemd.
|
2014-07-21 14:24:55 +00:00
|
|
|
func (srv *Server) ActivateAndServe() error {
|
2018-08-10 21:50:48 +00:00
|
|
|
unlock := unlockOnce(&srv.lock)
|
2017-11-09 21:01:09 +00:00
|
|
|
srv.lock.Lock()
|
2018-08-10 21:50:48 +00:00
|
|
|
defer unlock()
|
|
|
|
|
2017-11-09 21:01:09 +00:00
|
|
|
if srv.started {
|
|
|
|
return &Error{err: "server already started"}
|
|
|
|
}
|
2018-05-09 15:44:32 +00:00
|
|
|
|
2018-09-08 16:15:17 +00:00
|
|
|
srv.init()
|
|
|
|
|
2020-10-24 15:53:01 +00:00
|
|
|
if srv.PacketConn != nil {
|
2017-11-09 21:01:09 +00:00
|
|
|
// Check PacketConn interface's type is valid and value
|
|
|
|
// is not nil
|
2020-10-24 15:53:01 +00:00
|
|
|
if t, ok := srv.PacketConn.(*net.UDPConn); ok && t != nil {
|
2017-11-09 21:01:09 +00:00
|
|
|
if e := setUDPSocketOptions(t); e != nil {
|
|
|
|
return e
|
|
|
|
}
|
2014-07-18 19:32:17 +00:00
|
|
|
}
|
2020-10-24 15:53:01 +00:00
|
|
|
srv.started = true
|
|
|
|
unlock()
|
|
|
|
return srv.serveUDP(srv.PacketConn)
|
2014-07-18 19:32:17 +00:00
|
|
|
}
|
2020-10-24 15:53:01 +00:00
|
|
|
if srv.Listener != nil {
|
2017-11-09 21:01:09 +00:00
|
|
|
srv.started = true
|
2018-08-10 21:50:48 +00:00
|
|
|
unlock()
|
2020-10-24 15:53:01 +00:00
|
|
|
return srv.serveTCP(srv.Listener)
|
2014-07-21 14:24:55 +00:00
|
|
|
}
|
2014-07-18 19:32:17 +00:00
|
|
|
return &Error{err: "bad listeners"}
|
|
|
|
}
|
|
|
|
|
2017-11-10 10:33:17 +00:00
|
|
|
// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and
|
|
|
|
// ActivateAndServe will return.
|
2014-08-20 15:12:59 +00:00
|
|
|
func (srv *Server) Shutdown() error {
|
2018-09-13 13:36:28 +00:00
|
|
|
return srv.ShutdownContext(context.Background())
|
|
|
|
}
|
|
|
|
|
|
|
|
// ShutdownContext shuts down a server. After a call to ShutdownContext,
|
|
|
|
// ListenAndServe and ActivateAndServe will return.
|
|
|
|
//
|
|
|
|
// A context.Context may be passed to limit how long to wait for connections
|
|
|
|
// to terminate.
|
|
|
|
func (srv *Server) ShutdownContext(ctx context.Context) error {
|
2017-11-09 21:01:09 +00:00
|
|
|
srv.lock.Lock()
|
2018-10-09 17:46:15 +00:00
|
|
|
if !srv.started {
|
|
|
|
srv.lock.Unlock()
|
2018-09-13 13:36:28 +00:00
|
|
|
return &Error{err: "server not started"}
|
|
|
|
}
|
|
|
|
|
2018-10-09 17:46:15 +00:00
|
|
|
srv.started = false
|
|
|
|
|
2015-10-06 23:10:38 +00:00
|
|
|
if srv.PacketConn != nil {
|
2018-09-13 13:36:28 +00:00
|
|
|
srv.PacketConn.SetReadDeadline(aLongTimeAgo) // Unblock reads
|
2015-10-06 23:10:38 +00:00
|
|
|
}
|
2018-09-13 13:36:28 +00:00
|
|
|
|
2015-10-06 23:10:38 +00:00
|
|
|
if srv.Listener != nil {
|
|
|
|
srv.Listener.Close()
|
2014-08-19 09:25:41 +00:00
|
|
|
}
|
2018-09-13 13:36:28 +00:00
|
|
|
|
|
|
|
for rw := range srv.conns {
|
|
|
|
rw.SetReadDeadline(aLongTimeAgo) // Unblock reads
|
|
|
|
}
|
2018-10-09 17:46:15 +00:00
|
|
|
|
2018-09-13 13:36:28 +00:00
|
|
|
srv.lock.Unlock()
|
|
|
|
|
|
|
|
if testShutdownNotify != nil {
|
|
|
|
testShutdownNotify.Broadcast()
|
|
|
|
}
|
|
|
|
|
|
|
|
var ctxErr error
|
|
|
|
select {
|
|
|
|
case <-srv.shutdown:
|
|
|
|
case <-ctx.Done():
|
|
|
|
ctxErr = ctx.Err()
|
|
|
|
}
|
|
|
|
|
|
|
|
if srv.PacketConn != nil {
|
|
|
|
srv.PacketConn.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctxErr
|
2014-08-29 16:18:39 +00:00
|
|
|
}
|
2014-08-29 03:11:49 +00:00
|
|
|
|
2018-09-13 13:36:28 +00:00
|
|
|
var testShutdownNotify *sync.Cond
|
|
|
|
|
2014-08-29 16:18:39 +00:00
|
|
|
// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
|
|
|
|
func (srv *Server) getReadTimeout() time.Duration {
|
|
|
|
if srv.ReadTimeout != 0 {
|
2019-01-04 10:19:42 +00:00
|
|
|
return srv.ReadTimeout
|
2014-08-29 16:18:39 +00:00
|
|
|
}
|
2019-01-04 10:19:42 +00:00
|
|
|
return dnsTimeout
|
2014-08-18 19:30:10 +00:00
|
|
|
}
|
|
|
|
|
2012-08-31 08:13:21 +00:00
|
|
|
// serveTCP starts a TCP listener for the server.
|
2016-01-08 13:26:13 +00:00
|
|
|
func (srv *Server) serveTCP(l net.Listener) error {
|
2011-04-03 09:49:23 +00:00
|
|
|
defer l.Close()
|
2014-12-12 12:17:39 +00:00
|
|
|
|
|
|
|
if srv.NotifyStartedFunc != nil {
|
|
|
|
srv.NotifyStartedFunc()
|
|
|
|
}
|
|
|
|
|
2018-09-13 13:36:28 +00:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
defer func() {
|
|
|
|
wg.Wait()
|
|
|
|
close(srv.shutdown)
|
|
|
|
}()
|
|
|
|
|
|
|
|
for srv.isStarted() {
|
2016-06-09 06:00:08 +00:00
|
|
|
rw, err := l.Accept()
|
|
|
|
if err != nil {
|
2018-09-13 13:36:28 +00:00
|
|
|
if !srv.isStarted() {
|
|
|
|
return nil
|
|
|
|
}
|
2016-06-09 06:00:08 +00:00
|
|
|
if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
|
2015-10-30 17:08:27 +00:00
|
|
|
continue
|
|
|
|
}
|
2016-06-09 06:00:08 +00:00
|
|
|
return err
|
2011-04-03 09:49:23 +00:00
|
|
|
}
|
2018-09-13 13:36:28 +00:00
|
|
|
srv.lock.Lock()
|
|
|
|
// Track the connection to allow unblocking reads on shutdown.
|
|
|
|
srv.conns[rw] = struct{}{}
|
|
|
|
srv.lock.Unlock()
|
|
|
|
wg.Add(1)
|
2019-03-10 12:52:08 +00:00
|
|
|
go srv.serveTCPConn(&wg, rw)
|
2011-04-03 09:49:23 +00:00
|
|
|
}
|
2018-09-13 13:36:28 +00:00
|
|
|
|
|
|
|
return nil
|
2011-04-02 07:22:05 +00:00
|
|
|
}
|
|
|
|
|
2012-08-31 08:13:21 +00:00
|
|
|
// serveUDP starts a UDP listener for the server.
|
2020-10-24 15:53:01 +00:00
|
|
|
func (srv *Server) serveUDP(l net.PacketConn) error {
|
2011-04-03 09:49:23 +00:00
|
|
|
defer l.Close()
|
2014-08-29 16:18:39 +00:00
|
|
|
|
2019-01-04 08:09:23 +00:00
|
|
|
reader := Reader(defaultReader{srv})
|
2015-08-04 13:04:40 +00:00
|
|
|
if srv.DecorateReader != nil {
|
|
|
|
reader = srv.DecorateReader(reader)
|
2015-08-04 05:17:14 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 15:53:01 +00:00
|
|
|
lUDP, isUDP := l.(*net.UDPConn)
|
|
|
|
readerPC, canPacketConn := reader.(PacketConnReader)
|
|
|
|
if !isUDP && !canPacketConn {
|
|
|
|
return &Error{err: "PacketConnReader was not implemented on Reader returned from DecorateReader but is required for net.PacketConn"}
|
|
|
|
}
|
|
|
|
|
|
|
|
if srv.NotifyStartedFunc != nil {
|
|
|
|
srv.NotifyStartedFunc()
|
|
|
|
}
|
|
|
|
|
2018-09-13 13:36:28 +00:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
defer func() {
|
|
|
|
wg.Wait()
|
|
|
|
close(srv.shutdown)
|
|
|
|
}()
|
|
|
|
|
2014-08-29 16:26:23 +00:00
|
|
|
rtimeout := srv.getReadTimeout()
|
2014-08-19 20:46:00 +00:00
|
|
|
// deadline is not used here
|
2018-09-13 13:36:28 +00:00
|
|
|
for srv.isStarted() {
|
2020-10-24 15:53:01 +00:00
|
|
|
var (
|
|
|
|
m []byte
|
|
|
|
sPC net.Addr
|
|
|
|
sUDP *SessionUDP
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
if isUDP {
|
|
|
|
m, sUDP, err = reader.ReadUDP(lUDP, rtimeout)
|
|
|
|
} else {
|
|
|
|
m, sPC, err = readerPC.ReadPacketConn(l, rtimeout)
|
|
|
|
}
|
2016-06-09 06:00:08 +00:00
|
|
|
if err != nil {
|
2018-09-13 13:36:28 +00:00
|
|
|
if !srv.isStarted() {
|
|
|
|
return nil
|
|
|
|
}
|
2018-01-09 13:57:26 +00:00
|
|
|
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return err
|
2014-08-29 12:27:53 +00:00
|
|
|
}
|
2018-01-10 07:51:00 +00:00
|
|
|
if len(m) < headerSize {
|
2018-09-08 16:15:17 +00:00
|
|
|
if cap(m) == srv.UDPSize {
|
|
|
|
srv.udpPool.Put(m[:srv.UDPSize])
|
|
|
|
}
|
2018-01-10 07:51:00 +00:00
|
|
|
continue
|
|
|
|
}
|
2018-09-13 13:36:28 +00:00
|
|
|
wg.Add(1)
|
2020-10-24 15:53:01 +00:00
|
|
|
go srv.serveUDPPacket(&wg, m, l, sUDP, sPC)
|
2011-04-03 09:49:23 +00:00
|
|
|
}
|
2018-09-13 13:36:28 +00:00
|
|
|
|
|
|
|
return nil
|
2011-04-02 07:22:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-10 12:52:08 +00:00
|
|
|
// Serve a new TCP connection.
|
|
|
|
func (srv *Server) serveTCPConn(wg *sync.WaitGroup, rw net.Conn) {
|
2022-02-05 00:23:49 +00:00
|
|
|
w := &response{tsigProvider: srv.tsigProvider(), tcp: rw}
|
2015-08-04 13:04:40 +00:00
|
|
|
if srv.DecorateWriter != nil {
|
|
|
|
w.writer = srv.DecorateWriter(w)
|
2015-08-04 05:17:14 +00:00
|
|
|
} else {
|
|
|
|
w.writer = w
|
|
|
|
}
|
|
|
|
|
2019-01-04 08:09:23 +00:00
|
|
|
reader := Reader(defaultReader{srv})
|
2018-09-13 13:36:28 +00:00
|
|
|
if srv.DecorateReader != nil {
|
|
|
|
reader = srv.DecorateReader(reader)
|
|
|
|
}
|
|
|
|
|
2018-04-06 15:09:55 +00:00
|
|
|
idleTimeout := tcpIdleTimeout
|
|
|
|
if srv.IdleTimeout != nil {
|
|
|
|
idleTimeout = srv.IdleTimeout()
|
|
|
|
}
|
|
|
|
|
|
|
|
timeout := srv.getReadTimeout()
|
2018-03-30 13:50:27 +00:00
|
|
|
|
2018-05-14 19:12:20 +00:00
|
|
|
limit := srv.MaxTCPQueries
|
|
|
|
if limit == 0 {
|
|
|
|
limit = maxTCPQueries
|
|
|
|
}
|
|
|
|
|
2018-09-13 13:36:28 +00:00
|
|
|
for q := 0; (q < limit || limit == -1) && srv.isStarted(); q++ {
|
2019-03-10 12:52:08 +00:00
|
|
|
m, err := reader.ReadTCP(w.tcp, timeout)
|
2018-04-06 15:09:55 +00:00
|
|
|
if err != nil {
|
|
|
|
// TODO(tmthrgd): handle error
|
|
|
|
break
|
|
|
|
}
|
2019-03-10 12:52:08 +00:00
|
|
|
srv.serveDNS(m, w)
|
2019-03-10 11:59:36 +00:00
|
|
|
if w.closed {
|
2018-04-06 15:09:55 +00:00
|
|
|
break // Close() was called
|
|
|
|
}
|
|
|
|
if w.hijacked {
|
|
|
|
break // client will call Close() themselves
|
|
|
|
}
|
|
|
|
// The first read uses the read timeout, the rest use the
|
|
|
|
// idle timeout.
|
|
|
|
timeout = idleTimeout
|
|