mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-30 00:30:07 +00:00
TUN-5675: Remove github.com/dgrijalva/jwt-go dependency by upgrading coredns version
This commit is contained in:
37
vendor/github.com/coredns/coredns/core/dnsserver/address.go
generated
vendored
37
vendor/github.com/coredns/coredns/core/dnsserver/address.go
generated
vendored
@@ -4,20 +4,13 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/pkg/parse"
|
||||
"github.com/coredns/coredns/plugin/pkg/transport"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type zoneAddr struct {
|
||||
Zone string
|
||||
Port string
|
||||
Transport string // dns, tls or grpc
|
||||
IPNet *net.IPNet // if reverse zone this hold the IPNet
|
||||
Address string // used for bound zoneAddr - validation of overlapping
|
||||
Transport string // dns, tls or grpc
|
||||
Address string // used for bound zoneAddr - validation of overlapping
|
||||
}
|
||||
|
||||
// String returns the string representation of z.
|
||||
@@ -29,32 +22,6 @@ func (z zoneAddr) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// normalizeZone parses a zone string into a structured format with separate
|
||||
// host, and port portions, as well as the original input string.
|
||||
func normalizeZone(str string) (zoneAddr, error) {
|
||||
trans, str := parse.Transport(str)
|
||||
|
||||
host, port, ipnet, err := plugin.SplitHostPort(str)
|
||||
if err != nil {
|
||||
return zoneAddr{}, err
|
||||
}
|
||||
|
||||
if port == "" {
|
||||
switch trans {
|
||||
case transport.DNS:
|
||||
port = Port
|
||||
case transport.TLS:
|
||||
port = transport.TLSPort
|
||||
case transport.GRPC:
|
||||
port = transport.GRPCPort
|
||||
case transport.HTTPS:
|
||||
port = transport.HTTPSPort
|
||||
}
|
||||
}
|
||||
|
||||
return zoneAddr{Zone: dns.Fqdn(host), Port: port, Transport: trans, IPNet: ipnet}, nil
|
||||
}
|
||||
|
||||
// SplitProtocolHostPort splits a full formed address like "dns://[::1]:53" into parts.
|
||||
func SplitProtocolHostPort(address string) (protocol string, ip string, port string, err error) {
|
||||
parts := strings.Split(address, "://")
|
||||
|
18
vendor/github.com/coredns/coredns/core/dnsserver/config.go
generated
vendored
18
vendor/github.com/coredns/coredns/core/dnsserver/config.go
generated
vendored
@@ -3,10 +3,10 @@ package dnsserver
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/plugin"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
)
|
||||
|
||||
// Config configuration for a single server.
|
||||
@@ -32,10 +32,10 @@ type Config struct {
|
||||
// DNS-over-TLS or DNS-over-gRPC.
|
||||
Transport string
|
||||
|
||||
// If this function is not nil it will be used to further filter access
|
||||
// to this handler. The primary use is to limit access to a reverse zone
|
||||
// on a non-octet boundary, i.e. /17
|
||||
FilterFunc func(string) bool
|
||||
// If this function is not nil it will be used to inspect and validate
|
||||
// HTTP requests. Although this isn't referenced in-tree, external plugins
|
||||
// may depend on it.
|
||||
HTTPRequestValidateFunc func(*http.Request) bool
|
||||
|
||||
// TLSConfig when listening for encrypted connections (gRPC, DNS-over-TLS).
|
||||
TLSConfig *tls.Config
|
||||
@@ -50,9 +50,13 @@ type Config struct {
|
||||
// on them should register themselves here. The name should be the name as return by the
|
||||
// Handler's Name method.
|
||||
registry map[string]plugin.Handler
|
||||
|
||||
// firstConfigInBlock is used to reference the first config in a server block, for the
|
||||
// purpose of sharing single instance of each plugin among all zones in a server block.
|
||||
firstConfigInBlock *Config
|
||||
}
|
||||
|
||||
// keyForConfig build a key for identifying the configs during setup time
|
||||
// keyForConfig builds a key for identifying the configs during setup time
|
||||
func keyForConfig(blocIndex int, blocKeyIndex int) string {
|
||||
return fmt.Sprintf("%d:%d", blocIndex, blocKeyIndex)
|
||||
}
|
||||
|
7
vendor/github.com/coredns/coredns/core/dnsserver/https.go
generated
vendored
7
vendor/github.com/coredns/coredns/core/dnsserver/https.go
generated
vendored
@@ -2,6 +2,7 @@ package dnsserver
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/coredns/coredns/plugin/pkg/nonwriter"
|
||||
)
|
||||
@@ -14,6 +15,9 @@ type DoHWriter struct {
|
||||
raddr net.Addr
|
||||
// laddr is our address. This can be optionally set.
|
||||
laddr net.Addr
|
||||
|
||||
// request is the HTTP request we're currently handling.
|
||||
request *http.Request
|
||||
}
|
||||
|
||||
// RemoteAddr returns the remote address.
|
||||
@@ -21,3 +25,6 @@ func (d *DoHWriter) RemoteAddr() net.Addr { return d.raddr }
|
||||
|
||||
// LocalAddr returns the local address.
|
||||
func (d *DoHWriter) LocalAddr() net.Addr { return d.laddr }
|
||||
|
||||
// Request returns the HTTP request
|
||||
func (d *DoHWriter) Request() *http.Request { return d.request }
|
||||
|
17
vendor/github.com/coredns/coredns/core/dnsserver/onstartup.go
generated
vendored
17
vendor/github.com/coredns/coredns/core/dnsserver/onstartup.go
generated
vendored
@@ -1,14 +1,25 @@
|
||||
package dnsserver
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// startUpZones create the text that we show when starting up:
|
||||
// startUpZones creates the text that we show when starting up:
|
||||
// grpc://example.com.:1055
|
||||
// example.com.:1053 on 127.0.0.1
|
||||
func startUpZones(protocol, addr string, zones map[string]*Config) string {
|
||||
s := ""
|
||||
|
||||
for zone := range zones {
|
||||
keys := make([]string, len(zones))
|
||||
i := 0
|
||||
for k := range zones {
|
||||
keys[i] = k
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, zone := range keys {
|
||||
// split addr into protocol, IP and Port
|
||||
_, ip, port, err := SplitProtocolHostPort(addr)
|
||||
|
||||
|
91
vendor/github.com/coredns/coredns/core/dnsserver/register.go
generated
vendored
91
vendor/github.com/coredns/coredns/core/dnsserver/register.go
generated
vendored
@@ -4,16 +4,15 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/caddy/caddyfile"
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/pkg/dnsutil"
|
||||
"github.com/coredns/coredns/plugin/pkg/parse"
|
||||
"github.com/coredns/coredns/plugin/pkg/transport"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
"github.com/caddyserver/caddy/caddyfile"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
const serverType = "dns"
|
||||
@@ -22,6 +21,7 @@ const serverType = "dns"
|
||||
// wise they potentially clash with other server types.
|
||||
func init() {
|
||||
flag.StringVar(&Port, serverType+".port", DefaultPort, "Default port")
|
||||
flag.StringVar(&Port, "p", DefaultPort, "Default port")
|
||||
|
||||
caddy.RegisterServerType(serverType, caddy.ServerType{
|
||||
Directives: func() []string { return Directives },
|
||||
@@ -61,11 +61,57 @@ var _ caddy.Context = &dnsContext{}
|
||||
func (h *dnsContext) InspectServerBlocks(sourceFile string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) {
|
||||
// Normalize and check all the zone names and check for duplicates
|
||||
for ib, s := range serverBlocks {
|
||||
// Walk the s.Keys and expand any reverse address in their proper DNS in-addr zones. If the expansions leads for
|
||||
// more than one reverse zone, replace the current value and add the rest to s.Keys.
|
||||
zoneAddrs := []zoneAddr{}
|
||||
for ik, k := range s.Keys {
|
||||
za, err := normalizeZone(k)
|
||||
trans, k1 := parse.Transport(k) // get rid of any dns:// or other scheme.
|
||||
hosts, port, err := plugin.SplitHostPort(k1)
|
||||
// We need to make this a fully qualified domain name to catch all errors here and not later when
|
||||
// plugin.Normalize is called again on these strings, with the prime difference being that the domain
|
||||
// name is fully qualified. This was found by fuzzing where "ȶ" is deemed OK, but "ȶ." is not (might be a
|
||||
// bug in miekg/dns actually). But here we were checking ȶ, which is OK, and later we barf in ȶ. leading to
|
||||
// "index out of range".
|
||||
for ih := range hosts {
|
||||
_, _, err := plugin.SplitHostPort(dns.Fqdn(hosts[ih]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if port == "" {
|
||||
switch trans {
|
||||
case transport.DNS:
|
||||
port = Port
|
||||
case transport.TLS:
|
||||
port = transport.TLSPort
|
||||
case transport.GRPC:
|
||||
port = transport.GRPCPort
|
||||
case transport.HTTPS:
|
||||
port = transport.HTTPSPort
|
||||
}
|
||||
}
|
||||
|
||||
if len(hosts) > 1 {
|
||||
s.Keys[ik] = hosts[0] + ":" + port // replace for the first
|
||||
for _, h := range hosts[1:] { // add the rest
|
||||
s.Keys = append(s.Keys, h+":"+port)
|
||||
}
|
||||
}
|
||||
for i := range hosts {
|
||||
zoneAddrs = append(zoneAddrs, zoneAddr{Zone: dns.Fqdn(hosts[i]), Port: port, Transport: trans})
|
||||
}
|
||||
}
|
||||
|
||||
serverBlocks[ib].Keys = s.Keys // important to save back the new keys that are potentially created here.
|
||||
|
||||
var firstConfigInBlock *Config
|
||||
|
||||
for ik := range s.Keys {
|
||||
za := zoneAddrs[ik]
|
||||
s.Keys[ik] = za.String()
|
||||
// Save the config to our master list, and key it for lookups.
|
||||
cfg := &Config{
|
||||
@@ -74,23 +120,16 @@ func (h *dnsContext) InspectServerBlocks(sourceFile string, serverBlocks []caddy
|
||||
Port: za.Port,
|
||||
Transport: za.Transport,
|
||||
}
|
||||
keyConfig := keyForConfig(ib, ik)
|
||||
if za.IPNet == nil {
|
||||
h.saveConfig(keyConfig, cfg)
|
||||
continue
|
||||
}
|
||||
|
||||
ones, bits := za.IPNet.Mask.Size()
|
||||
if (bits-ones)%8 != 0 { // only do this for non-octet boundaries
|
||||
cfg.FilterFunc = func(s string) bool {
|
||||
// TODO(miek): strings.ToLower! Slow and allocates new string.
|
||||
addr := dnsutil.ExtractAddressFromReverse(strings.ToLower(s))
|
||||
if addr == "" {
|
||||
return true
|
||||
}
|
||||
return za.IPNet.Contains(net.ParseIP(addr))
|
||||
}
|
||||
// Set reference to the first config in the current block.
|
||||
// This is used later by MakeServers to share a single plugin list
|
||||
// for all zones in a server block.
|
||||
if ik == 0 {
|
||||
firstConfigInBlock = cfg
|
||||
}
|
||||
cfg.firstConfigInBlock = firstConfigInBlock
|
||||
|
||||
keyConfig := keyForConfig(ib, ik)
|
||||
h.saveConfig(keyConfig, cfg)
|
||||
}
|
||||
}
|
||||
@@ -107,6 +146,17 @@ func (h *dnsContext) MakeServers() ([]caddy.Server, error) {
|
||||
return nil, errValid
|
||||
}
|
||||
|
||||
// Copy the Plugin, ListenHosts and Debug from first config in the block
|
||||
// to all other config in the same block . Doing this results in zones
|
||||
// sharing the same plugin instances and settings as other zones in
|
||||
// the same block.
|
||||
for _, c := range h.configs {
|
||||
c.Plugin = c.firstConfigInBlock.Plugin
|
||||
c.ListenHosts = c.firstConfigInBlock.ListenHosts
|
||||
c.Debug = c.firstConfigInBlock.Debug
|
||||
c.TLSConfig = c.firstConfigInBlock.TLSConfig
|
||||
}
|
||||
|
||||
// we must map (group) each config to a bind address
|
||||
groups, err := groupConfigsByListenAddr(h.configs)
|
||||
if err != nil {
|
||||
@@ -223,7 +273,6 @@ func (h *dnsContext) validateZonesAndListeningAddresses() error {
|
||||
// address (what you pass into net.Listen) to the list of site configs.
|
||||
// This function does NOT vet the configs to ensure they are compatible.
|
||||
func groupConfigsByListenAddr(configs []*Config) (map[string][]*Config, error) {
|
||||
|
||||
groups := make(map[string][]*Config)
|
||||
for _, conf := range configs {
|
||||
for _, h := range conf.ListenHosts {
|
||||
|
51
vendor/github.com/coredns/coredns/core/dnsserver/server.go
generated
vendored
51
vendor/github.com/coredns/coredns/core/dnsserver/server.go
generated
vendored
@@ -10,6 +10,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/metrics/vars"
|
||||
"github.com/coredns/coredns/plugin/pkg/edns"
|
||||
@@ -20,7 +21,6 @@ import (
|
||||
"github.com/coredns/coredns/plugin/pkg/transport"
|
||||
"github.com/coredns/coredns/request"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
"github.com/miekg/dns"
|
||||
ot "github.com/opentracing/opentracing-go"
|
||||
)
|
||||
@@ -66,10 +66,6 @@ func NewServer(addr string, group []*Config) (*Server, error) {
|
||||
if site.Debug {
|
||||
s.debug = true
|
||||
log.D.Set()
|
||||
} else {
|
||||
// When reloading we need to explicitly disable debug logging if it is now disabled.
|
||||
s.debug = false
|
||||
log.D.Clear()
|
||||
}
|
||||
// set the config per zone
|
||||
s.zones[site.Zone] = site
|
||||
@@ -97,6 +93,11 @@ func NewServer(addr string, group []*Config) (*Server, error) {
|
||||
site.pluginChain = stack
|
||||
}
|
||||
|
||||
if !s.debug {
|
||||
// When reloading we need to explicitly disable debug logging if it is now disabled.
|
||||
log.D.Clear()
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -109,6 +110,7 @@ func (s *Server) Serve(l net.Listener) error {
|
||||
s.m.Lock()
|
||||
s.server[tcp] = &dns.Server{Listener: l, Net: "tcp", Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) {
|
||||
ctx := context.WithValue(context.Background(), Key{}, s)
|
||||
ctx = context.WithValue(ctx, LoopKey{}, 0)
|
||||
s.ServeDNS(ctx, w, r)
|
||||
})}
|
||||
s.m.Unlock()
|
||||
@@ -122,6 +124,7 @@ func (s *Server) ServePacket(p net.PacketConn) error {
|
||||
s.m.Lock()
|
||||
s.server[udp] = &dns.Server{PacketConn: p, Net: "udp", Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) {
|
||||
ctx := context.WithValue(context.Background(), Key{}, s)
|
||||
ctx = context.WithValue(ctx, LoopKey{}, 0)
|
||||
s.ServeDNS(ctx, w, r)
|
||||
})}
|
||||
s.m.Unlock()
|
||||
@@ -193,7 +196,7 @@ func (s *Server) Stop() (err error) {
|
||||
// Address together with Stop() implement caddy.GracefulServer.
|
||||
func (s *Server) Address() string { return s.Addr }
|
||||
|
||||
// ServeDNS is the entry point for every request to the address that s
|
||||
// ServeDNS is the entry point for every request to the address that
|
||||
// is bound to. It acts as a multiplexer for the requests zonename as
|
||||
// defined in the request so that the correct zone
|
||||
// (configuration and plugin stack) will handle the request.
|
||||
@@ -210,7 +213,7 @@ func (s *Server) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
|
||||
// In case the user doesn't enable error plugin, we still
|
||||
// need to make sure that we stay alive up here
|
||||
if rec := recover(); rec != nil {
|
||||
log.Errorf("Recovered from panic in server: %q", s.Addr)
|
||||
log.Errorf("Recovered from panic in server: %q %v", s.Addr, rec)
|
||||
vars.Panic.Inc()
|
||||
errorAndMetricsFunc(s.Addr, w, r, dns.RcodeServerFailure)
|
||||
}
|
||||
@@ -239,23 +242,16 @@ func (s *Server) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
|
||||
|
||||
for {
|
||||
if h, ok := s.zones[q[off:]]; ok {
|
||||
if h.pluginChain == nil { // zone defined, but has not got any plugins
|
||||
errorAndMetricsFunc(s.Addr, w, r, dns.RcodeRefused)
|
||||
return
|
||||
}
|
||||
if r.Question[0].Qtype != dns.TypeDS {
|
||||
if h.FilterFunc == nil {
|
||||
rcode, _ := h.pluginChain.ServeDNS(ctx, w, r)
|
||||
if !plugin.ClientWrite(rcode) {
|
||||
errorFunc(s.Addr, w, r, rcode)
|
||||
}
|
||||
return
|
||||
}
|
||||
// FilterFunc is set, call it to see if we should use this handler.
|
||||
// This is given to full query name.
|
||||
if h.FilterFunc(q) {
|
||||
rcode, _ := h.pluginChain.ServeDNS(ctx, w, r)
|
||||
if !plugin.ClientWrite(rcode) {
|
||||
errorFunc(s.Addr, w, r, rcode)
|
||||
}
|
||||
return
|
||||
rcode, _ := h.pluginChain.ServeDNS(ctx, w, r)
|
||||
if !plugin.ClientWrite(rcode) {
|
||||
errorFunc(s.Addr, w, r, rcode)
|
||||
}
|
||||
return
|
||||
}
|
||||
// The type is DS, keep the handler, but keep on searching as maybe we are serving
|
||||
// the parent as well and the DS should be routed to it - this will probably *misroute* DS
|
||||
@@ -332,7 +328,7 @@ func errorAndMetricsFunc(server string, w dns.ResponseWriter, r *dns.Msg, rc int
|
||||
answer.SetRcode(r, rc)
|
||||
state.SizeAndDo(answer)
|
||||
|
||||
vars.Report(server, state, vars.Dropped, rcode.ToString(rc), answer.Len(), time.Now())
|
||||
vars.Report(server, state, vars.Dropped, rcode.ToString(rc), "" /* plugin */, answer.Len(), time.Now())
|
||||
|
||||
w.WriteMsg(answer)
|
||||
}
|
||||
@@ -342,8 +338,13 @@ const (
|
||||
udp = 1
|
||||
)
|
||||
|
||||
// Key is the context key for the current server added to the context.
|
||||
type Key struct{}
|
||||
type (
|
||||
// Key is the context key for the current server added to the context.
|
||||
Key struct{}
|
||||
|
||||
// LoopKey is the context key to detect server wide loops.
|
||||
LoopKey struct{}
|
||||
)
|
||||
|
||||
// EnableChaos is a map with plugin names for which we should open CH class queries as we block these by default.
|
||||
var EnableChaos = map[string]struct{}{
|
||||
|
10
vendor/github.com/coredns/coredns/core/dnsserver/server_grpc.go
generated
vendored
10
vendor/github.com/coredns/coredns/core/dnsserver/server_grpc.go
generated
vendored
@@ -7,11 +7,11 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/pb"
|
||||
"github.com/coredns/coredns/plugin/pkg/reuseport"
|
||||
"github.com/coredns/coredns/plugin/pkg/transport"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
|
||||
"github.com/miekg/dns"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
@@ -34,12 +34,17 @@ func NewServergRPC(addr string, group []*Config) (*ServergRPC, error) {
|
||||
return nil, err
|
||||
}
|
||||
// The *tls* plugin must make sure that multiple conflicting
|
||||
// TLS configuration return an error: it can only be specified once.
|
||||
// TLS configuration returns an error: it can only be specified once.
|
||||
var tlsConfig *tls.Config
|
||||
for _, conf := range s.zones {
|
||||
// Should we error if some configs *don't* have TLS?
|
||||
tlsConfig = conf.TLSConfig
|
||||
}
|
||||
// http/2 is required when using gRPC. We need to specify it in next protos
|
||||
// or the upgrade won't happen.
|
||||
if tlsConfig != nil {
|
||||
tlsConfig.NextProtos = []string{"h2"}
|
||||
}
|
||||
|
||||
return &ServergRPC{Server: s, tlsConfig: tlsConfig}, nil
|
||||
}
|
||||
@@ -134,6 +139,7 @@ func (s *ServergRPC) Query(ctx context.Context, in *pb.DnsPacket) (*pb.DnsPacket
|
||||
w := &gRPCresponse{localAddr: s.listenAddr, remoteAddr: a, Msg: msg}
|
||||
|
||||
dnsCtx := context.WithValue(ctx, Key{}, s.Server)
|
||||
dnsCtx = context.WithValue(dnsCtx, LoopKey{}, 0)
|
||||
s.ServeDNS(dnsCtx, w, msg)
|
||||
|
||||
packed, err := w.Msg.Pack()
|
||||
|
47
vendor/github.com/coredns/coredns/core/dnsserver/server_https.go
generated
vendored
47
vendor/github.com/coredns/coredns/core/dnsserver/server_https.go
generated
vendored
@@ -9,38 +9,60 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"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"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
)
|
||||
|
||||
// ServerHTTPS represents an instance of a DNS-over-HTTPS server.
|
||||
type ServerHTTPS struct {
|
||||
*Server
|
||||
httpsServer *http.Server
|
||||
listenAddr net.Addr
|
||||
tlsConfig *tls.Config
|
||||
httpsServer *http.Server
|
||||
listenAddr net.Addr
|
||||
tlsConfig *tls.Config
|
||||
validRequest func(*http.Request) bool
|
||||
}
|
||||
|
||||
// NewServerHTTPS returns a new CoreDNS GRPC server and compiles all plugins in to it.
|
||||
// NewServerHTTPS returns a new CoreDNS HTTPS server and compiles all plugins in to it.
|
||||
func NewServerHTTPS(addr string, group []*Config) (*ServerHTTPS, error) {
|
||||
s, err := NewServer(addr, group)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// The *tls* plugin must make sure that multiple conflicting
|
||||
// TLS configuration return an error: it can only be specified once.
|
||||
// TLS configuration returns an error: it can only be specified once.
|
||||
var tlsConfig *tls.Config
|
||||
for _, conf := range s.zones {
|
||||
// Should we error if some configs *don't* have TLS?
|
||||
tlsConfig = conf.TLSConfig
|
||||
}
|
||||
|
||||
sh := &ServerHTTPS{Server: s, tlsConfig: tlsConfig, httpsServer: new(http.Server)}
|
||||
// http/2 is recommended when using DoH. We need to specify it in next protos
|
||||
// or the upgrade won't happen.
|
||||
if tlsConfig != nil {
|
||||
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
|
||||
}
|
||||
|
||||
// Use a custom request validation func or use the standard DoH path check.
|
||||
var validator func(*http.Request) bool
|
||||
for _, conf := range s.zones {
|
||||
validator = conf.HTTPRequestValidateFunc
|
||||
}
|
||||
if validator == nil {
|
||||
validator = func(r *http.Request) bool { return r.URL.Path == doh.Path }
|
||||
}
|
||||
|
||||
srv := &http.Server{
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
IdleTimeout: 120 * time.Second,
|
||||
}
|
||||
sh := &ServerHTTPS{
|
||||
Server: s, tlsConfig: tlsConfig, httpsServer: srv, validRequest: validator,
|
||||
}
|
||||
sh.httpsServer.Handler = sh
|
||||
|
||||
return sh, nil
|
||||
@@ -104,7 +126,7 @@ func (s *ServerHTTPS) Stop() error {
|
||||
// chain, converts it back and write it to the client.
|
||||
func (s *ServerHTTPS) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if r.URL.Path != doh.Path {
|
||||
if !s.validRequest(r) {
|
||||
http.Error(w, "", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
@@ -118,11 +140,16 @@ func (s *ServerHTTPS) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Create a DoHWriter with the correct addresses in it.
|
||||
h, p, _ := net.SplitHostPort(r.RemoteAddr)
|
||||
port, _ := strconv.Atoi(p)
|
||||
dw := &DoHWriter{laddr: s.listenAddr, raddr: &net.TCPAddr{IP: net.ParseIP(h), Port: port}}
|
||||
dw := &DoHWriter{
|
||||
laddr: s.listenAddr,
|
||||
raddr: &net.TCPAddr{IP: net.ParseIP(h), Port: port},
|
||||
request: r,
|
||||
}
|
||||
|
||||
// We just call the normal chain handler - all error handling is done there.
|
||||
// We should expect a packet to be returned that we can send to the client.
|
||||
ctx := context.WithValue(context.Background(), Key{}, s.Server)
|
||||
ctx = context.WithValue(ctx, LoopKey{}, 0)
|
||||
s.ServeDNS(ctx, dw, msg)
|
||||
|
||||
// See section 4.2.1 of RFC 8484.
|
||||
|
5
vendor/github.com/coredns/coredns/core/dnsserver/server_tls.go
generated
vendored
5
vendor/github.com/coredns/coredns/core/dnsserver/server_tls.go
generated
vendored
@@ -6,10 +6,10 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/plugin/pkg/reuseport"
|
||||
"github.com/coredns/coredns/plugin/pkg/transport"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ func NewServerTLS(addr string, group []*Config) (*ServerTLS, error) {
|
||||
return nil, err
|
||||
}
|
||||
// The *tls* plugin must make sure that multiple conflicting
|
||||
// TLS configuration return an error: it can only be specified once.
|
||||
// TLS configuration returns an error: it can only be specified once.
|
||||
var tlsConfig *tls.Config
|
||||
for _, conf := range s.zones {
|
||||
// Should we error if some configs *don't* have TLS?
|
||||
@@ -50,6 +50,7 @@ func (s *ServerTLS) Serve(l net.Listener) error {
|
||||
// Only fill out the TCP server for this one.
|
||||
s.server[tcp] = &dns.Server{Listener: l, Net: "tcp-tls", 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()
|
||||
|
4
vendor/github.com/coredns/coredns/core/dnsserver/zdirectives.go
generated
vendored
4
vendor/github.com/coredns/coredns/core/dnsserver/zdirectives.go
generated
vendored
@@ -11,6 +11,7 @@ package dnsserver
|
||||
// care what plugin above them are doing.
|
||||
var Directives = []string{
|
||||
"metadata",
|
||||
"geoip",
|
||||
"cancel",
|
||||
"tls",
|
||||
"reload",
|
||||
@@ -27,6 +28,7 @@ var Directives = []string{
|
||||
"errors",
|
||||
"log",
|
||||
"dnstap",
|
||||
"local",
|
||||
"dns64",
|
||||
"acl",
|
||||
"any",
|
||||
@@ -34,8 +36,10 @@ var Directives = []string{
|
||||
"loadbalance",
|
||||
"cache",
|
||||
"rewrite",
|
||||
"header",
|
||||
"dnssec",
|
||||
"autopath",
|
||||
"minimal",
|
||||
"template",
|
||||
"transfer",
|
||||
"hosts",
|
||||
|
36
vendor/github.com/coredns/coredns/coremain/run.go
generated
vendored
36
vendor/github.com/coredns/coredns/coremain/run.go
generated
vendored
@@ -4,15 +4,13 @@ package coremain
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/core/dnsserver"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -36,21 +34,6 @@ func init() {
|
||||
// Run is CoreDNS's main() function.
|
||||
func Run() {
|
||||
caddy.TrapSignals()
|
||||
|
||||
// Reset flag.CommandLine to get rid of unwanted flags for instance from glog (used in kubernetes).
|
||||
// And read the ones we want to keep.
|
||||
flag.VisitAll(func(f *flag.Flag) {
|
||||
if _, ok := flagsBlacklist[f.Name]; ok {
|
||||
return
|
||||
}
|
||||
flagsToKeep = append(flagsToKeep, f)
|
||||
})
|
||||
|
||||
flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
|
||||
for _, f := range flagsToKeep {
|
||||
flag.Var(f.Value, f.Name, f.Usage)
|
||||
}
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if len(flag.Args()) > 0 {
|
||||
@@ -112,7 +95,7 @@ func confLoader(serverType string) (caddy.Input, error) {
|
||||
return caddy.CaddyfileFromPipe(os.Stdin, serverType)
|
||||
}
|
||||
|
||||
contents, err := ioutil.ReadFile(conf)
|
||||
contents, err := os.ReadFile(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -125,7 +108,7 @@ func confLoader(serverType string) (caddy.Input, error) {
|
||||
|
||||
// defaultLoader loads the Corefile from the current working directory.
|
||||
func defaultLoader(serverType string) (caddy.Input, error) {
|
||||
contents, err := ioutil.ReadFile(caddy.DefaultConfigFile)
|
||||
contents, err := os.ReadFile(caddy.DefaultConfigFile)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
@@ -198,16 +181,3 @@ var (
|
||||
// Gitcommit contains the commit where we built CoreDNS from.
|
||||
GitCommit string
|
||||
)
|
||||
|
||||
// flagsBlacklist removes flags with these names from our flagset.
|
||||
var flagsBlacklist = map[string]struct{}{
|
||||
"logtostderr": {},
|
||||
"alsologtostderr": {},
|
||||
"v": {},
|
||||
"stderrthreshold": {},
|
||||
"vmodule": {},
|
||||
"log_backtrace_at": {},
|
||||
"log_dir": {},
|
||||
}
|
||||
|
||||
var flagsToKeep []*flag.Flag
|
||||
|
2
vendor/github.com/coredns/coredns/coremain/version.go
generated
vendored
2
vendor/github.com/coredns/coredns/coremain/version.go
generated
vendored
@@ -2,7 +2,7 @@ package coremain
|
||||
|
||||
// Various CoreDNS constants.
|
||||
const (
|
||||
CoreVersion = "1.7.0"
|
||||
CoreVersion = "1.8.7"
|
||||
coreName = "CoreDNS"
|
||||
serverType = "dns"
|
||||
)
|
||||
|
11
vendor/github.com/coredns/coredns/plugin/backend.go
generated
vendored
11
vendor/github.com/coredns/coredns/plugin/backend.go
generated
vendored
@@ -26,23 +26,14 @@ type ServiceBackend interface {
|
||||
// Note: it does not implement a specific service.
|
||||
Records(ctx context.Context, state request.Request, exact bool) ([]msg.Service, error)
|
||||
|
||||
// IsNameError return true if err indicated a record not found condition
|
||||
// IsNameError returns true if err indicated a record not found condition
|
||||
IsNameError(err error) bool
|
||||
|
||||
Transferer
|
||||
}
|
||||
|
||||
// Transferer defines an interface for backends that provide AXFR of all records.
|
||||
type Transferer interface {
|
||||
// Serial returns a SOA serial number to construct a SOA record.
|
||||
Serial(state request.Request) uint32
|
||||
|
||||
// MinTTL returns the minimum TTL to be used in the SOA record.
|
||||
MinTTL(state request.Request) uint32
|
||||
|
||||
// Transfer handles a zone transfer it writes to the client just
|
||||
// like any other handler.
|
||||
Transfer(ctx context.Context, state request.Request) (int, error)
|
||||
}
|
||||
|
||||
// Options are extra options that can be specified for a lookup.
|
||||
|
12
vendor/github.com/coredns/coredns/plugin/backend_lookup.go
generated
vendored
12
vendor/github.com/coredns/coredns/plugin/backend_lookup.go
generated
vendored
@@ -422,7 +422,7 @@ func NS(ctx context.Context, b ServiceBackend, zone string, state request.Reques
|
||||
old := state.QName()
|
||||
|
||||
state.Clear()
|
||||
state.Req.Question[0].Name = "ns.dns." + zone
|
||||
state.Req.Question[0].Name = dnsutil.Join("ns.dns.", zone)
|
||||
services, err := b.Services(ctx, state, false, opt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -440,8 +440,8 @@ func NS(ctx context.Context, b ServiceBackend, zone string, state request.Reques
|
||||
|
||||
case dns.TypeA, dns.TypeAAAA:
|
||||
serv.Host = msg.Domain(serv.Key)
|
||||
extra = append(extra, newAddress(serv, serv.Host, ip, what))
|
||||
ns := serv.NewNS(state.QName())
|
||||
extra = append(extra, newAddress(serv, ns.Ns, ip, what))
|
||||
if _, ok := seen[ns.Ns]; ok {
|
||||
continue
|
||||
}
|
||||
@@ -462,12 +462,8 @@ func SOA(ctx context.Context, b ServiceBackend, zone string, state request.Reque
|
||||
|
||||
header := dns.RR_Header{Name: zone, Rrtype: dns.TypeSOA, Ttl: ttl, Class: dns.ClassINET}
|
||||
|
||||
Mbox := hostmaster + "."
|
||||
Ns := "ns.dns."
|
||||
if zone[0] != '.' {
|
||||
Mbox += zone
|
||||
Ns += zone
|
||||
}
|
||||
Mbox := dnsutil.Join(hostmaster, zone)
|
||||
Ns := dnsutil.Join("ns.dns", zone)
|
||||
|
||||
soa := &dns.SOA{Hdr: header,
|
||||
Mbox: Mbox,
|
||||
|
8
vendor/github.com/coredns/coredns/plugin/cache/README.md
generated
vendored
8
vendor/github.com/coredns/coredns/plugin/cache/README.md
generated
vendored
@@ -10,6 +10,9 @@ With *cache* enabled, all records except zone transfers and metadata records wil
|
||||
3600s. Caching is mostly useful in a scenario when fetching data from the backend (upstream,
|
||||
database, etc.) is expensive.
|
||||
|
||||
*Cache* will change the query to enable DNSSEC (DNSSEC OK; DO) if it passes through the plugin. If
|
||||
the client didn't request any DNSSEC (records), these are filtered out when replying.
|
||||
|
||||
This plugin can only be used once per Server Block.
|
||||
|
||||
## Syntax
|
||||
@@ -72,9 +75,12 @@ If monitoring is enabled (via the *prometheus* plugin) then the following metric
|
||||
|
||||
* `coredns_cache_entries{server, type}` - Total elements in the cache by cache type.
|
||||
* `coredns_cache_hits_total{server, type}` - Counter of cache hits by cache type.
|
||||
* `coredns_cache_misses_total{server}` - Counter of cache misses.
|
||||
* `coredns_cache_misses_total{server}` - Counter of cache misses. - Deprecated, derive misses from cache hits/requests counters.
|
||||
* `coredns_cache_requests_total{server}` - Counter of cache requests.
|
||||
* `coredns_cache_prefetch_total{server}` - Counter of times the cache has prefetched a cached item.
|
||||
* `coredns_cache_drops_total{server}` - Counter of responses excluded from the cache due to request/response question name mismatch.
|
||||
* `coredns_cache_served_stale_total{server}` - Counter of requests served from stale cache entries.
|
||||
* `coredns_cache_evictions_total{server, type}` - Counter of cache evictions.
|
||||
|
||||
Cache types are either "denial" or "success". `Server` is the server handling the request, see the
|
||||
prometheus plugin for documentation.
|
||||
|
53
vendor/github.com/coredns/coredns/plugin/cache/cache.go
generated
vendored
53
vendor/github.com/coredns/coredns/plugin/cache/cache.go
generated
vendored
@@ -65,31 +65,21 @@ func New() *Cache {
|
||||
// key returns key under which we store the item, -1 will be returned if we don't store the message.
|
||||
// Currently we do not cache Truncated, errors zone transfers or dynamic update messages.
|
||||
// qname holds the already lowercased qname.
|
||||
func key(qname string, m *dns.Msg, t response.Type, do bool) (bool, uint64) {
|
||||
func key(qname string, m *dns.Msg, t response.Type) (bool, uint64) {
|
||||
// We don't store truncated responses.
|
||||
if m.Truncated {
|
||||
return false, 0
|
||||
}
|
||||
// Nor errors or Meta or Update
|
||||
// Nor errors or Meta or Update.
|
||||
if t == response.OtherError || t == response.Meta || t == response.Update {
|
||||
return false, 0
|
||||
}
|
||||
|
||||
return true, hash(qname, m.Question[0].Qtype, do)
|
||||
return true, hash(qname, m.Question[0].Qtype)
|
||||
}
|
||||
|
||||
var one = []byte("1")
|
||||
var zero = []byte("0")
|
||||
|
||||
func hash(qname string, qtype uint16, do bool) uint64 {
|
||||
func hash(qname string, qtype uint16) uint64 {
|
||||
h := fnv.New64()
|
||||
|
||||
if do {
|
||||
h.Write(one)
|
||||
} else {
|
||||
h.Write(zero)
|
||||
}
|
||||
|
||||
h.Write([]byte{byte(qtype >> 8)})
|
||||
h.Write([]byte{byte(qtype)})
|
||||
h.Write([]byte(qname))
|
||||
@@ -114,6 +104,7 @@ type ResponseWriter struct {
|
||||
state request.Request
|
||||
server string // Server handling the request.
|
||||
|
||||
do bool // When true the original request had the DO bit set.
|
||||
prefetch bool // When true write nothing back to the client.
|
||||
remoteAddr net.Addr
|
||||
}
|
||||
@@ -152,14 +143,10 @@ func (w *ResponseWriter) RemoteAddr() net.Addr {
|
||||
|
||||
// WriteMsg implements the dns.ResponseWriter interface.
|
||||
func (w *ResponseWriter) WriteMsg(res *dns.Msg) error {
|
||||
do := false
|
||||
mt, opt := response.Typify(res, w.now().UTC())
|
||||
if opt != nil {
|
||||
do = opt.Do()
|
||||
}
|
||||
mt, _ := response.Typify(res, w.now().UTC())
|
||||
|
||||
// key returns empty string for anything we don't want to cache.
|
||||
hasKey, key := key(w.state.Name(), res, mt, do)
|
||||
hasKey, key := key(w.state.Name(), res, mt)
|
||||
|
||||
msgTTL := dnsutil.MinimalTTL(res, mt)
|
||||
var duration time.Duration
|
||||
@@ -188,18 +175,16 @@ func (w *ResponseWriter) WriteMsg(res *dns.Msg) error {
|
||||
}
|
||||
|
||||
// Apply capped TTL to this reply to avoid jarring TTL experience 1799 -> 8 (e.g.)
|
||||
// We also may need to filter out DNSSEC records, see toMsg() for similar code.
|
||||
ttl := uint32(duration.Seconds())
|
||||
for i := range res.Answer {
|
||||
res.Answer[i].Header().Ttl = ttl
|
||||
}
|
||||
for i := range res.Ns {
|
||||
res.Ns[i].Header().Ttl = ttl
|
||||
}
|
||||
for i := range res.Extra {
|
||||
if res.Extra[i].Header().Rrtype != dns.TypeOPT {
|
||||
res.Extra[i].Header().Ttl = ttl
|
||||
}
|
||||
res.Answer = filterRRSlice(res.Answer, ttl, w.do, false)
|
||||
res.Ns = filterRRSlice(res.Ns, ttl, w.do, false)
|
||||
res.Extra = filterRRSlice(res.Extra, ttl, w.do, false)
|
||||
|
||||
if !w.do {
|
||||
res.AuthenticatedData = false // unset AD bit if client is not OK with DNSSEC
|
||||
}
|
||||
|
||||
return w.ResponseWriter.WriteMsg(res)
|
||||
}
|
||||
|
||||
@@ -209,7 +194,9 @@ func (w *ResponseWriter) set(m *dns.Msg, key uint64, mt response.Type, duration
|
||||
switch mt {
|
||||
case response.NoError, response.Delegation:
|
||||
i := newItem(m, w.now(), duration)
|
||||
w.pcache.Add(key, i)
|
||||
if w.pcache.Add(key, i) {
|
||||
evictions.WithLabelValues(w.server, Success).Inc()
|
||||
}
|
||||
// when pre-fetching, remove the negative cache entry if it exists
|
||||
if w.prefetch {
|
||||
w.ncache.Remove(key)
|
||||
@@ -217,7 +204,9 @@ func (w *ResponseWriter) set(m *dns.Msg, key uint64, mt response.Type, duration
|
||||
|
||||
case response.NameError, response.NoData, response.ServerError:
|
||||
i := newItem(m, w.now(), duration)
|
||||
w.ncache.Add(key, i)
|
||||
if w.ncache.Add(key, i) {
|
||||
evictions.WithLabelValues(w.server, Denial).Inc()
|
||||
}
|
||||
|
||||
case response.OtherError:
|
||||
// don't cache these
|
||||
|
46
vendor/github.com/coredns/coredns/plugin/cache/dnssec.go
generated
vendored
Normal file
46
vendor/github.com/coredns/coredns/plugin/cache/dnssec.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package cache
|
||||
|
||||
import "github.com/miekg/dns"
|
||||
|
||||
// isDNSSEC returns true if r is a DNSSEC record. NSEC,NSEC3,DS and RRSIG/SIG
|
||||
// are DNSSEC records. DNSKEYs is not in this list on the assumption that the
|
||||
// client explicitly asked for it.
|
||||
func isDNSSEC(r dns.RR) bool {
|
||||
switch r.Header().Rrtype {
|
||||
case dns.TypeNSEC:
|
||||
return true
|
||||
case dns.TypeNSEC3:
|
||||
return true
|
||||
case dns.TypeDS:
|
||||
return true
|
||||
case dns.TypeRRSIG:
|
||||
return true
|
||||
case dns.TypeSIG:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// filterRRSlice filters rrs and removes DNSSEC RRs when do is false. In the returned slice
|
||||
// the TTLs are set to ttl. If dup is true the RRs in rrs are _copied_ into the slice that is
|
||||
// returned.
|
||||
func filterRRSlice(rrs []dns.RR, ttl uint32, do, dup bool) []dns.RR {
|
||||
j := 0
|
||||
rs := make([]dns.RR, len(rrs))
|
||||
for _, r := range rrs {
|
||||
if !do && isDNSSEC(r) {
|
||||
continue
|
||||
}
|
||||
if r.Header().Rrtype == dns.TypeOPT {
|
||||
continue
|
||||
}
|
||||
r.Header().Ttl = ttl
|
||||
if dup {
|
||||
rs[j] = dns.Copy(r)
|
||||
} else {
|
||||
rs[j] = r
|
||||
}
|
||||
j++
|
||||
}
|
||||
return rs[:j]
|
||||
}
|
75
vendor/github.com/coredns/coredns/plugin/cache/handler.go
generated
vendored
75
vendor/github.com/coredns/coredns/plugin/cache/handler.go
generated
vendored
@@ -14,50 +14,53 @@ import (
|
||||
|
||||
// ServeDNS implements the plugin.Handler interface.
|
||||
func (c *Cache) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
||||
state := request.Request{W: w, Req: r}
|
||||
rc := r.Copy() // We potentially modify r, to prevent other plugins from seeing this (r is a pointer), copy r into rc.
|
||||
state := request.Request{W: w, Req: rc}
|
||||
do := state.Do()
|
||||
|
||||
zone := plugin.Zones(c.Zones).Matches(state.Name())
|
||||
if zone == "" {
|
||||
return plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r)
|
||||
return plugin.NextOrFailure(c.Name(), c.Next, ctx, w, rc)
|
||||
}
|
||||
|
||||
now := c.now().UTC()
|
||||
|
||||
server := metrics.WithServer(ctx)
|
||||
|
||||
// On cache miss, if the request has the OPT record and the DO bit set we leave the message as-is. If there isn't a DO bit
|
||||
// set we will modify the request to _add_ one. This means we will always do DNSSEC lookups on cache misses.
|
||||
// When writing to cache, any DNSSEC RRs in the response are written to cache with the response.
|
||||
// When sending a response to a non-DNSSEC client, we remove DNSSEC RRs from the response. We use a 2048 buffer size, which is
|
||||
// less than 4096 (and older default) and more than 1024 which may be too small. We might need to tweaks this
|
||||
// value to be smaller still to prevent UDP fragmentation?
|
||||
|
||||
ttl := 0
|
||||
i := c.getIgnoreTTL(now, state, server)
|
||||
if i != nil {
|
||||
ttl = i.ttl(now)
|
||||
}
|
||||
if i == nil {
|
||||
crr := &ResponseWriter{ResponseWriter: w, Cache: c, state: state, server: server}
|
||||
return plugin.NextOrFailure(c.Name(), c.Next, ctx, crr, r)
|
||||
crr := &ResponseWriter{ResponseWriter: w, Cache: c, state: state, server: server, do: do}
|
||||
return c.doRefresh(ctx, state, crr)
|
||||
}
|
||||
if ttl < 0 {
|
||||
servedStale.WithLabelValues(server).Inc()
|
||||
// Adjust the time to get a 0 TTL in the reply built from a stale item.
|
||||
now = now.Add(time.Duration(ttl) * time.Second)
|
||||
go func() {
|
||||
r := r.Copy()
|
||||
crr := &ResponseWriter{Cache: c, state: state, server: server, prefetch: true, remoteAddr: w.LocalAddr()}
|
||||
plugin.NextOrFailure(c.Name(), c.Next, ctx, crr, r)
|
||||
}()
|
||||
cw := newPrefetchResponseWriter(server, state, c)
|
||||
go c.doPrefetch(ctx, state, cw, i, now)
|
||||
} else if c.shouldPrefetch(i, now) {
|
||||
cw := newPrefetchResponseWriter(server, state, c)
|
||||
go c.doPrefetch(ctx, state, cw, i, now)
|
||||
}
|
||||
resp := i.toMsg(r, now)
|
||||
resp := i.toMsg(r, now, do)
|
||||
w.WriteMsg(resp)
|
||||
|
||||
if c.shouldPrefetch(i, now) {
|
||||
go c.doPrefetch(ctx, state, server, i, now)
|
||||
}
|
||||
return dns.RcodeSuccess, nil
|
||||
}
|
||||
|
||||
func (c *Cache) doPrefetch(ctx context.Context, state request.Request, server string, i *item, now time.Time) {
|
||||
cw := newPrefetchResponseWriter(server, state, c)
|
||||
|
||||
cachePrefetches.WithLabelValues(server).Inc()
|
||||
plugin.NextOrFailure(c.Name(), c.Next, ctx, cw, state.Req)
|
||||
func (c *Cache) doPrefetch(ctx context.Context, state request.Request, cw *ResponseWriter, i *item, now time.Time) {
|
||||
cachePrefetches.WithLabelValues(cw.server).Inc()
|
||||
c.doRefresh(ctx, state, cw)
|
||||
|
||||
// When prefetching we loose the item i, and with it the frequency
|
||||
// that we've gathered sofar. See we copy the frequencies info back
|
||||
@@ -67,6 +70,13 @@ func (c *Cache) doPrefetch(ctx context.Context, state request.Request, server st
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) doRefresh(ctx context.Context, state request.Request, cw *ResponseWriter) (int, error) {
|
||||
if !state.Do() {
|
||||
setDo(state.Req)
|
||||
}
|
||||
return plugin.NextOrFailure(c.Name(), c.Next, ctx, cw, state.Req)
|
||||
}
|
||||
|
||||
func (c *Cache) shouldPrefetch(i *item, now time.Time) bool {
|
||||
if c.prefetch <= 0 {
|
||||
return false
|
||||
@@ -80,7 +90,8 @@ func (c *Cache) shouldPrefetch(i *item, now time.Time) bool {
|
||||
func (c *Cache) Name() string { return "cache" }
|
||||
|
||||
func (c *Cache) get(now time.Time, state request.Request, server string) (*item, bool) {
|
||||
k := hash(state.Name(), state.QType(), state.Do())
|
||||
k := hash(state.Name(), state.QType())
|
||||
cacheRequests.WithLabelValues(server).Inc()
|
||||
|
||||
if i, ok := c.ncache.Get(k); ok && i.(*item).ttl(now) > 0 {
|
||||
cacheHits.WithLabelValues(server, Denial).Inc()
|
||||
@@ -97,7 +108,8 @@ func (c *Cache) get(now time.Time, state request.Request, server string) (*item,
|
||||
|
||||
// getIgnoreTTL unconditionally returns an item if it exists in the cache.
|
||||
func (c *Cache) getIgnoreTTL(now time.Time, state request.Request, server string) *item {
|
||||
k := hash(state.Name(), state.QType(), state.Do())
|
||||
k := hash(state.Name(), state.QType())
|
||||
cacheRequests.WithLabelValues(server).Inc()
|
||||
|
||||
if i, ok := c.ncache.Get(k); ok {
|
||||
ttl := i.(*item).ttl(now)
|
||||
@@ -118,7 +130,7 @@ func (c *Cache) getIgnoreTTL(now time.Time, state request.Request, server string
|
||||
}
|
||||
|
||||
func (c *Cache) exists(state request.Request) *item {
|
||||
k := hash(state.Name(), state.QType(), state.Do())
|
||||
k := hash(state.Name(), state.QType())
|
||||
if i, ok := c.ncache.Get(k); ok {
|
||||
return i.(*item)
|
||||
}
|
||||
@@ -127,3 +139,22 @@ func (c *Cache) exists(state request.Request) *item {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setDo sets the DO bit and UDP buffer size in the message m.
|
||||
func setDo(m *dns.Msg) {
|
||||
o := m.IsEdns0()
|
||||
if o != nil {
|
||||
o.SetDo()
|
||||
o.SetUDPSize(defaultUDPBufSize)
|
||||
return
|
||||
}
|
||||
|
||||
o = &dns.OPT{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeOPT}}
|
||||
o.SetDo()
|
||||
o.SetUDPSize(defaultUDPBufSize)
|
||||
m.Extra = append(m.Extra, o)
|
||||
}
|
||||
|
||||
// defaultUDPBufsize is the bufsize the cache plugin uses on outgoing requests that don't
|
||||
// have an OPT RR.
|
||||
const defaultUDPBufSize = 2048
|
||||
|
23
vendor/github.com/coredns/coredns/plugin/cache/item.go
generated
vendored
23
vendor/github.com/coredns/coredns/plugin/cache/item.go
generated
vendored
@@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/coredns/coredns/plugin/cache/freq"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
@@ -55,7 +56,7 @@ func newItem(m *dns.Msg, now time.Time, d time.Duration) *item {
|
||||
// So we're forced to always set this to 1; regardless if the answer came from the cache or not.
|
||||
// On newer systems(e.g. ubuntu 16.04 with glib version 2.23), this issue is resolved.
|
||||
// So we may set this bit back to 0 in the future ?
|
||||
func (i *item) toMsg(m *dns.Msg, now time.Time) *dns.Msg {
|
||||
func (i *item) toMsg(m *dns.Msg, now time.Time, do bool) *dns.Msg {
|
||||
m1 := new(dns.Msg)
|
||||
m1.SetReply(m)
|
||||
|
||||
@@ -64,6 +65,9 @@ func (i *item) toMsg(m *dns.Msg, now time.Time) *dns.Msg {
|
||||
// just set it to true.
|
||||
m1.Authoritative = true
|
||||
m1.AuthenticatedData = i.AuthenticatedData
|
||||
if !do {
|
||||
m1.AuthenticatedData = false // when DNSSEC was not wanted, it can't be authenticated data.
|
||||
}
|
||||
m1.RecursionAvailable = i.RecursionAvailable
|
||||
m1.Rcode = i.Rcode
|
||||
|
||||
@@ -72,19 +76,10 @@ func (i *item) toMsg(m *dns.Msg, now time.Time) *dns.Msg {
|
||||
m1.Extra = make([]dns.RR, len(i.Extra))
|
||||
|
||||
ttl := uint32(i.ttl(now))
|
||||
for j, r := range i.Answer {
|
||||
m1.Answer[j] = dns.Copy(r)
|
||||
m1.Answer[j].Header().Ttl = ttl
|
||||
}
|
||||
for j, r := range i.Ns {
|
||||
m1.Ns[j] = dns.Copy(r)
|
||||
m1.Ns[j].Header().Ttl = ttl
|
||||
}
|
||||
// newItem skips OPT records, so we can just use i.Extra as is.
|
||||
for j, r := range i.Extra {
|
||||
m1.Extra[j] = dns.Copy(r)
|
||||
m1.Extra[j].Header().Ttl = ttl
|
||||
}
|
||||
m1.Answer = filterRRSlice(i.Answer, ttl, do, true)
|
||||
m1.Ns = filterRRSlice(i.Ns, ttl, do, true)
|
||||
m1.Extra = filterRRSlice(i.Extra, ttl, do, true)
|
||||
|
||||
return m1
|
||||
}
|
||||
|
||||
|
33
vendor/github.com/coredns/coredns/plugin/cache/metrics.go
generated
vendored
33
vendor/github.com/coredns/coredns/plugin/cache/metrics.go
generated
vendored
@@ -4,49 +4,64 @@ import (
|
||||
"github.com/coredns/coredns/plugin"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
)
|
||||
|
||||
var (
|
||||
// cacheSize is total elements in the cache by cache type.
|
||||
cacheSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
cacheSize = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "entries",
|
||||
Help: "The number of elements in the cache.",
|
||||
}, []string{"server", "type"})
|
||||
// cacheRequests is a counter of all requests through the cache.
|
||||
cacheRequests = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "requests_total",
|
||||
Help: "The count of cache requests.",
|
||||
}, []string{"server"})
|
||||
// cacheHits is counter of cache hits by cache type.
|
||||
cacheHits = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
cacheHits = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "hits_total",
|
||||
Help: "The count of cache hits.",
|
||||
}, []string{"server", "type"})
|
||||
// cacheMisses is the counter of cache misses.
|
||||
cacheMisses = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
// cacheMisses is the counter of cache misses. - Deprecated
|
||||
cacheMisses = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "misses_total",
|
||||
Help: "The count of cache misses.",
|
||||
Help: "The count of cache misses. Deprecated, derive misses from cache hits/requests counters.",
|
||||
}, []string{"server"})
|
||||
// cachePrefetches is the number of time the cache has prefetched a cached item.
|
||||
cachePrefetches = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
cachePrefetches = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "prefetch_total",
|
||||
Help: "The number of time the cache has prefetched a cached item.",
|
||||
Help: "The number of times the cache has prefetched a cached item.",
|
||||
}, []string{"server"})
|
||||
// cacheDrops is the number responses that are not cached, because the reply is malformed.
|
||||
cacheDrops = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
cacheDrops = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "drops_total",
|
||||
Help: "The number responses that are not cached, because the reply is malformed.",
|
||||
}, []string{"server"})
|
||||
// servedStale is the number of requests served from stale cache entries.
|
||||
servedStale = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
servedStale = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "served_stale_total",
|
||||
Help: "The number of requests served from stale cache entries.",
|
||||
}, []string{"server"})
|
||||
// evictions is the counter of cache evictions.
|
||||
evictions = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: "cache",
|
||||
Name: "evictions_total",
|
||||
Help: "The count of cache evictions.",
|
||||
}, []string{"server", "type"})
|
||||
)
|
||||
|
22
vendor/github.com/coredns/coredns/plugin/cache/setup.go
generated
vendored
22
vendor/github.com/coredns/coredns/plugin/cache/setup.go
generated
vendored
@@ -6,13 +6,11 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/core/dnsserver"
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/metrics"
|
||||
"github.com/coredns/coredns/plugin/pkg/cache"
|
||||
clog "github.com/coredns/coredns/plugin/pkg/log"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
)
|
||||
|
||||
var log = clog.NewWithPlugin("cache")
|
||||
@@ -29,13 +27,6 @@ func setup(c *caddy.Controller) error {
|
||||
return ca
|
||||
})
|
||||
|
||||
c.OnStartup(func() error {
|
||||
metrics.MustRegister(c,
|
||||
cacheSize, cacheHits, cacheMisses,
|
||||
cachePrefetches, cacheDrops, servedStale)
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -50,10 +41,7 @@ func cacheParse(c *caddy.Controller) (*Cache, error) {
|
||||
j++
|
||||
|
||||
// cache [ttl] [zones..]
|
||||
origins := make([]string, len(c.ServerBlockKeys))
|
||||
copy(origins, c.ServerBlockKeys)
|
||||
args := c.RemainingArgs()
|
||||
|
||||
if len(args) > 0 {
|
||||
// first args may be just a number, then it is the ttl, if not it is a zone
|
||||
ttl, err := strconv.Atoi(args[0])
|
||||
@@ -66,10 +54,8 @@ func cacheParse(c *caddy.Controller) (*Cache, error) {
|
||||
ca.nttl = time.Duration(ttl) * time.Second
|
||||
args = args[1:]
|
||||
}
|
||||
if len(args) > 0 {
|
||||
copy(origins, args)
|
||||
}
|
||||
}
|
||||
origins := plugin.OriginsFromArgsOrServerBlock(args, c.ServerBlockKeys)
|
||||
|
||||
// Refinements? In an extra block.
|
||||
for c.NextBlock() {
|
||||
@@ -198,11 +184,7 @@ func cacheParse(c *caddy.Controller) (*Cache, error) {
|
||||
}
|
||||
}
|
||||
|
||||
for i := range origins {
|
||||
origins[i] = plugin.Host(origins[i]).Normalize()
|
||||
}
|
||||
ca.Zones = origins
|
||||
|
||||
ca.pcache = cache.New(ca.pcap)
|
||||
ca.ncache = cache.New(ca.ncap)
|
||||
}
|
||||
|
6
vendor/github.com/coredns/coredns/plugin/metrics/README.md
generated
vendored
6
vendor/github.com/coredns/coredns/plugin/metrics/README.md
generated
vendored
@@ -17,7 +17,7 @@ The following metrics are exported:
|
||||
* `coredns_dns_request_size_bytes{server, zone, proto}` - size of the request in bytes.
|
||||
* `coredns_dns_do_requests_total{server, zone}` - queries that have the DO bit set
|
||||
* `coredns_dns_response_size_bytes{server, zone, proto}` - response size in bytes.
|
||||
* `coredns_dns_responses_total{server, zone, rcode}` - response per zone and rcode.
|
||||
* `coredns_dns_responses_total{server, zone, rcode, plugin}` - response per zone, rcode and plugin.
|
||||
* `coredns_plugin_enabled{server, zone, name}` - indicates whether a plugin is enabled on per server and zone basis.
|
||||
|
||||
Each counter has a label `zone` which is the zonename used for the request/response.
|
||||
@@ -30,8 +30,10 @@ Extra labels used are:
|
||||
* `proto` which holds the transport of the response ("udp" or "tcp")
|
||||
* The address family (`family`) of the transport (1 = IP (IP version 4), 2 = IP6 (IP version 6)).
|
||||
* `type` which holds the query type. It holds most common types (A, AAAA, MX, SOA, CNAME, PTR, TXT,
|
||||
NS, SRV, DS, DNSKEY, RRSIG, NSEC, NSEC3, IXFR, AXFR and ANY) and "other" which lumps together all
|
||||
NS, SRV, DS, DNSKEY, RRSIG, NSEC, NSEC3, HTTPS, IXFR, AXFR and ANY) and "other" which lumps together all
|
||||
other types.
|
||||
* the `plugin` label holds the name of the plugin that made the write to the client. If the server
|
||||
did the write (on error for instance), the value is empty.
|
||||
|
||||
If monitoring is enabled, queries that do not enter the plugin chain are exported under the fake
|
||||
name "dropped" (without a closing dot - this is never a valid domain name).
|
||||
|
28
vendor/github.com/coredns/coredns/plugin/metrics/handler.go
generated
vendored
28
vendor/github.com/coredns/coredns/plugin/metrics/handler.go
generated
vendored
@@ -2,10 +2,10 @@ package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/metrics/vars"
|
||||
"github.com/coredns/coredns/plugin/pkg/dnstest"
|
||||
"github.com/coredns/coredns/plugin/pkg/rcode"
|
||||
"github.com/coredns/coredns/request"
|
||||
|
||||
@@ -23,13 +23,35 @@ func (m *Metrics) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
|
||||
}
|
||||
|
||||
// Record response to get status code and size of the reply.
|
||||
rw := dnstest.NewRecorder(w)
|
||||
rw := NewRecorder(w)
|
||||
status, err := plugin.NextOrFailure(m.Name(), m.Next, ctx, rw, r)
|
||||
|
||||
vars.Report(WithServer(ctx), state, zone, rcode.ToString(rw.Rcode), rw.Len, rw.Start)
|
||||
rc := rw.Rcode
|
||||
if !plugin.ClientWrite(status) {
|
||||
// when no response was written, fallback to status returned from next plugin as this status
|
||||
// is actually used as rcode of DNS response
|
||||
// see https://github.com/coredns/coredns/blob/master/core/dnsserver/server.go#L318
|
||||
rc = status
|
||||
}
|
||||
plugin := m.authoritativePlugin(rw.Caller)
|
||||
vars.Report(WithServer(ctx), state, zone, rcode.ToString(rc), plugin, rw.Len, rw.Start)
|
||||
|
||||
return status, err
|
||||
}
|
||||
|
||||
// Name implements the Handler interface.
|
||||
func (m *Metrics) Name() string { return "prometheus" }
|
||||
|
||||
// authoritativePlugin returns which of made the write, if none is found the empty string is returned.
|
||||
func (m *Metrics) authoritativePlugin(caller [3]string) string {
|
||||
// a b and c contain the full path of the caller, the plugin name 2nd last elements
|
||||
// .../coredns/plugin/whoami/whoami.go --> whoami
|
||||
// this is likely FS specific, so use filepath.
|
||||
for _, c := range caller {
|
||||
plug := filepath.Base(filepath.Dir(c))
|
||||
if _, ok := m.plugins[plug]; ok {
|
||||
return plug
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
37
vendor/github.com/coredns/coredns/plugin/metrics/metrics.go
generated
vendored
37
vendor/github.com/coredns/coredns/plugin/metrics/metrics.go
generated
vendored
@@ -8,11 +8,12 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/metrics/vars"
|
||||
"github.com/coredns/coredns/plugin/pkg/reuseport"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
@@ -31,29 +32,18 @@ type Metrics struct {
|
||||
zoneNames []string
|
||||
zoneMap map[string]struct{}
|
||||
zoneMu sync.RWMutex
|
||||
|
||||
plugins map[string]struct{} // all available plugins, used to determine which plugin made the client write
|
||||
}
|
||||
|
||||
// New returns a new instance of Metrics with the given address.
|
||||
func New(addr string) *Metrics {
|
||||
met := &Metrics{
|
||||
Addr: addr,
|
||||
Reg: prometheus.NewRegistry(),
|
||||
Reg: prometheus.DefaultRegisterer.(*prometheus.Registry),
|
||||
zoneMap: make(map[string]struct{}),
|
||||
plugins: pluginList(caddy.ListPlugins()),
|
||||
}
|
||||
// Add the default collectors
|
||||
met.MustRegister(prometheus.NewGoCollector())
|
||||
met.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
|
||||
|
||||
// Add all of our collectors
|
||||
met.MustRegister(buildInfo)
|
||||
met.MustRegister(vars.Panic)
|
||||
met.MustRegister(vars.RequestCount)
|
||||
met.MustRegister(vars.RequestDuration)
|
||||
met.MustRegister(vars.RequestSize)
|
||||
met.MustRegister(vars.RequestDo)
|
||||
met.MustRegister(vars.ResponseSize)
|
||||
met.MustRegister(vars.ResponseRcode)
|
||||
met.MustRegister(vars.PluginEnabled)
|
||||
|
||||
return met
|
||||
}
|
||||
@@ -154,6 +144,19 @@ func keys(m map[string]struct{}) []string {
|
||||
return sx
|
||||
}
|
||||
|
||||
// pluginList iterates over the returned plugin map from caddy and removes the "dns." prefix from them.
|
||||
func pluginList(m map[string][]string) map[string]struct{} {
|
||||
pm := map[string]struct{}{}
|
||||
for _, p := range m["others"] {
|
||||
// only add 'dns.' plugins
|
||||
if len(p) > 3 {
|
||||
pm[p[4:]] = struct{}{}
|
||||
continue
|
||||
}
|
||||
}
|
||||
return pm
|
||||
}
|
||||
|
||||
// ListenAddr is assigned the address of the prometheus listener. Its use is mainly in tests where
|
||||
// we listen on "localhost:0" and need to retrieve the actual address.
|
||||
var ListenAddr string
|
||||
@@ -162,7 +165,7 @@ var ListenAddr string
|
||||
// before erroring when it tries to close the metrics server
|
||||
const shutdownTimeout time.Duration = time.Second * 5
|
||||
|
||||
var buildInfo = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
var buildInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Name: "build_info",
|
||||
Help: "A metric with a constant '1' value labeled by version, revision, and goversion from which CoreDNS was built.",
|
||||
|
30
vendor/github.com/coredns/coredns/plugin/metrics/recorder.go
generated
vendored
Normal file
30
vendor/github.com/coredns/coredns/plugin/metrics/recorder.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/coredns/coredns/plugin/pkg/dnstest"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Recorder is a dnstest.Recorder specific to the metrics plugin.
|
||||
type Recorder struct {
|
||||
*dnstest.Recorder
|
||||
// CallerN holds the string return value of the call to runtime.Caller(N+1)
|
||||
Caller [3]string
|
||||
}
|
||||
|
||||
// NewRecorder makes and returns a new Recorder.
|
||||
func NewRecorder(w dns.ResponseWriter) *Recorder { return &Recorder{Recorder: dnstest.NewRecorder(w)} }
|
||||
|
||||
// WriteMsg records the status code and calls the
|
||||
// underlying ResponseWriter's WriteMsg method.
|
||||
func (r *Recorder) WriteMsg(res *dns.Msg) error {
|
||||
_, r.Caller[0], _, _ = runtime.Caller(1)
|
||||
_, r.Caller[1], _, _ = runtime.Caller(2)
|
||||
_, r.Caller[2], _, _ = runtime.Caller(3)
|
||||
r.Len += res.Len()
|
||||
r.Msg = res
|
||||
return r.ResponseWriter.WriteMsg(res)
|
||||
}
|
23
vendor/github.com/coredns/coredns/plugin/metrics/register.go
generated
vendored
23
vendor/github.com/coredns/coredns/plugin/metrics/register.go
generated
vendored
@@ -1,23 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/coredns/coredns/core/dnsserver"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// MustRegister registers the prometheus Collectors when the metrics plugin is used.
|
||||
func MustRegister(c *caddy.Controller, cs ...prometheus.Collector) {
|
||||
m := dnsserver.GetConfig(c).Handler("prometheus")
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
x, ok := m.(*Metrics)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, c := range cs {
|
||||
x.MustRegister(c)
|
||||
}
|
||||
}
|
8
vendor/github.com/coredns/coredns/plugin/metrics/setup.go
generated
vendored
8
vendor/github.com/coredns/coredns/plugin/metrics/setup.go
generated
vendored
@@ -4,14 +4,13 @@ import (
|
||||
"net"
|
||||
"runtime"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/core/dnsserver"
|
||||
"github.com/coredns/coredns/coremain"
|
||||
"github.com/coredns/coredns/plugin"
|
||||
"github.com/coredns/coredns/plugin/metrics/vars"
|
||||
clog "github.com/coredns/coredns/plugin/pkg/log"
|
||||
"github.com/coredns/coredns/plugin/pkg/uniq"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -81,8 +80,9 @@ func parse(c *caddy.Controller) (*Metrics, error) {
|
||||
}
|
||||
i++
|
||||
|
||||
for _, z := range c.ServerBlockKeys {
|
||||
met.AddZone(plugin.Host(z).Normalize())
|
||||
zones := plugin.OriginsFromArgsOrServerBlock(nil /* args */, c.ServerBlockKeys)
|
||||
for _, z := range zones {
|
||||
met.AddZone(z)
|
||||
}
|
||||
args := c.RemainingArgs()
|
||||
|
||||
|
36
vendor/github.com/coredns/coredns/plugin/metrics/vars/monitor.go
generated
vendored
Normal file
36
vendor/github.com/coredns/coredns/plugin/metrics/vars/monitor.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
package vars
|
||||
|
||||
import (
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
var monitorType = map[uint16]struct{}{
|
||||
dns.TypeAAAA: {},
|
||||
dns.TypeA: {},
|
||||
dns.TypeCNAME: {},
|
||||
dns.TypeDNSKEY: {},
|
||||
dns.TypeDS: {},
|
||||
dns.TypeMX: {},
|
||||
dns.TypeNSEC3: {},
|
||||
dns.TypeNSEC: {},
|
||||
dns.TypeNS: {},
|
||||
dns.TypePTR: {},
|
||||
dns.TypeRRSIG: {},
|
||||
dns.TypeSOA: {},
|
||||
dns.TypeSRV: {},
|
||||
dns.TypeTXT: {},
|
||||
dns.TypeHTTPS: {},
|
||||
// Meta Qtypes
|
||||
dns.TypeIXFR: {},
|
||||
dns.TypeAXFR: {},
|
||||
dns.TypeANY: {},
|
||||
}
|
||||
|
||||
// qTypeString returns the RR type based on monitorType. It returns the text representation
|
||||
// of those types. RR types not in that list will have "other" returned.
|
||||
func qTypeString(qtype uint16) string {
|
||||
if _, known := monitorType[qtype]; known {
|
||||
return dns.Type(qtype).String()
|
||||
}
|
||||
return "other"
|
||||
}
|
42
vendor/github.com/coredns/coredns/plugin/metrics/vars/report.go
generated
vendored
42
vendor/github.com/coredns/coredns/plugin/metrics/vars/report.go
generated
vendored
@@ -4,14 +4,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/coredns/coredns/request"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Report reports the metrics data associated with request. This function is exported because it is also
|
||||
// called from core/dnsserver to report requests hitting the server that should not be handled and are thus
|
||||
// not sent down the plugin chain.
|
||||
func Report(server string, req request.Request, zone, rcode string, size int, start time.Time) {
|
||||
func Report(server string, req request.Request, zone, rcode, plugin string, size int, start time.Time) {
|
||||
// Proto and Family.
|
||||
net := req.Proto()
|
||||
fam := "1"
|
||||
@@ -19,45 +17,17 @@ func Report(server string, req request.Request, zone, rcode string, size int, st
|
||||
fam = "2"
|
||||
}
|
||||
|
||||
typ := req.QType()
|
||||
|
||||
if req.Do() {
|
||||
RequestDo.WithLabelValues(server, zone).Inc()
|
||||
}
|
||||
|
||||
if _, known := monitorType[typ]; known {
|
||||
RequestCount.WithLabelValues(server, zone, net, fam, dns.Type(typ).String()).Inc()
|
||||
RequestDuration.WithLabelValues(server, zone, dns.Type(typ).String()).Observe(time.Since(start).Seconds())
|
||||
} else {
|
||||
RequestCount.WithLabelValues(server, zone, net, fam, other).Inc()
|
||||
RequestDuration.WithLabelValues(server, zone, other).Observe(time.Since(start).Seconds())
|
||||
}
|
||||
qType := qTypeString(req.QType())
|
||||
RequestCount.WithLabelValues(server, zone, net, fam, qType).Inc()
|
||||
|
||||
RequestDuration.WithLabelValues(server, zone).Observe(time.Since(start).Seconds())
|
||||
|
||||
ResponseSize.WithLabelValues(server, zone, net).Observe(float64(size))
|
||||
RequestSize.WithLabelValues(server, zone, net).Observe(float64(req.Len()))
|
||||
|
||||
ResponseRcode.WithLabelValues(server, zone, rcode).Inc()
|
||||
ResponseRcode.WithLabelValues(server, zone, rcode, plugin).Inc()
|
||||
}
|
||||
|
||||
var monitorType = map[uint16]struct{}{
|
||||
dns.TypeAAAA: {},
|
||||
dns.TypeA: {},
|
||||
dns.TypeCNAME: {},
|
||||
dns.TypeDNSKEY: {},
|
||||
dns.TypeDS: {},
|
||||
dns.TypeMX: {},
|
||||
dns.TypeNSEC3: {},
|
||||
dns.TypeNSEC: {},
|
||||
dns.TypeNS: {},
|
||||
dns.TypePTR: {},
|
||||
dns.TypeRRSIG: {},
|
||||
dns.TypeSOA: {},
|
||||
dns.TypeSRV: {},
|
||||
dns.TypeTXT: {},
|
||||
// Meta Qtypes
|
||||
dns.TypeIXFR: {},
|
||||
dns.TypeAXFR: {},
|
||||
dns.TypeANY: {},
|
||||
}
|
||||
|
||||
const other = "other"
|
||||
|
25
vendor/github.com/coredns/coredns/plugin/metrics/vars/vars.go
generated
vendored
25
vendor/github.com/coredns/coredns/plugin/metrics/vars/vars.go
generated
vendored
@@ -4,41 +4,42 @@ import (
|
||||
"github.com/coredns/coredns/plugin"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
)
|
||||
|
||||
// Request* and Response* are the prometheus counters and gauges we are using for exporting metrics.
|
||||
var (
|
||||
RequestCount = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
RequestCount = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: "requests_total",
|
||||
Help: "Counter of DNS requests made per zone, protocol and family.",
|
||||
}, []string{"server", "zone", "proto", "family", "type"})
|
||||
|
||||
RequestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
RequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: "request_duration_seconds",
|
||||
Buckets: plugin.TimeBuckets,
|
||||
Help: "Histogram of the time (in seconds) each request took.",
|
||||
}, []string{"server", "zone", "type"})
|
||||
Help: "Histogram of the time (in seconds) each request took per zone.",
|
||||
}, []string{"server", "zone"})
|
||||
|
||||
RequestSize = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
RequestSize = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: "request_size_bytes",
|
||||
Help: "Size of the EDNS0 UDP buffer in bytes (64K for TCP).",
|
||||
Help: "Size of the EDNS0 UDP buffer in bytes (64K for TCP) per zone and protocol.",
|
||||
Buckets: []float64{0, 100, 200, 300, 400, 511, 1023, 2047, 4095, 8291, 16e3, 32e3, 48e3, 64e3},
|
||||
}, []string{"server", "zone", "proto"})
|
||||
|
||||
RequestDo = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
RequestDo = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: "do_requests_total",
|
||||
Help: "Counter of DNS requests with DO bit set per zone.",
|
||||
}, []string{"server", "zone"})
|
||||
|
||||
ResponseSize = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
ResponseSize = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: "response_size_bytes",
|
||||
@@ -46,20 +47,20 @@ var (
|
||||
Buckets: []float64{0, 100, 200, 300, 400, 511, 1023, 2047, 4095, 8291, 16e3, 32e3, 48e3, 64e3},
|
||||
}, []string{"server", "zone", "proto"})
|
||||
|
||||
ResponseRcode = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
ResponseRcode = promauto.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: "responses_total",
|
||||
Help: "Counter of response status codes.",
|
||||
}, []string{"server", "zone", "rcode"})
|
||||
}, []string{"server", "zone", "rcode", "plugin"})
|
||||
|
||||
Panic = prometheus.NewCounter(prometheus.CounterOpts{
|
||||
Panic = promauto.NewCounter(prometheus.CounterOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Name: "panics_total",
|
||||
Help: "A metrics that counts the number of panics.",
|
||||
})
|
||||
|
||||
PluginEnabled = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
PluginEnabled = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Namespace: plugin.Namespace,
|
||||
Name: "plugin_enabled",
|
||||
Help: "A metric that indicates whether a plugin is enabled on per server and zone basis.",
|
||||
|
139
vendor/github.com/coredns/coredns/plugin/normalize.go
generated
vendored
139
vendor/github.com/coredns/coredns/plugin/normalize.go
generated
vendored
@@ -3,10 +3,14 @@ package plugin
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/coredns/coredns/plugin/pkg/cidr"
|
||||
"github.com/coredns/coredns/plugin/pkg/log"
|
||||
"github.com/coredns/coredns/plugin/pkg/parse"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
@@ -62,81 +66,132 @@ type (
|
||||
// Normalize will return the host portion of host, stripping
|
||||
// of any port or transport. The host will also be fully qualified and lowercased.
|
||||
// An empty string is returned on failure
|
||||
// Deprecated: use OriginsFromArgsOrServerBlock or NormalizeExact
|
||||
func (h Host) Normalize() string {
|
||||
// The error can be ignored here, because this function should only be called after the corefile has already been vetted.
|
||||
host, _ := h.MustNormalize()
|
||||
return host
|
||||
var caller string
|
||||
if _, file, line, ok := runtime.Caller(1); ok {
|
||||
caller = fmt.Sprintf("(%v line %d) ", file, line)
|
||||
}
|
||||
log.Warning("An external plugin " + caller + "is using the deprecated function Normalize. " +
|
||||
"This will be removed in a future versions of CoreDNS. The plugin should be updated to use " +
|
||||
"OriginsFromArgsOrServerBlock or NormalizeExact instead.")
|
||||
|
||||
s := string(h)
|
||||
_, s = parse.Transport(s)
|
||||
|
||||
// The error can be ignored here, because this function is called after the corefile has already been vetted.
|
||||
hosts, _, err := SplitHostPort(s)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return Name(hosts[0]).Normalize()
|
||||
}
|
||||
|
||||
// MustNormalize will return the host portion of host, stripping
|
||||
// of any port or transport. The host will also be fully qualified and lowercased.
|
||||
// An error is returned on error
|
||||
// Deprecated: use OriginsFromArgsOrServerBlock or NormalizeExact
|
||||
func (h Host) MustNormalize() (string, error) {
|
||||
var caller string
|
||||
if _, file, line, ok := runtime.Caller(1); ok {
|
||||
caller = fmt.Sprintf("(%v line %d) ", file, line)
|
||||
}
|
||||
log.Warning("An external plugin " + caller + "is using the deprecated function MustNormalize. " +
|
||||
"This will be removed in a future versions of CoreDNS. The plugin should be updated to use " +
|
||||
"OriginsFromArgsOrServerBlock or NormalizeExact instead.")
|
||||
|
||||
s := string(h)
|
||||
_, s = parse.Transport(s)
|
||||
|
||||
// The error can be ignored here, because this function is called after the corefile has already been vetted.
|
||||
host, _, _, err := SplitHostPort(s)
|
||||
hosts, _, err := SplitHostPort(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return Name(host).Normalize(), nil
|
||||
return Name(hosts[0]).Normalize(), nil
|
||||
}
|
||||
|
||||
// SplitHostPort splits s up in a host and port portion, taking reverse address notation into account.
|
||||
// String the string s should *not* be prefixed with any protocols, i.e. dns://. The returned ipnet is the
|
||||
// *net.IPNet that is used when the zone is a reverse and a netmask is given.
|
||||
func SplitHostPort(s string) (host, port string, ipnet *net.IPNet, err error) {
|
||||
// NormalizeExact will return the host portion of host, stripping
|
||||
// of any port or transport. The host will also be fully qualified and lowercased.
|
||||
// An empty slice is returned on failure
|
||||
func (h Host) NormalizeExact() []string {
|
||||
// The error can be ignored here, because this function should only be called after the corefile has already been vetted.
|
||||
s := string(h)
|
||||
_, s = parse.Transport(s)
|
||||
|
||||
hosts, _, err := SplitHostPort(s)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for i := range hosts {
|
||||
hosts[i] = Name(hosts[i]).Normalize()
|
||||
|
||||
}
|
||||
return hosts
|
||||
}
|
||||
|
||||
// SplitHostPort splits s up in a host(s) and port portion, taking reverse address notation into account.
|
||||
// String the string s should *not* be prefixed with any protocols, i.e. dns://. SplitHostPort can return
|
||||
// multiple hosts when a reverse notation on a non-octet boundary is given.
|
||||
func SplitHostPort(s string) (hosts []string, port string, err error) {
|
||||
// If there is: :[0-9]+ on the end we assume this is the port. This works for (ascii) domain
|
||||
// names and our reverse syntax, which always needs a /mask *before* the port.
|
||||
// So from the back, find first colon, and then check if it's a number.
|
||||
host = s
|
||||
|
||||
colon := strings.LastIndex(s, ":")
|
||||
if colon == len(s)-1 {
|
||||
return "", "", nil, fmt.Errorf("expecting data after last colon: %q", s)
|
||||
return nil, "", fmt.Errorf("expecting data after last colon: %q", s)
|
||||
}
|
||||
if colon != -1 {
|
||||
if p, err := strconv.Atoi(s[colon+1:]); err == nil {
|
||||
port = strconv.Itoa(p)
|
||||
host = s[:colon]
|
||||
s = s[:colon]
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(miek): this should take escaping into account.
|
||||
if len(host) > 255 {
|
||||
return "", "", nil, fmt.Errorf("specified zone is too long: %d > 255", len(host))
|
||||
if len(s) > 255 {
|
||||
return nil, "", fmt.Errorf("specified zone is too long: %d > 255", len(s))
|
||||
}
|
||||
|
||||
_, d := dns.IsDomainName(host)
|
||||
if !d {
|
||||
return "", "", nil, fmt.Errorf("zone is not a valid domain name: %s", host)
|
||||
if _, ok := dns.IsDomainName(s); !ok {
|
||||
return nil, "", fmt.Errorf("zone is not a valid domain name: %s", s)
|
||||
}
|
||||
|
||||
// Check if it parses as a reverse zone, if so we use that. Must be fully specified IP and mask.
|
||||
ip, n, err := net.ParseCIDR(host)
|
||||
ones, bits := 0, 0
|
||||
if err == nil {
|
||||
if rev, e := dns.ReverseAddr(ip.String()); e == nil {
|
||||
ones, bits = n.Mask.Size()
|
||||
// get the size, in bits, of each portion of hostname defined in the reverse address. (8 for IPv4, 4 for IPv6)
|
||||
sizeDigit := 8
|
||||
if len(n.IP) == net.IPv6len {
|
||||
sizeDigit = 4
|
||||
}
|
||||
// Get the first lower octet boundary to see what encompassing zone we should be authoritative for.
|
||||
mod := (bits - ones) % sizeDigit
|
||||
nearest := (bits - ones) + mod
|
||||
offset := 0
|
||||
var end bool
|
||||
for i := 0; i < nearest/sizeDigit; i++ {
|
||||
offset, end = dns.NextLabel(rev, offset)
|
||||
if end {
|
||||
break
|
||||
}
|
||||
}
|
||||
host = rev[offset:]
|
||||
}
|
||||
_, n, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return []string{s}, port, nil
|
||||
}
|
||||
return host, port, n, nil
|
||||
|
||||
if s[0] == ':' || (s[0] == '0' && strings.Contains(s, ":")) {
|
||||
return nil, "", fmt.Errorf("invalid CIDR %s", s)
|
||||
}
|
||||
|
||||
// now check if multiple hosts must be returned.
|
||||
nets := cidr.Split(n)
|
||||
hosts = cidr.Reverse(nets)
|
||||
return hosts, port, nil
|
||||
}
|
||||
|
||||
// OriginsFromArgsOrServerBlock returns the normalized args if that slice
|
||||
// is not empty, otherwise the serverblock slice is returned (in a newly copied slice).
|
||||
func OriginsFromArgsOrServerBlock(args, serverblock []string) []string {
|
||||
if len(args) == 0 {
|
||||
s := make([]string, len(serverblock))
|
||||
copy(s, serverblock)
|
||||
for i := range s {
|
||||
s[i] = Host(s[i]).NormalizeExact()[0] // expansion of these already happened in dnsserver/register.go
|
||||
}
|
||||
return s
|
||||
}
|
||||
s := []string{}
|
||||
for i := range args {
|
||||
sx := Host(args[i]).NormalizeExact()
|
||||
if len(sx) == 0 {
|
||||
continue // silently ignores errors.
|
||||
}
|
||||
s = append(s, sx...)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
38
vendor/github.com/coredns/coredns/plugin/pkg/cache/cache.go
generated
vendored
38
vendor/github.com/coredns/coredns/plugin/pkg/cache/cache.go
generated
vendored
@@ -45,9 +45,10 @@ func New(size int) *Cache {
|
||||
}
|
||||
|
||||
// Add adds a new element to the cache. If the element already exists it is overwritten.
|
||||
func (c *Cache) Add(key uint64, el interface{}) {
|
||||
// Returns true if an existing element was evicted to make room for this element.
|
||||
func (c *Cache) Add(key uint64, el interface{}) bool {
|
||||
shard := key & (shardSize - 1)
|
||||
c.shards[shard].Add(key, el)
|
||||
return c.shards[shard].Add(key, el)
|
||||
}
|
||||
|
||||
// Get looks up element index under key.
|
||||
@@ -71,22 +72,33 @@ func (c *Cache) Len() int {
|
||||
return l
|
||||
}
|
||||
|
||||
// Walk walks each shard in the cache.
|
||||
func (c *Cache) Walk(f func(map[uint64]interface{}, uint64) bool) {
|
||||
for _, s := range c.shards {
|
||||
s.Walk(f)
|
||||
}
|
||||
}
|
||||
|
||||
// newShard returns a new shard with size.
|
||||
func newShard(size int) *shard { return &shard{items: make(map[uint64]interface{}), size: size} }
|
||||
|
||||
// Add adds element indexed by key into the cache. Any existing element is overwritten
|
||||
func (s *shard) Add(key uint64, el interface{}) {
|
||||
// Returns true if an existing element was evicted to make room for this element.
|
||||
func (s *shard) Add(key uint64, el interface{}) bool {
|
||||
eviction := false
|
||||
s.Lock()
|
||||
if len(s.items) >= s.size {
|
||||
if _, ok := s.items[key]; !ok {
|
||||
for k := range s.items {
|
||||
delete(s.items, k)
|
||||
eviction = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
s.items[key] = el
|
||||
s.Unlock()
|
||||
return eviction
|
||||
}
|
||||
|
||||
// Remove removes the element indexed by key from the cache.
|
||||
@@ -122,4 +134,24 @@ func (s *shard) Len() int {
|
||||
return l
|
||||
}
|
||||
|
||||
// Walk walks the shard for each element the function f is executed while holding a write lock.
|
||||
func (s *shard) Walk(f func(map[uint64]interface{}, uint64) bool) {
|
||||
s.RLock()
|
||||
items := make([]uint64, len(s.items))
|
||||
i := 0
|
||||
for k := range s.items {
|
||||
items[i] = k
|
||||
i++
|
||||
}
|
||||
s.RUnlock()
|
||||
for _, k := range items {
|
||||
s.Lock()
|
||||
ok := f(s.items, k)
|
||||
s.Unlock()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shardSize = 256
|
||||
|
83
vendor/github.com/coredns/coredns/plugin/pkg/cidr/cidr.go
generated
vendored
Normal file
83
vendor/github.com/coredns/coredns/plugin/pkg/cidr/cidr.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// Package cidr contains functions that deal with classless reverse zones in the DNS.
|
||||
package cidr
|
||||
|
||||
import (
|
||||
"math"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/apparentlymart/go-cidr/cidr"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Split returns a slice of non-overlapping subnets that in union equal the subnet n,
|
||||
// and where each subnet falls on a reverse name segment boundary.
|
||||
// for ipv4 this is any multiple of 8 bits (/8, /16, /24 or /32)
|
||||
// for ipv6 this is any multiple of 4 bits
|
||||
func Split(n *net.IPNet) []string {
|
||||
boundary := 8
|
||||
nstr := n.String()
|
||||
if strings.Contains(nstr, ":") {
|
||||
boundary = 4
|
||||
}
|
||||
ones, _ := n.Mask.Size()
|
||||
if ones%boundary == 0 {
|
||||
return []string{n.String()}
|
||||
}
|
||||
|
||||
mask := int(math.Ceil(float64(ones)/float64(boundary))) * boundary
|
||||
networks := nets(n, mask)
|
||||
cidrs := make([]string, len(networks))
|
||||
for i := range networks {
|
||||
cidrs[i] = networks[i].String()
|
||||
}
|
||||
return cidrs
|
||||
}
|
||||
|
||||
// nets return a slice of prefixes with the desired mask subnetted from original network.
|
||||
func nets(network *net.IPNet, newPrefixLen int) []*net.IPNet {
|
||||
prefixLen, _ := network.Mask.Size()
|
||||
maxSubnets := int(math.Exp2(float64(newPrefixLen)) / math.Exp2(float64(prefixLen)))
|
||||
nets := []*net.IPNet{{network.IP, net.CIDRMask(newPrefixLen, 8*len(network.IP))}}
|
||||
|
||||
for i := 1; i < maxSubnets; i++ {
|
||||
next, exceeds := cidr.NextSubnet(nets[len(nets)-1], newPrefixLen)
|
||||
nets = append(nets, next)
|
||||
if exceeds {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nets
|
||||
}
|
||||
|
||||
// Reverse return the reverse zones that are authoritative for each net in ns.
|
||||
func Reverse(nets []string) []string {
|
||||
rev := make([]string, len(nets))
|
||||
for i := range nets {
|
||||
ip, n, _ := net.ParseCIDR(nets[i])
|
||||
r, err1 := dns.ReverseAddr(ip.String())
|
||||
if err1 != nil {
|
||||
continue
|
||||
}
|
||||
ones, bits := n.Mask.Size()
|
||||
// get the size, in bits, of each portion of hostname defined in the reverse address. (8 for IPv4, 4 for IPv6)
|
||||
sizeDigit := 8
|
||||
if len(n.IP) == net.IPv6len {
|
||||
sizeDigit = 4
|
||||
}
|
||||
// Get the first lower octet boundary to see what encompassing zone we should be authoritative for.
|
||||
mod := (bits - ones) % sizeDigit
|
||||
nearest := (bits - ones) + mod
|
||||
offset := 0
|
||||
var end bool
|
||||
for i := 0; i < nearest/sizeDigit; i++ {
|
||||
offset, end = dns.NextLabel(r, offset)
|
||||
if end {
|
||||
break
|
||||
}
|
||||
}
|
||||
rev[i] = r[offset:]
|
||||
}
|
||||
return rev
|
||||
}
|
5
vendor/github.com/coredns/coredns/plugin/pkg/doh/doh.go
generated
vendored
5
vendor/github.com/coredns/coredns/plugin/pkg/doh/doh.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
@@ -50,7 +49,6 @@ func NewRequest(method, url string, m *dns.Msg) (*http.Request, error) {
|
||||
default:
|
||||
return nil, fmt.Errorf("method not allowed: %s", method)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ResponseToMsg converts a http.Response to a dns message.
|
||||
@@ -72,7 +70,6 @@ func RequestToMsg(req *http.Request) (*dns.Msg, error) {
|
||||
default:
|
||||
return nil, fmt.Errorf("method not allowed: %s", req.Method)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// requestToMsgPost extracts the dns message from the request body.
|
||||
@@ -95,7 +92,7 @@ func requestToMsgGet(req *http.Request) (*dns.Msg, error) {
|
||||
}
|
||||
|
||||
func toMsg(r io.ReadCloser) (*dns.Msg, error) {
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
buf, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
4
vendor/github.com/coredns/coredns/plugin/pkg/log/log.go
generated
vendored
4
vendor/github.com/coredns/coredns/plugin/pkg/log/log.go
generated
vendored
@@ -10,7 +10,7 @@ package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
golog "log"
|
||||
"os"
|
||||
"sync"
|
||||
@@ -102,7 +102,7 @@ func Fatal(v ...interface{}) { log(fatal, v...); os.Exit(1) }
|
||||
func Fatalf(format string, v ...interface{}) { logf(fatal, format, v...); os.Exit(1) }
|
||||
|
||||
// Discard sets the log output to /dev/null.
|
||||
func Discard() { golog.SetOutput(ioutil.Discard) }
|
||||
func Discard() { golog.SetOutput(io.Discard) }
|
||||
|
||||
const (
|
||||
debug = "[DEBUG] "
|
||||
|
6
vendor/github.com/coredns/coredns/plugin/pkg/parse/host.go
generated
vendored
6
vendor/github.com/coredns/coredns/plugin/pkg/parse/host.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package parse
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@@ -11,6 +12,9 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// ErrNoNameservers is returned by HostPortOrFile if no servers can be parsed.
|
||||
var ErrNoNameservers = errors.New("no nameservers found")
|
||||
|
||||
// Strips the zone, but preserves any port that comes after the zone
|
||||
func stripZone(host string) string {
|
||||
if strings.Contains(host, "%") {
|
||||
@@ -70,7 +74,7 @@ func HostPortOrFile(s ...string) ([]string, error) {
|
||||
servers = append(servers, h)
|
||||
}
|
||||
if len(servers) == 0 {
|
||||
return servers, fmt.Errorf("no nameservers found")
|
||||
return servers, ErrNoNameservers
|
||||
}
|
||||
return servers, nil
|
||||
}
|
||||
|
35
vendor/github.com/coredns/coredns/plugin/pkg/parse/parse.go
generated
vendored
35
vendor/github.com/coredns/coredns/plugin/pkg/parse/parse.go
generated
vendored
@@ -4,46 +4,35 @@ package parse
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
"github.com/coredns/coredns/plugin/pkg/transport"
|
||||
|
||||
"github.com/caddyserver/caddy"
|
||||
)
|
||||
|
||||
// Transfer parses transfer statements: 'transfer [to|from] [address...]'.
|
||||
func Transfer(c *caddy.Controller, secondary bool) (tos, froms []string, err error) {
|
||||
// TransferIn parses transfer statements: 'transfer from [address...]'.
|
||||
func TransferIn(c *caddy.Controller) (froms []string, err error) {
|
||||
if !c.NextArg() {
|
||||
return nil, nil, c.ArgErr()
|
||||
return nil, c.ArgErr()
|
||||
}
|
||||
value := c.Val()
|
||||
switch value {
|
||||
case "to":
|
||||
tos = c.RemainingArgs()
|
||||
for i := range tos {
|
||||
if tos[i] != "*" {
|
||||
normalized, err := HostPort(tos[i], transport.Port)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
tos[i] = normalized
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, c.Errf("unknown property %s", value)
|
||||
case "from":
|
||||
if !secondary {
|
||||
return nil, nil, fmt.Errorf("can't use `transfer from` when not being a secondary")
|
||||
}
|
||||
froms = c.RemainingArgs()
|
||||
if len(froms) == 0 {
|
||||
return nil, c.ArgErr()
|
||||
}
|
||||
for i := range froms {
|
||||
if froms[i] != "*" {
|
||||
normalized, err := HostPort(froms[i], transport.Port)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
froms[i] = normalized
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("can't use '*' in transfer from")
|
||||
return nil, fmt.Errorf("can't use '*' in transfer from")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
return froms, nil
|
||||
}
|
||||
|
1
vendor/github.com/coredns/coredns/plugin/pkg/trace/trace.go
generated
vendored
1
vendor/github.com/coredns/coredns/plugin/pkg/trace/trace.go
generated
vendored
@@ -2,6 +2,7 @@ package trace
|
||||
|
||||
import (
|
||||
"github.com/coredns/coredns/plugin"
|
||||
|
||||
ot "github.com/opentracing/opentracing-go"
|
||||
)
|
||||
|
||||
|
5
vendor/github.com/coredns/coredns/plugin/plugin.go
generated
vendored
5
vendor/github.com/coredns/coredns/plugin/plugin.go
generated
vendored
@@ -69,7 +69,7 @@ func (f HandlerFunc) Name() string { return "handlerfunc" }
|
||||
// Error returns err with 'plugin/name: ' prefixed to it.
|
||||
func Error(name string, err error) error { return fmt.Errorf("%s/%s: %s", "plugin", name, err) }
|
||||
|
||||
// NextOrFailure calls next.ServeDNS when next is not nil, otherwise it will return, a ServerFailure and a nil error.
|
||||
// NextOrFailure calls next.ServeDNS when next is not nil, otherwise it will return, a ServerFailure and a `no next plugin found` error.
|
||||
func NextOrFailure(name string, next Handler, ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { // nolint: golint
|
||||
if next != nil {
|
||||
if span := ot.SpanFromContext(ctx); span != nil {
|
||||
@@ -105,5 +105,8 @@ const Namespace = "coredns"
|
||||
// TimeBuckets is based on Prometheus client_golang prometheus.DefBuckets
|
||||
var TimeBuckets = prometheus.ExponentialBuckets(0.00025, 2, 16) // from 0.25ms to 8 seconds
|
||||
|
||||
// SlimTimeBuckets is low cardinality set of duration buckets.
|
||||
var SlimTimeBuckets = prometheus.ExponentialBuckets(0.00025, 10, 5) // from 0.25ms to 2.5 seconds
|
||||
|
||||
// ErrOnce is returned when a plugin doesn't support multiple setups per server.
|
||||
var ErrOnce = errors.New("this plugin can only be used once per Server Block")
|
||||
|
2
vendor/github.com/coredns/coredns/plugin/register.go
generated
vendored
2
vendor/github.com/coredns/coredns/plugin/register.go
generated
vendored
@@ -1,6 +1,6 @@
|
||||
package plugin
|
||||
|
||||
import "github.com/caddyserver/caddy"
|
||||
import "github.com/coredns/caddy"
|
||||
|
||||
// Register registers your plugin with CoreDNS and allows it to be called when the server is running.
|
||||
func Register(name string, action caddy.SetupFunc) {
|
||||
|
13
vendor/github.com/coredns/coredns/plugin/test/file.go
generated
vendored
13
vendor/github.com/coredns/coredns/plugin/test/file.go
generated
vendored
@@ -1,18 +1,17 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// TempFile will create a temporary file on disk and returns the name and a cleanup function to remove it later.
|
||||
func TempFile(dir, content string) (string, func(), error) {
|
||||
f, err := ioutil.TempFile(dir, "go-test-tmpfile")
|
||||
f, err := os.CreateTemp(dir, "go-test-tmpfile")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := ioutil.WriteFile(f.Name(), []byte(content), 0644); err != nil {
|
||||
if err := os.WriteFile(f.Name(), []byte(content), 0644); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
rmFunc := func() { os.Remove(f.Name()) }
|
||||
@@ -21,7 +20,7 @@ func TempFile(dir, content string) (string, func(), error) {
|
||||
|
||||
// WritePEMFiles creates a tmp dir with ca.pem, cert.pem, and key.pem and the func to remove it
|
||||
func WritePEMFiles(dir string) (string, func(), error) {
|
||||
tempDir, err := ioutil.TempDir(dir, "go-test-pemfiles")
|
||||
tempDir, err := os.MkdirTemp(dir, "go-test-pemfiles")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
@@ -45,7 +44,7 @@ xGbtCkhVk2VQ+BiCWnjYXJ6ZMzabP7wiOFDP9Pvr2ik22PRItsW/TLfHFXM1jDmc
|
||||
I1rs/VUGKzcJGVIWbHrgjP68CTStGAvKgbsTqw7aLXTSqtPw88N9XVSyRg==
|
||||
-----END CERTIFICATE-----`
|
||||
path := filepath.Join(tempDir, "ca.pem")
|
||||
if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
if err := os.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
data = `-----BEGIN CERTIFICATE-----
|
||||
@@ -66,7 +65,7 @@ zhDEPP4FhY+Sz+y1yWirphl7A1aZwhXVPcfWIGqpQ3jzNwUeocbH27kuLh+U4hQo
|
||||
qeg10RdFnw==
|
||||
-----END CERTIFICATE-----`
|
||||
path = filepath.Join(tempDir, "cert.pem")
|
||||
if err = ioutil.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
if err = os.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
@@ -98,7 +97,7 @@ E/WObVJXDnBdViu0L9abE9iaTToBVri4cmlDlZagLuKVR+TFTCN/DSlVZTDkqkLI
|
||||
8chzqtkH6b2b2R73hyRysWjsomys34ma3mEEPTX/aXeAF2MSZ/EWT9yL
|
||||
-----END RSA PRIVATE KEY-----`
|
||||
path = filepath.Join(tempDir, "key.pem")
|
||||
if err = ioutil.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
if err = os.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
|
24
vendor/github.com/coredns/coredns/plugin/test/helpers.go
generated
vendored
24
vendor/github.com/coredns/coredns/plugin/test/helpers.go
generated
vendored
@@ -29,14 +29,15 @@ func (p RRSet) Less(i, j int) bool { return p[i].String() < p[j].String() }
|
||||
// Case represents a test case that encapsulates various data from a query and response.
|
||||
// Note that is the TTL of a record is 303 we don't compare it with the TTL.
|
||||
type Case struct {
|
||||
Qname string
|
||||
Qtype uint16
|
||||
Rcode int
|
||||
Do bool
|
||||
Answer []dns.RR
|
||||
Ns []dns.RR
|
||||
Extra []dns.RR
|
||||
Error error
|
||||
Qname string
|
||||
Qtype uint16
|
||||
Rcode int
|
||||
Do bool
|
||||
AuthenticatedData bool
|
||||
Answer []dns.RR
|
||||
Ns []dns.RR
|
||||
Extra []dns.RR
|
||||
Error error
|
||||
}
|
||||
|
||||
// Msg returns a *dns.Msg embedded in c.
|
||||
@@ -99,6 +100,9 @@ func DNSKEY(rr string) *dns.DNSKEY { r, _ := dns.NewRR(rr); return r.(*dns.DNSKE
|
||||
// DS returns a DS record from rr. It panics on errors.
|
||||
func DS(rr string) *dns.DS { r, _ := dns.NewRR(rr); return r.(*dns.DS) }
|
||||
|
||||
// NAPTR returns a NAPTR record from rr. It panics on errors.
|
||||
func NAPTR(rr string) *dns.NAPTR { r, _ := dns.NewRR(rr); return r.(*dns.NAPTR) }
|
||||
|
||||
// OPT returns an OPT record with UDP buffer size set to bufsize and the DO bit set to do.
|
||||
func OPT(bufsize int, do bool) *dns.OPT {
|
||||
o := new(dns.OPT)
|
||||
@@ -112,7 +116,7 @@ func OPT(bufsize int, do bool) *dns.OPT {
|
||||
return o
|
||||
}
|
||||
|
||||
// Header test if the header in resp matches the header as defined in tc.
|
||||
// Header tests if the header in resp matches the header as defined in tc.
|
||||
func Header(tc Case, resp *dns.Msg) error {
|
||||
if resp.Rcode != tc.Rcode {
|
||||
return fmt.Errorf("rcode is %q, expected %q", dns.RcodeToString[resp.Rcode], dns.RcodeToString[tc.Rcode])
|
||||
@@ -248,7 +252,7 @@ func Section(tc Case, sec sect, rr []dns.RR) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CNAMEOrder makes sure that CNAMES do not appear after their target records
|
||||
// CNAMEOrder makes sure that CNAMES do not appear after their target records.
|
||||
func CNAMEOrder(res *dns.Msg) error {
|
||||
for i, c := range res.Answer {
|
||||
if c.Header().Rrtype != dns.TypeCNAME {
|
||||
|
12
vendor/github.com/coredns/coredns/plugin/test/responsewriter.go
generated
vendored
12
vendor/github.com/coredns/coredns/plugin/test/responsewriter.go
generated
vendored
@@ -38,22 +38,22 @@ func (t *ResponseWriter) RemoteAddr() net.Addr {
|
||||
return &net.UDPAddr{IP: ip, Port: port, Zone: ""}
|
||||
}
|
||||
|
||||
// WriteMsg implement dns.ResponseWriter interface.
|
||||
// WriteMsg implements dns.ResponseWriter interface.
|
||||
func (t *ResponseWriter) WriteMsg(m *dns.Msg) error { return nil }
|
||||
|
||||
// Write implement dns.ResponseWriter interface.
|
||||
// Write implements dns.ResponseWriter interface.
|
||||
func (t *ResponseWriter) Write(buf []byte) (int, error) { return len(buf), nil }
|
||||
|
||||
// Close implement dns.ResponseWriter interface.
|
||||
// Close implements dns.ResponseWriter interface.
|
||||
func (t *ResponseWriter) Close() error { return nil }
|
||||
|
||||
// TsigStatus implement dns.ResponseWriter interface.
|
||||
// TsigStatus implements dns.ResponseWriter interface.
|
||||
func (t *ResponseWriter) TsigStatus() error { return nil }
|
||||
|
||||
// TsigTimersOnly implement dns.ResponseWriter interface.
|
||||
// TsigTimersOnly implements dns.ResponseWriter interface.
|
||||
func (t *ResponseWriter) TsigTimersOnly(bool) {}
|
||||
|
||||
// Hijack implement dns.ResponseWriter interface.
|
||||
// Hijack implements dns.ResponseWriter interface.
|
||||
func (t *ResponseWriter) Hijack() {}
|
||||
|
||||
// ResponseWriter6 returns fixed client and remote address in IPv6. The remote
|
||||
|
2
vendor/github.com/coredns/coredns/plugin/test/scrape.go
generated
vendored
2
vendor/github.com/coredns/coredns/plugin/test/scrape.go
generated
vendored
@@ -77,7 +77,7 @@ func Scrape(url string) []*MetricFamily {
|
||||
return result
|
||||
}
|
||||
|
||||
// ScrapeMetricAsInt provide a sum of all metrics collected for the name and label provided.
|
||||
// ScrapeMetricAsInt provides a sum of all metrics collected for the name and label provided.
|
||||
// if the metric is not a numeric value, it will be counted a 0.
|
||||
func ScrapeMetricAsInt(addr string, name string, label string, nometricvalue int) int {
|
||||
|
||||
|
4
vendor/github.com/coredns/coredns/request/request.go
generated
vendored
4
vendor/github.com/coredns/coredns/request/request.go
generated
vendored
@@ -144,7 +144,7 @@ func (r *Request) Family() int {
|
||||
return 2
|
||||
}
|
||||
|
||||
// Do returns if the request has the DO (DNSSEC OK) bit set.
|
||||
// Do returns true if the request has the DO (DNSSEC OK) bit set.
|
||||
func (r *Request) Do() bool {
|
||||
if r.size != 0 {
|
||||
return r.do
|
||||
@@ -338,6 +338,8 @@ func (r *Request) Clear() {
|
||||
r.port = ""
|
||||
r.localPort = ""
|
||||
r.family = 0
|
||||
r.size = 0
|
||||
r.do = false
|
||||
}
|
||||
|
||||
// Match checks if the reply matches the qname and qtype from the request, it returns
|
||||
|
Reference in New Issue
Block a user