mirror of
https://github.com/coredns/coredns.git
synced 2026-08-27 15:17:06 -04:00
Keep miekg/dns's default request policy unless a plugin explicitly registers an additional opcode. Aggregate the policy at the listener, then enforce it again after zone routing so mixed server blocks on one socket remain isolated. Apply the same policy to UDP, TCP, and DNS-over-TLS while preserving TSIG verification and the one-question requirement. Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>
106 lines
2.7 KiB
Go
106 lines
2.7 KiB
Go
package dnsserver
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/coredns/caddy"
|
|
"github.com/coredns/coredns/plugin/pkg/reuseport"
|
|
"github.com/coredns/coredns/plugin/pkg/transport"
|
|
|
|
"github.com/miekg/dns"
|
|
"github.com/pires/go-proxyproto"
|
|
)
|
|
|
|
// ServerTLS represents an instance of a TLS-over-DNS-server.
|
|
type ServerTLS struct {
|
|
*Server
|
|
tlsConfig *tls.Config
|
|
}
|
|
|
|
// NewServerTLS returns a new CoreDNS TLS server and compiles all plugin in to it.
|
|
func NewServerTLS(addr string, group []*Config) (*ServerTLS, error) {
|
|
s, err := NewServer(addr, group)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// The *tls* plugin must make sure that multiple conflicting
|
|
// TLS configuration returns an error: it can only be specified once.
|
|
var tlsConfig *tls.Config
|
|
for _, z := range s.zones {
|
|
for _, conf := range z {
|
|
// Should we error if some configs *don't* have TLS?
|
|
tlsConfig = conf.TLSConfig
|
|
}
|
|
}
|
|
|
|
return &ServerTLS{Server: s, tlsConfig: tlsConfig}, nil
|
|
}
|
|
|
|
// Compile-time check to ensure ServerTLS implements the caddy.GracefulServer interface
|
|
var _ caddy.GracefulServer = &ServerTLS{}
|
|
|
|
// Serve implements caddy.TCPServer interface.
|
|
func (s *ServerTLS) Serve(l net.Listener) error {
|
|
s.m.Lock()
|
|
|
|
if s.tlsConfig != nil {
|
|
l = tls.NewListener(l, s.tlsConfig)
|
|
}
|
|
|
|
// Only fill out the TCP server for this one.
|
|
s.server[tcp] = &dns.Server{Listener: l,
|
|
Net: "tcp-tls",
|
|
TsigSecret: s.tsigSecret,
|
|
MsgAcceptFunc: s.msgAcceptFunc(),
|
|
MaxTCPQueries: s.MaxTCPQueries,
|
|
ReadTimeout: s.ReadTimeout,
|
|
WriteTimeout: s.WriteTimeout,
|
|
IdleTimeout: func() time.Duration {
|
|
return s.IdleTimeout
|
|
},
|
|
Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) {
|
|
ctx := context.WithValue(context.Background(), Key{}, s.Server)
|
|
ctx = context.WithValue(ctx, LoopKey{}, 0)
|
|
s.ServeDNS(ctx, w, r)
|
|
})}
|
|
|
|
s.m.Unlock()
|
|
|
|
return s.server[tcp].ActivateAndServe()
|
|
}
|
|
|
|
// ServePacket implements caddy.UDPServer interface.
|
|
func (s *ServerTLS) ServePacket(_p net.PacketConn) error { return nil }
|
|
|
|
// Listen implements caddy.TCPServer interface.
|
|
func (s *ServerTLS) Listen() (net.Listener, error) {
|
|
l, err := reuseport.Listen("tcp", s.Addr[len(transport.TLS+"://"):])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if s.connPolicy != nil {
|
|
l = &proxyproto.Listener{Listener: l, ConnPolicy: s.connPolicy}
|
|
}
|
|
return l, nil
|
|
}
|
|
|
|
// ListenPacket implements caddy.UDPServer interface.
|
|
func (s *ServerTLS) ListenPacket() (net.PacketConn, error) { return nil, nil }
|
|
|
|
// OnStartupComplete lists the sites served by this server
|
|
// and any relevant information, assuming Quiet is false.
|
|
func (s *ServerTLS) OnStartupComplete() {
|
|
if Quiet {
|
|
return
|
|
}
|
|
|
|
out := startUpZones(transport.TLS+"://", s.Addr, s.zones)
|
|
if out != "" {
|
|
fmt.Print(out)
|
|
}
|
|
}
|