Skip to content

Commit 75d87bc

Browse files
author
Dan Boros
committed
Merge branch 'master' into sync-v1.1.68
2 parents 54c180d + 0b41fbe commit 75d87bc

File tree

3 files changed

+121
-10
lines changed

3 files changed

+121
-10
lines changed

server.go

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
307378
func (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()

udp_darwin.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//go:build darwin
2+
// +build darwin
3+
4+
package dns
5+
6+
import "net"
7+
8+
// SessionUDP holds the remote address.
9+
type SessionUDP struct {
10+
raddr *net.UDPAddr
11+
}
12+
13+
// RemoteAddr returns the remote network address.
14+
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
15+
16+
// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a
17+
// session struct instead of a net.UDPAddr.
18+
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
19+
n, _, _, raddr, err := conn.ReadMsgUDP(b, nil)
20+
if err != nil {
21+
return n, nil, err
22+
}
23+
return n, &SessionUDP{raddr}, err
24+
}
25+
26+
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a
27+
// session struct instead of a net.Addr.
28+
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
29+
n, _, err := conn.WriteMsgUDP(b, nil, session.raddr)
30+
return n, err
31+
}
32+
33+
func setUDPSocketOptions(*net.UDPConn) error { return nil }
34+
35+
//lint:ignore U1000 Ignore unused function.
36+
func parseDstFromOOB([]byte, net.IP) net.IP { return nil }

udp_no_control.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//go:build windows || darwin
2-
// +build windows darwin
1+
//go:build windows
2+
// +build windows
33

44
// TODO(tmthrgd): Remove this Windows-specific code if go.dev/issue/7175 and
55
// go.dev/issue/7174 are ever fixed.

0 commit comments

Comments
 (0)