Skip to content

Commit e129a67

Browse files
committed
Add control of recursion desired flag for DNS probes
This defaults recursion desired to on to preserve existing behaviour, but allows it to be configured. Signed-off-by: David Leadbeater <[email protected]>
1 parent 70bff79 commit e129a67

File tree

5 files changed

+43
-14
lines changed

5 files changed

+43
-14
lines changed

CONFIGURATION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ query_name: <string>
189189
[ query_type: <string> | default = "ANY" ]
190190
[ query_class: <string> | default = "IN" ]
191191

192+
[ recursion_desired: <boolean> | default = true ]
193+
192194
# List of valid response codes.
193195
valid_rcodes:
194196
[ - <string> ... | default = "NOERROR" ]

config/config.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ var (
8282
// DefaultDNSProbe set default value for DNSProbe
8383
DefaultDNSProbe = DNSProbe{
8484
IPProtocolFallback: true,
85+
RecursionDesired: true,
8586
}
8687
)
8788

@@ -264,8 +265,9 @@ type DNSProbe struct {
264265
TransportProtocol string `yaml:"transport_protocol,omitempty"`
265266
QueryClass string `yaml:"query_class,omitempty"` // Defaults to IN.
266267
QueryName string `yaml:"query_name,omitempty"`
267-
QueryType string `yaml:"query_type,omitempty"` // Defaults to ANY.
268-
ValidRcodes []string `yaml:"valid_rcodes,omitempty"` // Defaults to NOERROR.
268+
QueryType string `yaml:"query_type,omitempty"` // Defaults to ANY.
269+
RecursionDesired bool `yaml:"recursion_desired,omitempty"` // Defaults to true.
270+
ValidRcodes []string `yaml:"valid_rcodes,omitempty"` // Defaults to NOERROR.
269271
ValidateAnswer DNSRRValidator `yaml:"validate_answer_rrs,omitempty"`
270272
ValidateAuthority DNSRRValidator `yaml:"validate_authority_rrs,omitempty"`
271273
ValidateAdditional DNSRRValidator `yaml:"validate_additional_rrs,omitempty"`

prober/dns.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry
250250

251251
msg := new(dns.Msg)
252252
msg.Id = dns.Id()
253-
msg.RecursionDesired = true
253+
msg.RecursionDesired = module.DNS.RecursionDesired
254254
msg.Question = make([]dns.Question, 1)
255255
msg.Question[0] = dns.Question{dns.Fqdn(module.DNS.QueryName), qt, qc}
256256

prober/dns_test.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,20 @@ func startDNSServer(protocol string, handler func(dns.ResponseWriter, *dns.Msg))
6969
func recursiveDNSHandler(w dns.ResponseWriter, r *dns.Msg) {
7070
m := new(dns.Msg)
7171
m.SetReply(r)
72-
answers := []string{
73-
"example.com. 3600 IN A 127.0.0.1",
74-
"example.com. 3600 IN A 127.0.0.2",
75-
}
76-
for _, rr := range answers {
77-
a, err := dns.NewRR(rr)
78-
if err != nil {
79-
panic(err)
72+
if !r.RecursionDesired {
73+
m.Rcode = dns.RcodeRefused
74+
} else {
75+
answers := []string{
76+
"example.com. 3600 IN A 127.0.0.1",
77+
"example.com. 3600 IN A 127.0.0.2",
78+
}
79+
for _, rr := range answers {
80+
a, err := dns.NewRR(rr)
81+
if err != nil {
82+
panic(err)
83+
}
84+
m.Answer = append(m.Answer, a)
8085
}
81-
m.Answer = append(m.Answer, a)
8286
}
8387
if err := w.WriteMsg(m); err != nil {
8488
panic(err)
@@ -99,13 +103,15 @@ func TestRecursiveDNSResponse(t *testing.T) {
99103
IPProtocol: "ip4",
100104
IPProtocolFallback: true,
101105
QueryName: "example.com",
106+
RecursionDesired: true,
102107
}, true,
103108
},
104109
{
105110
config.DNSProbe{
106111
IPProtocol: "ip4",
107112
IPProtocolFallback: true,
108113
QueryName: "example.com",
114+
RecursionDesired: true,
109115
ValidRcodes: []string{"SERVFAIL", "NXDOMAIN"},
110116
}, false,
111117
},
@@ -114,6 +120,7 @@ func TestRecursiveDNSResponse(t *testing.T) {
114120
IPProtocol: "ip4",
115121
IPProtocolFallback: true,
116122
QueryName: "example.com",
123+
RecursionDesired: true,
117124
ValidateAnswer: config.DNSRRValidator{
118125
FailIfMatchesRegexp: []string{".*7200.*"},
119126
FailIfNotMatchesRegexp: []string{".*3600.*"},
@@ -125,6 +132,7 @@ func TestRecursiveDNSResponse(t *testing.T) {
125132
IPProtocol: "ip4",
126133
IPProtocolFallback: true,
127134
QueryName: "example.com",
135+
RecursionDesired: true,
128136
ValidateAuthority: config.DNSRRValidator{
129137
FailIfMatchesRegexp: []string{".*7200.*"},
130138
},
@@ -135,11 +143,20 @@ func TestRecursiveDNSResponse(t *testing.T) {
135143
IPProtocol: "ip4",
136144
IPProtocolFallback: true,
137145
QueryName: "example.com",
146+
RecursionDesired: true,
138147
ValidateAdditional: config.DNSRRValidator{
139148
FailIfNotMatchesRegexp: []string{".*3600.*"},
140149
},
141150
}, false,
142151
},
152+
{
153+
config.DNSProbe{
154+
IPProtocol: "ip4",
155+
IPProtocolFallback: true,
156+
QueryName: "example.com",
157+
RecursionDesired: false,
158+
}, false,
159+
},
143160
}
144161

145162
for _, protocol := range PROTOCOLS {
@@ -166,6 +183,9 @@ func TestRecursiveDNSResponse(t *testing.T) {
166183
"probe_dns_authority_rrs": 0,
167184
"probe_dns_additional_rrs": 0,
168185
}
186+
if !test.Probe.RecursionDesired {
187+
expectedResults["probe_dns_answer_rrs"] = 0
188+
}
169189
checkRegistryResults(expectedResults, mfs, t)
170190
}
171191
}
@@ -474,6 +494,7 @@ func TestDNSProtocol(t *testing.T) {
474494
QueryName: "example.com",
475495
TransportProtocol: protocol,
476496
IPProtocol: "ip6",
497+
RecursionDesired: true,
477498
},
478499
}
479500
registry := prometheus.NewRegistry()
@@ -497,6 +518,7 @@ func TestDNSProtocol(t *testing.T) {
497518
Timeout: time.Second,
498519
DNS: config.DNSProbe{
499520
QueryName: "example.com",
521+
RecursionDesired: true,
500522
TransportProtocol: protocol,
501523
IPProtocol: "ip4",
502524
},
@@ -523,6 +545,7 @@ func TestDNSProtocol(t *testing.T) {
523545
Timeout: time.Second,
524546
DNS: config.DNSProbe{
525547
QueryName: "example.com",
548+
RecursionDesired: true,
526549
TransportProtocol: protocol,
527550
},
528551
}
@@ -547,7 +570,8 @@ func TestDNSProtocol(t *testing.T) {
547570
module = config.Module{
548571
Timeout: time.Second,
549572
DNS: config.DNSProbe{
550-
QueryName: "example.com",
573+
QueryName: "example.com",
574+
RecursionDesired: true,
551575
},
552576
}
553577
registry = prometheus.NewRegistry()
@@ -590,6 +614,7 @@ func TestDNSMetrics(t *testing.T) {
590614
IPProtocol: "ip4",
591615
IPProtocolFallback: true,
592616
QueryName: "example.com",
617+
RecursionDesired: true,
593618
},
594619
}
595620
registry := prometheus.NewRegistry()

prober/utils_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ func TestChooseProtocol(t *testing.T) {
162162
registry = prometheus.NewPedanticRegistry()
163163

164164
ip, _, err = chooseProtocol(ctx, "ip4", false, "ipv6.google.com", registry, logger)
165-
if err != nil && err.Error() != "address ipv6.google.com: no suitable address found" {
165+
if err != nil && err.Error() != "address ipv6.google.com: no suitable address found" && err.Error() != "lookup ipv6.google.com: no such host" {
166166
t.Error(err)
167167
} else if err == nil {
168168
t.Error("should set error")

0 commit comments

Comments
 (0)