-
Notifications
You must be signed in to change notification settings - Fork 0
/
server_chaos.go
83 lines (67 loc) · 1.7 KB
/
server_chaos.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
78
79
80
81
82
83
package server
import (
"context"
"github.com/miekg/dns"
"darvaza.org/resolver/pkg/errors"
"darvaza.org/resolver/pkg/exdns"
)
// ExchangeCHAOS handles only CHAOS requests
func (srv *Server) ExchangeCHAOS(_ context.Context, req *dns.Msg) (*dns.Msg, error) {
var answers []dns.RR
if srv.cfg.DisableCHAOS {
return handleRcodeSuccess(req, []dns.RR{})
}
exdns.ForEachQuestionOfClass(req, dns.ClassCHAOS, func(q dns.Question) {
rr, ok := srv.chaosAnswer(q)
if ok {
answers = append(answers, rr...)
}
})
if len(answers) == 0 {
// no idea what to do with this request
return handleRcodeError(req, dns.RcodeNotImplemented)
}
// (partial?) success
return handleRcodeSuccess(req, answers)
}
func (srv *Server) chaosAnswer(q dns.Question) ([]dns.RR, bool) {
switch q.Name {
case "authors.bind.":
if s := srv.cfg.Authors; s != "" {
return dnsTXTAnswer(q, s)
}
case "version.bind.", "version.server.":
if s := srv.cfg.Version; s != "" {
return dnsTXTAnswer(q, s)
}
case "hostname.bind.", "id.server.":
if s := srv.cfg.Name; s != "" {
return dnsTXTAnswer(q, s)
}
}
return nil, false
}
func dnsTXTAnswer(q dns.Question, content ...string) ([]dns.RR, bool) {
rr := &dns.TXT{
Hdr: dns.RR_Header{
Name: q.Name,
Rrtype: dns.TypeTXT,
Class: q.Qclass,
},
Txt: content,
}
return []dns.RR{rr}, true
}
func handleRcodeError(req *dns.Msg, rCode int) (*dns.Msg, error) {
resp := new(dns.Msg)
resp.SetRcode(req, rCode)
return nil, errors.MsgAsError(resp)
}
func handleRcodeSuccess(req *dns.Msg, answers []dns.RR) (*dns.Msg, error) {
resp := new(dns.Msg)
resp.SetReply(req)
resp.Compress = false
resp.RecursionAvailable = true
resp.Answer = answers
return resp, nil
}