mirror of
https://github.com/coredns/coredns.git
synced 2025-12-09 11:55:13 -05:00
* middleware/metrics: add more metrics middleware/cache: Add metrics for number of elements in the cache. Also export the total size. Update README to detail the new metrics. middleware/metrics Move metrics into subpackage called "vars". This breaks the import cycle and is cleaner. This allows vars.Report to be used in the the dnsserver to log refused queries. middleware/metrics: tests Add tests to the metrics framework. The metrics/test subpackage allows scraping of the local server. Do a few test scrape of the metrics that are defined in the metrics middleware. This also allows metrics integration tests to check if the caching and dnssec middleware export their metrics correctly. * update README * typos * fix tests
122 lines
3.0 KiB
Go
122 lines
3.0 KiB
Go
// Package rewrite is middleware for rewriting requests internally to something different.
|
|
package rewrite
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/miekg/coredns/middleware"
|
|
|
|
"github.com/miekg/dns"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
// Result is the result of a rewrite
|
|
type Result int
|
|
|
|
const (
|
|
// RewriteIgnored is returned when rewrite is not done on request.
|
|
RewriteIgnored Result = iota
|
|
// RewriteDone is returned when rewrite is done on request.
|
|
RewriteDone
|
|
// RewriteStatus is returned when rewrite is not needed and status code should be set
|
|
// for the request.
|
|
RewriteStatus
|
|
)
|
|
|
|
// Rewrite is middleware to rewrite requests internally before being handled.
|
|
type Rewrite struct {
|
|
Next middleware.Handler
|
|
Rules []Rule
|
|
noRevert bool
|
|
}
|
|
|
|
// ServeDNS implements the middleware.Handler interface.
|
|
func (rw Rewrite) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
|
wr := NewResponseReverter(w, r)
|
|
for _, rule := range rw.Rules {
|
|
switch result := rule.Rewrite(r); result {
|
|
case RewriteDone:
|
|
if rw.noRevert {
|
|
return rw.Next.ServeDNS(ctx, w, r)
|
|
}
|
|
return rw.Next.ServeDNS(ctx, wr, r)
|
|
case RewriteIgnored:
|
|
break
|
|
case RewriteStatus:
|
|
// only valid for complex rules.
|
|
// if cRule, ok := rule.(*ComplexRule); ok && cRule.Status != 0 {
|
|
// return cRule.Status, nil
|
|
// }
|
|
}
|
|
}
|
|
return rw.Next.ServeDNS(ctx, w, r)
|
|
}
|
|
|
|
func (rw Rewrite) Name() string { return "rewrite" }
|
|
|
|
// Rule describes an internal location rewrite rule.
|
|
type Rule interface {
|
|
// Rewrite rewrites the internal location of the current request.
|
|
Rewrite(*dns.Msg) Result
|
|
}
|
|
|
|
// SimpleRule is a simple rewrite rule. If the From and To look like a type
|
|
// the type of the request is rewritten, otherwise the name is.
|
|
// Note: TSIG signed requests will be invalid.
|
|
type SimpleRule struct {
|
|
From, To string
|
|
fromType, toType uint16
|
|
fromClass, toClass uint16
|
|
}
|
|
|
|
// NewSimpleRule creates a new Simple Rule
|
|
func NewSimpleRule(from, to string) SimpleRule {
|
|
tpf := dns.StringToType[from]
|
|
tpt := dns.StringToType[to]
|
|
|
|
// ANY is both a type and class, ANY class rewritting is way more less frequent
|
|
// so we default to ANY as a type.
|
|
clf := dns.StringToClass[from]
|
|
clt := dns.StringToClass[to]
|
|
if from == "ANY" {
|
|
clf = 0
|
|
clt = 0
|
|
}
|
|
|
|
// It's only a type/class if uppercase is used.
|
|
if from != strings.ToUpper(from) {
|
|
tpf = 0
|
|
clf = 0
|
|
from = middleware.Name(from).Normalize()
|
|
}
|
|
if to != strings.ToUpper(to) {
|
|
tpt = 0
|
|
clt = 0
|
|
to = middleware.Name(to).Normalize()
|
|
}
|
|
return SimpleRule{From: from, To: to, fromType: tpf, toType: tpt, fromClass: clf, toClass: clt}
|
|
}
|
|
|
|
// Rewrite rewrites the the current request.
|
|
func (s SimpleRule) Rewrite(r *dns.Msg) Result {
|
|
if s.fromType > 0 && s.toType > 0 {
|
|
if r.Question[0].Qtype == s.fromType {
|
|
r.Question[0].Qtype = s.toType
|
|
return RewriteDone
|
|
}
|
|
}
|
|
|
|
if s.fromClass > 0 && s.toClass > 0 {
|
|
if r.Question[0].Qclass == s.fromClass {
|
|
r.Question[0].Qclass = s.toClass
|
|
return RewriteDone
|
|
}
|
|
}
|
|
|
|
if s.From == r.Question[0].Name {
|
|
r.Question[0].Name = s.To
|
|
return RewriteDone
|
|
}
|
|
return RewriteIgnored
|
|
}
|