diff options
-rw-r--r-- | core/dnsserver/listen_go111.go | 33 | ||||
-rw-r--r-- | core/dnsserver/listen_go_not111.go | 11 | ||||
-rw-r--r-- | core/dnsserver/server.go | 5 | ||||
-rw-r--r-- | core/dnsserver/server_grpc.go | 3 | ||||
-rw-r--r-- | core/dnsserver/server_https.go | 3 | ||||
-rw-r--r-- | core/dnsserver/server_tls.go | 3 | ||||
-rw-r--r-- | plugin.md | 5 | ||||
-rw-r--r-- | plugin/pkg/reuseport/listen_go111.go | 37 | ||||
-rw-r--r-- | plugin/pkg/reuseport/listen_go_not111.go | 13 |
9 files changed, 64 insertions, 49 deletions
diff --git a/core/dnsserver/listen_go111.go b/core/dnsserver/listen_go111.go deleted file mode 100644 index 573988b33..000000000 --- a/core/dnsserver/listen_go111.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build go1.11 -// +build aix darwin dragonfly freebsd linux netbsd openbsd - -package dnsserver - -import ( - "context" - "net" - "syscall" - - "github.com/coredns/coredns/plugin/pkg/log" - - "golang.org/x/sys/unix" -) - -func reuseportControl(network, address string, c syscall.RawConn) error { - c.Control(func(fd uintptr) { - if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil { - log.Warningf("Failed to set SO_REUSEPORT on socket: %s", err) - } - }) - return nil -} - -func listen(network, addr string) (net.Listener, error) { - lc := net.ListenConfig{Control: reuseportControl} - return lc.Listen(context.Background(), network, addr) -} - -func listenPacket(network, addr string) (net.PacketConn, error) { - lc := net.ListenConfig{Control: reuseportControl} - return lc.ListenPacket(context.Background(), network, addr) -} diff --git a/core/dnsserver/listen_go_not111.go b/core/dnsserver/listen_go_not111.go deleted file mode 100644 index 11021d099..000000000 --- a/core/dnsserver/listen_go_not111.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd - -package dnsserver - -import "net" - -func listen(network, addr string) (net.Listener, error) { return net.Listen(network, addr) } - -func listenPacket(network, addr string) (net.PacketConn, error) { - return net.ListenPacket(network, addr) -} diff --git a/core/dnsserver/server.go b/core/dnsserver/server.go index 9a6fea1ce..9b8fb23e4 100644 --- a/core/dnsserver/server.go +++ b/core/dnsserver/server.go @@ -15,6 +15,7 @@ import ( "github.com/coredns/coredns/plugin/pkg/edns" "github.com/coredns/coredns/plugin/pkg/log" "github.com/coredns/coredns/plugin/pkg/rcode" + "github.com/coredns/coredns/plugin/pkg/reuseport" "github.com/coredns/coredns/plugin/pkg/trace" "github.com/coredns/coredns/plugin/pkg/transport" "github.com/coredns/coredns/request" @@ -126,7 +127,7 @@ func (s *Server) ServePacket(p net.PacketConn) error { // Listen implements caddy.TCPServer interface. func (s *Server) Listen() (net.Listener, error) { - l, err := listen("tcp", s.Addr[len(transport.DNS+"://"):]) + l, err := reuseport.Listen("tcp", s.Addr[len(transport.DNS+"://"):]) if err != nil { return nil, err } @@ -140,7 +141,7 @@ func (s *Server) WrapListener(ln net.Listener) net.Listener { // ListenPacket implements caddy.UDPServer interface. func (s *Server) ListenPacket() (net.PacketConn, error) { - p, err := listenPacket("udp", s.Addr[len(transport.DNS+"://"):]) + p, err := reuseport.ListenPacket("udp", s.Addr[len(transport.DNS+"://"):]) if err != nil { return nil, err } diff --git a/core/dnsserver/server_grpc.go b/core/dnsserver/server_grpc.go index e4f48ddec..7b530f97a 100644 --- a/core/dnsserver/server_grpc.go +++ b/core/dnsserver/server_grpc.go @@ -8,6 +8,7 @@ import ( "net" "github.com/coredns/coredns/pb" + "github.com/coredns/coredns/plugin/pkg/reuseport" "github.com/coredns/coredns/plugin/pkg/transport" "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" @@ -72,7 +73,7 @@ func (s *ServergRPC) ServePacket(p net.PacketConn) error { return nil } // Listen implements caddy.TCPServer interface. func (s *ServergRPC) Listen() (net.Listener, error) { - l, err := net.Listen("tcp", s.Addr[len(transport.GRPC+"://"):]) + l, err := reuseport.Listen("tcp", s.Addr[len(transport.GRPC+"://"):]) if err != nil { return nil, err } diff --git a/core/dnsserver/server_https.go b/core/dnsserver/server_https.go index 6b5a72384..d2515295c 100644 --- a/core/dnsserver/server_https.go +++ b/core/dnsserver/server_https.go @@ -12,6 +12,7 @@ import ( "github.com/coredns/coredns/plugin/pkg/dnsutil" "github.com/coredns/coredns/plugin/pkg/doh" "github.com/coredns/coredns/plugin/pkg/response" + "github.com/coredns/coredns/plugin/pkg/reuseport" "github.com/coredns/coredns/plugin/pkg/transport" ) @@ -61,7 +62,7 @@ func (s *ServerHTTPS) ServePacket(p net.PacketConn) error { return nil } // Listen implements caddy.TCPServer interface. func (s *ServerHTTPS) Listen() (net.Listener, error) { - l, err := net.Listen("tcp", s.Addr[len(transport.HTTPS+"://"):]) + l, err := reuseport.Listen("tcp", s.Addr[len(transport.HTTPS+"://"):]) if err != nil { return nil, err } diff --git a/core/dnsserver/server_tls.go b/core/dnsserver/server_tls.go index 1bc6e6ac2..0b7fa517a 100644 --- a/core/dnsserver/server_tls.go +++ b/core/dnsserver/server_tls.go @@ -6,6 +6,7 @@ import ( "fmt" "net" + "github.com/coredns/coredns/plugin/pkg/reuseport" "github.com/coredns/coredns/plugin/pkg/transport" "github.com/miekg/dns" @@ -57,7 +58,7 @@ func (s *ServerTLS) ServePacket(p net.PacketConn) error { return nil } // Listen implements caddy.TCPServer interface. func (s *ServerTLS) Listen() (net.Listener, error) { - l, err := net.Listen("tcp", s.Addr[len(transport.TLS+"://"):]) + l, err := reuseport.Listen("tcp", s.Addr[len(transport.TLS+"://"):]) if err != nil { return nil, err } @@ -64,6 +64,11 @@ a *Metrics* section detailing the metrics. If the plugin supports signalling readiness it should have a *Ready* section detailing how it works, and implement the `ready.Readiness` interface. +## Opening Sockets + +See the plugin/pkg/reuseport for `Listen` and `ListenPacket` functions. Using these functions makes +you plugin handle reload events better. + ## Documentation Each plugin should have a README.md explaining what the plugin does and how it is configured. The diff --git a/plugin/pkg/reuseport/listen_go111.go b/plugin/pkg/reuseport/listen_go111.go new file mode 100644 index 000000000..fa6f365d6 --- /dev/null +++ b/plugin/pkg/reuseport/listen_go111.go @@ -0,0 +1,37 @@ +// +build go1.11 +// +build aix darwin dragonfly freebsd linux netbsd openbsd + +package reuseport + +import ( + "context" + "net" + "syscall" + + "github.com/coredns/coredns/plugin/pkg/log" + + "golang.org/x/sys/unix" +) + +func control(network, address string, c syscall.RawConn) error { + c.Control(func(fd uintptr) { + if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil { + log.Warningf("Failed to set SO_REUSEPORT on socket: %s", err) + } + }) + return nil +} + +// Listen announces on the local network address. See net.Listen for more information. +// If SO_REUSEPORT is available it will be set on the socket. +func Listen(network, addr string) (net.Listener, error) { + lc := net.ListenConfig{Control: control} + return lc.Listen(context.Background(), network, addr) +} + +// ListenPacket announces on the local network address. See net.ListenPacket for more information. +// If SO_REUSEPORT is available it will be set on the socket. +func ListenPacket(network, addr string) (net.PacketConn, error) { + lc := net.ListenConfig{Control: control} + return lc.ListenPacket(context.Background(), network, addr) +} diff --git a/plugin/pkg/reuseport/listen_go_not111.go b/plugin/pkg/reuseport/listen_go_not111.go new file mode 100644 index 000000000..e3bdfb906 --- /dev/null +++ b/plugin/pkg/reuseport/listen_go_not111.go @@ -0,0 +1,13 @@ +// +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd + +package reuseport + +import "net" + +// Listen is a wrapper around net.Listen. +func Listen(network, addr string) (net.Listener, error) { return net.Listen(network, addr) } + +// ListenPacket is a wrapper around net.ListenPacket. +func ListenPacket(network, addr string) (net.PacketConn, error) { + return net.ListenPacket(network, addr) +} |