-
Notifications
You must be signed in to change notification settings - Fork 7
/
records.go
77 lines (64 loc) · 1.77 KB
/
records.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package records
import (
"context"
"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/request"
"github.com/miekg/dns"
)
// Records is the plugin handler.
type Records struct {
origins []string // for easy matching, these strings are the index in the map m.
m map[string][]dns.RR
Next plugin.Handler
}
// ServeDNS implements the plugin.Handle interface.
func (re *Records) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
state := request.Request{W: w, Req: r}
qname := state.Name()
zone := plugin.Zones(re.origins).Matches(qname)
if zone == "" {
return plugin.NextOrFailure(re.Name(), re.Next, ctx, w, r)
}
// New we should have some data for this zone, as we just have a list of RR, iterate through them, find the qname
// and see if the qtype exists. If so reply, if not do the normal DNS thing and return either NXDOMAIN or NODATA.
m := new(dns.Msg)
m.SetReply(r)
m.Authoritative = true
nxdomain := true
var soa dns.RR
for _, r := range re.m[zone] {
if r.Header().Rrtype == dns.TypeSOA && soa == nil {
soa = r
}
if r.Header().Name == qname {
nxdomain = false
if r.Header().Rrtype == state.QType() {
m.Answer = append(m.Answer, r)
}
}
}
// handle NXDOMAIN, NODATA and normal response here.
if nxdomain {
m.Rcode = dns.RcodeNameError
if soa != nil {
m.Ns = []dns.RR{soa}
}
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
if len(m.Answer) == 0 {
if soa != nil {
m.Ns = []dns.RR{soa}
}
}
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
// Name implements the plugin.Handle interface.
func (re *Records) Name() string { return "records" }
// New returns a pointer to a new and intialized Records.
func New() *Records {
re := new(Records)
re.m = make(map[string][]dns.RR)
return re
}