1
0
Fork 0

Fix panic when parsing resolv.conf

This commit is contained in:
Ludovic Fernandez 2018-03-02 10:46:04 +01:00 committed by Traefiker Bot
parent f149b56063
commit 9ae808aac4
316 changed files with 37454 additions and 13195 deletions

View file

@ -285,7 +285,7 @@ type Server struct {
WriteTimeout time.Duration
// TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
IdleTimeout func() time.Duration
// Secret(s) for Tsig map[<zonename>]<base64 secret>.
// Secret(s) for Tsig map[<zonename>]<base64 secret>. The zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2).
TsigSecret map[string]string
// Unsafe instructs the server to disregard any sanity checks and directly hand the message to
// the handler. It will specifically not check if the query has the QR bit not set.
@ -297,10 +297,7 @@ type Server struct {
// DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
DecorateWriter DecorateWriter
// Graceful shutdown handling
inFlight sync.WaitGroup
// Shutdown handling
lock sync.RWMutex
started bool
}
@ -412,10 +409,8 @@ func (srv *Server) ActivateAndServe() error {
return &Error{err: "bad listeners"}
}
// Shutdown gracefully shuts down a server. After a call to Shutdown, ListenAndServe and
// ActivateAndServe will return. All in progress queries are completed before the server
// is taken down. If the Shutdown is taking longer than the reading timeout an error
// is returned.
// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and
// ActivateAndServe will return.
func (srv *Server) Shutdown() error {
srv.lock.Lock()
if !srv.started {
@ -431,19 +426,7 @@ func (srv *Server) Shutdown() error {
if srv.Listener != nil {
srv.Listener.Close()
}
fin := make(chan bool)
go func() {
srv.inFlight.Wait()
fin <- true
}()
select {
case <-time.After(srv.getReadTimeout()):
return &Error{err: "server shutdown is pending"}
case <-fin:
return nil
}
return nil
}
// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
@ -477,13 +460,6 @@ func (srv *Server) serveTCP(l net.Listener) error {
// deadline is not used here
for {
rw, err := l.Accept()
if err != nil {
if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
continue
}
return err
}
m, err := reader.ReadTCP(rw, rtimeout)
srv.lock.RLock()
if !srv.started {
srv.lock.RUnlock()
@ -491,10 +467,19 @@ func (srv *Server) serveTCP(l net.Listener) error {
}
srv.lock.RUnlock()
if err != nil {
continue
if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
continue
}
return err
}
srv.inFlight.Add(1)
go srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw)
go func() {
m, err := reader.ReadTCP(rw, rtimeout)
if err != nil {
rw.Close()
return
}
srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw)
}()
}
}
@ -527,17 +512,20 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
}
srv.lock.RUnlock()
if err != nil {
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
continue
}
return err
}
if len(m) < headerSize {
continue
}
srv.inFlight.Add(1)
go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
}
}
// Serve a new connection.
func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, s *SessionUDP, t net.Conn) {
defer srv.inFlight.Done()
w := &response{tsigSecret: srv.TsigSecret, udp: u, tcp: t, remoteAddr: a, udpSession: s}
if srv.DecorateWriter != nil {
w.writer = srv.DecorateWriter(w)
@ -647,11 +635,8 @@ func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *S
conn.SetReadDeadline(time.Now().Add(timeout))
m := make([]byte, srv.UDPSize)
n, s, err := ReadFromSessionUDP(conn, m)
if err != nil || n == 0 {
if err != nil {
return nil, nil, err
}
return nil, nil, ErrShortRead
if err != nil {
return nil, nil, err
}
m = m[:n]
return m, s, nil