@@ -246,10 +246,11 @@ type Server struct {
246246 MsgInvalidFunc MsgInvalidFunc
247247
248248 // Shutdown handling
249- lock sync.RWMutex
250- started bool
251- shutdown chan struct {}
252- conns map [net.Conn ]struct {}
249+ lock sync.RWMutex
250+ started bool
251+ shutdown chan struct {}
252+ shutdownOnce sync.Once
253+ conns map [net.Conn ]struct {}
253254
254255 // A pool for UDP message buffers.
255256 udpPool sync.Pool
@@ -303,6 +304,76 @@ func unlockOnce(l sync.Locker) func() {
303304 return func () { once .Do (l .Unlock ) }
304305}
305306
307+ func (srv * Server ) Listen () error {
308+ unlock := unlockOnce (& srv .lock )
309+ srv .lock .Lock ()
310+ defer unlock ()
311+
312+ if srv .started {
313+ return & Error {err : "server already started" }
314+ }
315+
316+ addr := srv .Addr
317+ if addr == "" {
318+ addr = ":domain"
319+ }
320+
321+ srv .init ()
322+
323+ switch srv .Net {
324+ case "tcp" , "tcp4" , "tcp6" :
325+ l , err := listenTCP (srv .Net , addr , srv .ReusePort , srv .ReuseAddr )
326+ if err != nil {
327+ return err
328+ }
329+ srv .Listener = l
330+ srv .started = true
331+ unlock ()
332+ return nil
333+ case "tcp-tls" , "tcp4-tls" , "tcp6-tls" :
334+ if srv .TLSConfig == nil || (len (srv .TLSConfig .Certificates ) == 0 && srv .TLSConfig .GetCertificate == nil && srv .TLSConfig .GetConfigForClient == nil ) {
335+ return errors .New ("dns: neither Certificates nor GetCertificate nor GetConfigForClient set in Config" )
336+ }
337+ network := strings .TrimSuffix (srv .Net , "-tls" )
338+ l , err := listenTCP (network , addr , srv .ReusePort , srv .ReuseAddr )
339+ if err != nil {
340+ return err
341+ }
342+ l = tls .NewListener (l , srv .TLSConfig )
343+ srv .Listener = l
344+ srv .started = true
345+ unlock ()
346+ return nil
347+ case "udp" , "udp4" , "udp6" :
348+ l , err := listenUDP (srv .Net , addr , srv .ReusePort , srv .ReuseAddr )
349+ if err != nil {
350+ return err
351+ }
352+ u := l .(* net.UDPConn )
353+ if e := setUDPSocketOptions (u ); e != nil {
354+ u .Close ()
355+ return e
356+ }
357+ srv .PacketConn = l
358+ srv .started = true
359+ unlock ()
360+ return nil
361+ }
362+ return & Error {err : "bad network" }
363+ }
364+
365+ func (srv * Server ) Serve () error {
366+ switch srv .Net {
367+ case "tcp" , "tcp4" , "tcp6" :
368+ return srv .serveTCP (srv .Listener )
369+ case "tcp-tls" , "tcp4-tls" , "tcp6-tls" :
370+ return srv .serveTCP (srv .Listener )
371+ case "udp" , "udp4" , "udp6" :
372+ return srv .serveUDP (srv .PacketConn )
373+ }
374+ return & Error {err : "bad network" }
375+ }
376+
306377// ListenAndServe starts a nameserver on the configured address in *Server.
307378func (srv * Server ) ListenAndServe () error {
308379 unlock := unlockOnce (& srv .lock )
@@ -331,8 +402,8 @@ func (srv *Server) ListenAndServe() error {
331402 unlock ()
332403 return srv .serveTCP (l )
333404 case "tcp-tls" , "tcp4-tls" , "tcp6-tls" :
334- if srv .TLSConfig == nil || (len (srv .TLSConfig .Certificates ) == 0 && srv .TLSConfig .GetCertificate == nil ) {
335- return errors .New ("neither Certificates nor GetCertificate set in config " )
405+ if srv .TLSConfig == nil || (len (srv .TLSConfig .Certificates ) == 0 && srv .TLSConfig .GetCertificate == nil && srv . TLSConfig . GetConfigForClient == nil ) {
406+ return errors .New ("dns: neither Certificates nor GetCertificate nor GetConfigForClient set in Config " )
336407 }
337408 network := strings .TrimSuffix (srv .Net , "-tls" )
338409 l , err := listenTCP (network , addr , srv .ReusePort , srv .ReuseAddr )
@@ -468,7 +539,9 @@ func (srv *Server) serveTCP(l net.Listener) error {
468539 var wg sync.WaitGroup
469540 defer func () {
470541 wg .Wait ()
471- close (srv .shutdown )
542+ srv .shutdownOnce .Do (func () {
543+ close (srv .shutdown )
544+ })
472545 }()
473546
474547 for srv .isStarted () {
@@ -515,7 +588,9 @@ func (srv *Server) serveUDP(l net.PacketConn) error {
515588 var wg sync.WaitGroup
516589 defer func () {
517590 wg .Wait ()
518- close (srv .shutdown )
591+ srv .shutdownOnce .Do (func () {
592+ close (srv .shutdown )
593+ })
519594 }()
520595
521596 rtimeout := srv .getReadTimeout ()
0 commit comments