From d80ad4aae511236dbdcb6832d9d4578b4bdacc9f Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Fri, 18 Jul 2014 20:32:17 +0100 Subject: [PATCH] Add support for systemd socket activation --- server.go | 32 ++++++++++++++++++++++++++++++++ udp_other.go | 6 +++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/server.go b/server.go index 445ad14f..3713f85f 100644 --- a/server.go +++ b/server.go @@ -97,6 +97,12 @@ func ListenAndServe(addr string, network string, handler Handler) error { return server.ListenAndServe() } +// Start a server with these listeners. Invoke handler for incoming queries. +func StartAndServe(ls []net.Listener, ps []net.PacketConn, handler Handler) error { + server := &Server{Listeners: ls, PacketConns: ps, Handler: handler} + return server.StartAndServe() +} + func (mux *ServeMux) match(q string, t uint16) Handler { mux.m.RLock() defer mux.m.RUnlock() @@ -197,6 +203,10 @@ type Server struct { Addr string // if "tcp" it will invoke a TCP listener, otherwise an UDP one. Net string + // TCP Listeners to use, this is to aid in systemd's socket activation. + Listeners []net.Listener + // UDP "Listeners" to use, this is to aid in systemd's socket activation. + PacketConns []net.PacketConn // Handler to invoke, dns.DefaultServeMux if nil. Handler Handler // Default buffer size to use to read incoming UDP messages. If not set @@ -252,6 +262,28 @@ func (srv *Server) ListenAndServe() error { return &Error{err: "bad network"} } +// StartAndServe starts a nameserver with the first listener the or first +// packetconn configured in *Server. +func (srv *Server) StartAndServe() error { + if len(srv.Listeners) > 0 { + if t, ok := srv.Listeners[0].(*net.TCPListener); ok { + return srv.serveTCP(t) + } + } + if len(srv.PacketConns) > 0 { + if srv.UDPSize == 0 { + srv.UDPSize = MinMsgSize + } + if t, ok := srv.PacketConns[0].(*net.UDPConn); ok { + if e := setUDPSocketOptions(t); e != nil { + return e + } + return srv.serveUDP(t) + } + } + return &Error{err: "bad listeners"} +} + // serveTCP starts a TCP listener for the server. // Each request is handled in a seperate goroutine. func (srv *Server) serveTCP(l *net.TCPListener) error { diff --git a/udp_other.go b/udp_other.go index 65cfe642..2732b0e2 100644 --- a/udp_other.go +++ b/udp_other.go @@ -15,7 +15,7 @@ import ( // We tried to adhire to some kind of naming scheme. -func setUDPSocketOptions4(conn *net.UDPConn) error { return nil } -func setUDPSocketOptions6(conn *net.UDPConn) error { return nil } -func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil } +func setUDPSocketOptions4(conn *net.UDPConn) error { return nil } +func setUDPSocketOptions6(conn *net.UDPConn) error { return nil } +func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil } func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { return nil, nil }