]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_Advanced.py
Merge pull request #7594 from rgacogne/dnsdist-set-rules
[thirdparty/pdns.git] / regression-tests.dnsdist / test_Advanced.py
CommitLineData
ec5f5c6b 1#!/usr/bin/env python
26b86deb 2import base64
ec5f5c6b 3from datetime import datetime, timedelta
ec5f5c6b 4import os
26b86deb 5import string
856c35e3 6import time
b1bec9f0 7import dns
4bfdbd34 8import clientsubnetoption
ec5f5c6b
RG
9from dnsdisttests import DNSDistTest
10
b1bec9f0
RG
11class TestAdvancedAllow(DNSDistTest):
12
13 _config_template = """
bc084a31 14 addAction(AllRule(), NoneAction())
b1bec9f0
RG
15 addAction(makeRule("allowed.advanced.tests.powerdns.com."), AllowAction())
16 addAction(AllRule(), DropAction())
17 newServer{address="127.0.0.1:%s"}
18 """
19
20 def testAdvancedAllow(self):
21 """
22 Advanced: Allowed qname is not dropped
23
24 A query for allowed.advanced.tests.powerdns.com. should be allowed
25 while others should be dropped.
26 """
27 name = 'allowed.advanced.tests.powerdns.com.'
28 query = dns.message.make_query(name, 'A', 'IN')
29 response = dns.message.make_response(query)
30 rrset = dns.rrset.from_text(name,
31 3600,
32 dns.rdataclass.IN,
33 dns.rdatatype.A,
34 '127.0.0.1')
35 response.answer.append(rrset)
36
37 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
38 self.assertTrue(receivedQuery)
39 self.assertTrue(receivedResponse)
40 receivedQuery.id = query.id
41 self.assertEquals(query, receivedQuery)
42 self.assertEquals(response, receivedResponse)
43
44 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
45 self.assertTrue(receivedQuery)
46 self.assertTrue(receivedResponse)
47 receivedQuery.id = query.id
48 self.assertEquals(query, receivedQuery)
49 self.assertEquals(response, receivedResponse)
50
51 def testAdvancedAllowDropped(self):
52 """
53 Advanced: Not allowed qname is dropped
54
55 A query for notallowed.advanced.tests.powerdns.com. should be dropped.
56 """
57 name = 'notallowed.advanced.tests.powerdns.com.'
58 query = dns.message.make_query(name, 'A', 'IN')
59 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
60 self.assertEquals(receivedResponse, None)
61
62 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
63 self.assertEquals(receivedResponse, None)
64
ec5f5c6b
RG
65class TestAdvancedFixupCase(DNSDistTest):
66
ec5f5c6b
RG
67 _config_template = """
68 truncateTC(true)
69 fixupCase(true)
70 newServer{address="127.0.0.1:%s"}
71 """
72
ec5f5c6b
RG
73 def testAdvancedFixupCase(self):
74 """
617dfe22
RG
75 Advanced: Fixup Case
76
ec5f5c6b
RG
77 Send a query with lower and upper chars,
78 make the backend return a lowercase version,
79 check that dnsdist fixes the response.
80 """
81 name = 'fiXuPCasE.advanced.tests.powerdns.com.'
82 query = dns.message.make_query(name, 'A', 'IN')
83 lowercasequery = dns.message.make_query(name.lower(), 'A', 'IN')
84 response = dns.message.make_response(lowercasequery)
85 expectedResponse = dns.message.make_response(query)
86 rrset = dns.rrset.from_text(name,
87 3600,
88 dns.rdataclass.IN,
89 dns.rdatatype.A,
90 '127.0.0.1')
91 response.answer.append(rrset)
92 expectedResponse.answer.append(rrset)
93
94 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
95 self.assertTrue(receivedQuery)
96 self.assertTrue(receivedResponse)
97 receivedQuery.id = query.id
ec5f5c6b
RG
98 self.assertEquals(query, receivedQuery)
99 self.assertEquals(expectedResponse, receivedResponse)
100
101 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
102 self.assertTrue(receivedQuery)
103 self.assertTrue(receivedResponse)
104 receivedQuery.id = query.id
ec5f5c6b
RG
105 self.assertEquals(query, receivedQuery)
106 self.assertEquals(expectedResponse, receivedResponse)
107
108
109class TestAdvancedRemoveRD(DNSDistTest):
110
ec5f5c6b 111 _config_template = """
6bb38cd6 112 addAction("norecurse.advanced.tests.powerdns.com.", NoRecurseAction())
ec5f5c6b
RG
113 newServer{address="127.0.0.1:%s"}
114 """
115
ec5f5c6b
RG
116 def testAdvancedNoRD(self):
117 """
617dfe22
RG
118 Advanced: No RD
119
ec5f5c6b
RG
120 Send a query with RD,
121 check that dnsdist clears the RD flag.
122 """
123 name = 'norecurse.advanced.tests.powerdns.com.'
124 query = dns.message.make_query(name, 'A', 'IN')
125 expectedQuery = dns.message.make_query(name, 'A', 'IN')
126 expectedQuery.flags &= ~dns.flags.RD
127
128 response = dns.message.make_response(query)
129 rrset = dns.rrset.from_text(name,
130 3600,
131 dns.rdataclass.IN,
132 dns.rdatatype.A,
133 '127.0.0.1')
134 response.answer.append(rrset)
135
136 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
137 self.assertTrue(receivedQuery)
138 self.assertTrue(receivedResponse)
139 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
140 self.assertEquals(expectedQuery, receivedQuery)
141 self.assertEquals(response, receivedResponse)
142
143 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
144 self.assertTrue(receivedQuery)
145 self.assertTrue(receivedResponse)
146 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
147 self.assertEquals(expectedQuery, receivedQuery)
148 self.assertEquals(response, receivedResponse)
149
150 def testAdvancedKeepRD(self):
151 """
617dfe22
RG
152 Advanced: No RD canary
153
ec5f5c6b
RG
154 Send a query with RD for a canary domain,
155 check that dnsdist does not clear the RD flag.
156 """
157 name = 'keeprecurse.advanced.tests.powerdns.com.'
158 query = dns.message.make_query(name, 'A', 'IN')
159
160 response = dns.message.make_response(query)
161 rrset = dns.rrset.from_text(name,
162 3600,
163 dns.rdataclass.IN,
164 dns.rdatatype.A,
165 '127.0.0.1')
166 response.answer.append(rrset)
167
168 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
169 self.assertTrue(receivedQuery)
170 self.assertTrue(receivedResponse)
171 receivedQuery.id = query.id
ec5f5c6b
RG
172 self.assertEquals(query, receivedQuery)
173 self.assertEquals(response, receivedResponse)
174
175 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
176 self.assertTrue(receivedQuery)
177 self.assertTrue(receivedResponse)
178 receivedQuery.id = query.id
ec5f5c6b
RG
179 self.assertEquals(query, receivedQuery)
180 self.assertEquals(response, receivedResponse)
181
182
183class TestAdvancedAddCD(DNSDistTest):
184
ec5f5c6b 185 _config_template = """
6bb38cd6 186 addAction("setcd.advanced.tests.powerdns.com.", DisableValidationAction())
b1bec9f0 187 addAction(makeRule("setcdviaaction.advanced.tests.powerdns.com."), DisableValidationAction())
ec5f5c6b
RG
188 newServer{address="127.0.0.1:%s"}
189 """
190
ec5f5c6b
RG
191 def testAdvancedSetCD(self):
192 """
617dfe22
RG
193 Advanced: Set CD
194
ec5f5c6b
RG
195 Send a query with CD cleared,
196 check that dnsdist set the CD flag.
197 """
198 name = 'setcd.advanced.tests.powerdns.com.'
199 query = dns.message.make_query(name, 'A', 'IN')
b1bec9f0
RG
200 expectedQuery = dns.message.make_query(name, 'A', 'IN')
201 expectedQuery.flags |= dns.flags.CD
202
203 response = dns.message.make_response(query)
204 rrset = dns.rrset.from_text(name,
205 3600,
206 dns.rdataclass.IN,
207 dns.rdatatype.A,
208 '127.0.0.1')
209 response.answer.append(rrset)
210
211 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
212 self.assertTrue(receivedQuery)
213 self.assertTrue(receivedResponse)
214 receivedQuery.id = expectedQuery.id
215 self.assertEquals(expectedQuery, receivedQuery)
216 self.assertEquals(response, receivedResponse)
217
218 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
219 self.assertTrue(receivedQuery)
220 self.assertTrue(receivedResponse)
221 receivedQuery.id = expectedQuery.id
222 self.assertEquals(expectedQuery, receivedQuery)
223 self.assertEquals(response, receivedResponse)
224
225 def testAdvancedSetCDViaAction(self):
226 """
227 Advanced: Set CD via Action
228
229 Send a query with CD cleared,
230 check that dnsdist set the CD flag.
231 """
232 name = 'setcdviaaction.advanced.tests.powerdns.com.'
233 query = dns.message.make_query(name, 'A', 'IN')
234 expectedQuery = dns.message.make_query(name, 'A', 'IN')
ec5f5c6b
RG
235 expectedQuery.flags |= dns.flags.CD
236
237 response = dns.message.make_response(query)
238 rrset = dns.rrset.from_text(name,
239 3600,
240 dns.rdataclass.IN,
241 dns.rdatatype.A,
242 '127.0.0.1')
243 response.answer.append(rrset)
244
245 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
246 self.assertTrue(receivedQuery)
247 self.assertTrue(receivedResponse)
248 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
249 self.assertEquals(expectedQuery, receivedQuery)
250 self.assertEquals(response, receivedResponse)
251
252 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
253 self.assertTrue(receivedQuery)
254 self.assertTrue(receivedResponse)
255 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
256 self.assertEquals(expectedQuery, receivedQuery)
257 self.assertEquals(response, receivedResponse)
258
259 def testAdvancedKeepNoCD(self):
260 """
617dfe22
RG
261 Advanced: Preserve CD canary
262
ec5f5c6b
RG
263 Send a query without CD for a canary domain,
264 check that dnsdist does not set the CD flag.
265 """
266 name = 'keepnocd.advanced.tests.powerdns.com.'
267 query = dns.message.make_query(name, 'A', 'IN')
268
269 response = dns.message.make_response(query)
270 rrset = dns.rrset.from_text(name,
271 3600,
272 dns.rdataclass.IN,
273 dns.rdatatype.A,
274 '127.0.0.1')
275 response.answer.append(rrset)
276
277 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
278 self.assertTrue(receivedQuery)
279 self.assertTrue(receivedResponse)
280 receivedQuery.id = query.id
ec5f5c6b
RG
281 self.assertEquals(query, receivedQuery)
282 self.assertEquals(response, receivedResponse)
283
284 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
285 self.assertTrue(receivedQuery)
286 self.assertTrue(receivedResponse)
287 receivedQuery.id = query.id
ec5f5c6b
RG
288 self.assertEquals(query, receivedQuery)
289 self.assertEquals(response, receivedResponse)
290
b1bec9f0
RG
291class TestAdvancedClearRD(DNSDistTest):
292
293 _config_template = """
6bb38cd6 294 addAction("clearrd.advanced.tests.powerdns.com.", NoRecurseAction())
b1bec9f0
RG
295 addAction(makeRule("clearrdviaaction.advanced.tests.powerdns.com."), NoRecurseAction())
296 newServer{address="127.0.0.1:%s"}
297 """
298
299 def testAdvancedClearRD(self):
300 """
301 Advanced: Clear RD
302
303 Send a query with RD set,
304 check that dnsdist clears the RD flag.
305 """
306 name = 'clearrd.advanced.tests.powerdns.com.'
307 query = dns.message.make_query(name, 'A', 'IN')
308 expectedQuery = dns.message.make_query(name, 'A', 'IN')
309 expectedQuery.flags &= ~dns.flags.RD
310
311 response = dns.message.make_response(query)
312 rrset = dns.rrset.from_text(name,
313 3600,
314 dns.rdataclass.IN,
315 dns.rdatatype.A,
316 '127.0.0.1')
317 response.answer.append(rrset)
318
319 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
320 self.assertTrue(receivedQuery)
321 self.assertTrue(receivedResponse)
322 receivedQuery.id = expectedQuery.id
323 self.assertEquals(expectedQuery, receivedQuery)
324 self.assertEquals(response, receivedResponse)
325
326 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
327 self.assertTrue(receivedQuery)
328 self.assertTrue(receivedResponse)
329 receivedQuery.id = expectedQuery.id
330 self.assertEquals(expectedQuery, receivedQuery)
331 self.assertEquals(response, receivedResponse)
332
333 def testAdvancedClearRDViaAction(self):
334 """
335 Advanced: Clear RD via Action
336
337 Send a query with RD set,
338 check that dnsdist clears the RD flag.
339 """
340 name = 'clearrdviaaction.advanced.tests.powerdns.com.'
341 query = dns.message.make_query(name, 'A', 'IN')
342 expectedQuery = dns.message.make_query(name, 'A', 'IN')
343 expectedQuery.flags &= ~dns.flags.RD
344
345 response = dns.message.make_response(query)
346 rrset = dns.rrset.from_text(name,
347 3600,
348 dns.rdataclass.IN,
349 dns.rdatatype.A,
350 '127.0.0.1')
351 response.answer.append(rrset)
352
353 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
354 self.assertTrue(receivedQuery)
355 self.assertTrue(receivedResponse)
356 receivedQuery.id = expectedQuery.id
357 self.assertEquals(expectedQuery, receivedQuery)
358 self.assertEquals(response, receivedResponse)
359
360 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
361 self.assertTrue(receivedQuery)
362 self.assertTrue(receivedResponse)
363 receivedQuery.id = expectedQuery.id
364 self.assertEquals(expectedQuery, receivedQuery)
365 self.assertEquals(response, receivedResponse)
366
367 def testAdvancedKeepRD(self):
368 """
369 Advanced: Preserve RD canary
370
371 Send a query with RD for a canary domain,
372 check that dnsdist does not clear the RD flag.
373 """
374 name = 'keeprd.advanced.tests.powerdns.com.'
375 query = dns.message.make_query(name, 'A', 'IN')
376
377 response = dns.message.make_response(query)
378 rrset = dns.rrset.from_text(name,
379 3600,
380 dns.rdataclass.IN,
381 dns.rdatatype.A,
382 '127.0.0.1')
383 response.answer.append(rrset)
384
385 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
386 self.assertTrue(receivedQuery)
387 self.assertTrue(receivedResponse)
388 receivedQuery.id = query.id
389 self.assertEquals(query, receivedQuery)
390 self.assertEquals(response, receivedResponse)
391
392 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
393 self.assertTrue(receivedQuery)
394 self.assertTrue(receivedResponse)
395 receivedQuery.id = query.id
396 self.assertEquals(query, receivedQuery)
397 self.assertEquals(response, receivedResponse)
398
ec5f5c6b
RG
399
400class TestAdvancedACL(DNSDistTest):
401
ec5f5c6b
RG
402 _config_template = """
403 newServer{address="127.0.0.1:%s"}
404 """
18a0e7c6 405 _acl = ['192.0.2.1/32']
ec5f5c6b
RG
406
407 def testACLBlocked(self):
408 """
617dfe22
RG
409 Advanced: ACL blocked
410
ec5f5c6b
RG
411 Send an A query to "tests.powerdns.com.",
412 we expect no response since 127.0.0.1 is not on the
413 ACL.
414 """
903853f4 415 name = 'tests.powerdns.com.'
7791f83a 416 query = dns.message.make_query(name, 'A', 'IN')
7791f83a
RG
417
418 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
903853f4 419 self.assertEquals(receivedResponse, None)
7791f83a
RG
420
421 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
903853f4
RG
422 self.assertEquals(receivedResponse, None)
423
424class TestAdvancedDelay(DNSDistTest):
425
426 _config_template = """
427 addAction(AllRule(), DelayAction(1000))
428 newServer{address="127.0.0.1:%s"}
429 """
7791f83a 430
903853f4 431 def testDelayed(self):
7791f83a 432 """
903853f4 433 Advanced: Delayed
7791f83a 434
903853f4
RG
435 Send an A query to "tests.powerdns.com.",
436 check that the response delay is longer than 1000 ms
437 over UDP, less than that over TCP.
7791f83a 438 """
903853f4
RG
439 name = 'tests.powerdns.com.'
440 query = dns.message.make_query(name, 'A', 'IN')
441 response = dns.message.make_response(query)
7791f83a
RG
442 rrset = dns.rrset.from_text(name,
443 60,
444 dns.rdataclass.IN,
903853f4
RG
445 dns.rdatatype.A,
446 '192.0.2.1')
447 response.answer.append(rrset)
7791f83a 448
903853f4
RG
449 begin = datetime.now()
450 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
451 end = datetime.now()
452 receivedQuery.id = query.id
453 self.assertEquals(query, receivedQuery)
454 self.assertEquals(response, receivedResponse)
455 self.assertTrue((end - begin) > timedelta(0, 1))
456
457 begin = datetime.now()
458 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
459 end = datetime.now()
460 receivedQuery.id = query.id
461 self.assertEquals(query, receivedQuery)
462 self.assertEquals(response, receivedResponse)
463 self.assertTrue((end - begin) < timedelta(0, 1))
7791f83a 464
e7a1029c
RG
465
466class TestAdvancedTruncateAnyAndTCP(DNSDistTest):
467
468 _config_template = """
469 truncateTC(false)
470 addAction(AndRule({QTypeRule("ANY"), TCPRule(true)}), TCAction())
471 newServer{address="127.0.0.1:%s"}
472 """
473 def testTruncateAnyOverTCP(self):
474 """
475 Advanced: Truncate ANY over TCP
476
b1bec9f0 477 Send an ANY query to "anytruncatetcp.advanced.tests.powerdns.com.",
e7a1029c
RG
478 should be truncated over TCP, not over UDP (yes, it makes no sense,
479 deal with it).
480 """
b1bec9f0 481 name = 'anytruncatetcp.advanced.tests.powerdns.com.'
e7a1029c
RG
482 query = dns.message.make_query(name, 'ANY', 'IN')
483
484 response = dns.message.make_response(query)
485 rrset = dns.rrset.from_text(name,
486 3600,
487 dns.rdataclass.IN,
488 dns.rdatatype.A,
489 '127.0.0.1')
490
491 response.answer.append(rrset)
492
493 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
494 self.assertTrue(receivedQuery)
495 self.assertTrue(receivedResponse)
496 receivedQuery.id = query.id
e7a1029c
RG
497 self.assertEquals(query, receivedQuery)
498 self.assertEquals(receivedResponse, response)
499
500 expectedResponse = dns.message.make_response(query)
501 expectedResponse.flags |= dns.flags.TC
502
503 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
e7a1029c
RG
504 self.assertEquals(receivedResponse, expectedResponse)
505
506class TestAdvancedAndNot(DNSDistTest):
507
508 _config_template = """
55baa1f2 509 addAction(AndRule({NotRule(QTypeRule("A")), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP))
e7a1029c
RG
510 newServer{address="127.0.0.1:%s"}
511 """
512 def testAOverUDPReturnsNotImplementedCanary(self):
513 """
514 Advanced: !A && UDP canary
515
516 dnsdist is configured to reply 'not implemented' for query
517 over UDP AND !qtype A.
518 We send an A query over UDP and TCP, and check that the
519 response is OK.
520 """
b1bec9f0 521 name = 'andnot.advanced.tests.powerdns.com.'
e7a1029c
RG
522 query = dns.message.make_query(name, 'A', 'IN')
523 response = dns.message.make_response(query)
524 rrset = dns.rrset.from_text(name,
525 3600,
526 dns.rdataclass.IN,
527 dns.rdatatype.A,
528 '127.0.0.1')
529 response.answer.append(rrset)
530
531 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
532 self.assertTrue(receivedQuery)
533 self.assertTrue(receivedResponse)
534 receivedQuery.id = query.id
e7a1029c
RG
535 self.assertEquals(query, receivedQuery)
536 self.assertEquals(receivedResponse, response)
537
538 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
539 self.assertTrue(receivedQuery)
540 self.assertTrue(receivedResponse)
541 receivedQuery.id = query.id
e7a1029c
RG
542 self.assertEquals(query, receivedQuery)
543 self.assertEquals(receivedResponse, response)
544
545 def testAOverUDPReturnsNotImplemented(self):
546 """
547 Advanced: !A && UDP
548
549 dnsdist is configured to reply 'not implemented' for query
550 over UDP AND !qtype A.
551 We send a TXT query over UDP and TCP, and check that the
552 response is OK for TCP and 'not implemented' for UDP.
553 """
b1bec9f0 554 name = 'andnot.advanced.tests.powerdns.com.'
e7a1029c
RG
555 query = dns.message.make_query(name, 'TXT', 'IN')
556
557 expectedResponse = dns.message.make_response(query)
558 expectedResponse.set_rcode(dns.rcode.NOTIMP)
559
560 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
e7a1029c
RG
561 self.assertEquals(receivedResponse, expectedResponse)
562
563 response = dns.message.make_response(query)
564 rrset = dns.rrset.from_text(name,
565 3600,
566 dns.rdataclass.IN,
567 dns.rdatatype.TXT,
568 'nothing to see here')
569 response.answer.append(rrset)
570
571 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
572 self.assertTrue(receivedQuery)
573 self.assertTrue(receivedResponse)
574 receivedQuery.id = query.id
e7a1029c
RG
575 self.assertEquals(query, receivedQuery)
576 self.assertEquals(receivedResponse, response)
577
578class TestAdvancedOr(DNSDistTest):
579
580 _config_template = """
55baa1f2 581 addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP))
e7a1029c
RG
582 newServer{address="127.0.0.1:%s"}
583 """
584 def testAAAAOverUDPReturnsNotImplemented(self):
585 """
586 Advanced: A || UDP: AAAA
587
588 dnsdist is configured to reply 'not implemented' for query
589 over UDP OR qtype A.
590 We send an AAAA query over UDP and TCP, and check that the
591 response is 'not implemented' for UDP and OK for TCP.
592 """
b1bec9f0 593 name = 'aorudp.advanced.tests.powerdns.com.'
e7a1029c
RG
594 query = dns.message.make_query(name, 'AAAA', 'IN')
595 response = dns.message.make_response(query)
596 rrset = dns.rrset.from_text(name,
597 3600,
598 dns.rdataclass.IN,
599 dns.rdatatype.AAAA,
600 '::1')
601 response.answer.append(rrset)
602
603 expectedResponse = dns.message.make_response(query)
604 expectedResponse.set_rcode(dns.rcode.NOTIMP)
605
606 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
e7a1029c
RG
607 self.assertEquals(receivedResponse, expectedResponse)
608
609 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
610 self.assertTrue(receivedQuery)
611 self.assertTrue(receivedResponse)
612 receivedQuery.id = query.id
e7a1029c
RG
613 self.assertEquals(query, receivedQuery)
614 self.assertEquals(receivedResponse, response)
615
616 def testAOverUDPReturnsNotImplemented(self):
617 """
618 Advanced: A || UDP: A
619
620 dnsdist is configured to reply 'not implemented' for query
621 over UDP OR qtype A.
622 We send an A query over UDP and TCP, and check that the
623 response is 'not implemented' for both.
624 """
b1bec9f0 625 name = 'aorudp.advanced.tests.powerdns.com.'
e7a1029c
RG
626 query = dns.message.make_query(name, 'A', 'IN')
627
628 expectedResponse = dns.message.make_response(query)
629 expectedResponse.set_rcode(dns.rcode.NOTIMP)
630
631 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
e7a1029c
RG
632 self.assertEquals(receivedResponse, expectedResponse)
633
634 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
e7a1029c 635 self.assertEquals(receivedResponse, expectedResponse)
886e2cf2 636
b1bec9f0
RG
637
638class TestAdvancedLogAction(DNSDistTest):
639
640 _config_template = """
641 newServer{address="127.0.0.1:%s"}
642 addAction(AllRule(), LogAction("dnsdist.log", false))
643 """
644 def testAdvancedLogAction(self):
645 """
646 Advanced: Log all queries
647
648 """
649 count = 50
650 name = 'logaction.advanced.tests.powerdns.com.'
651 query = dns.message.make_query(name, 'A', 'IN')
652 response = dns.message.make_response(query)
653 rrset = dns.rrset.from_text(name,
654 3600,
655 dns.rdataclass.IN,
656 dns.rdatatype.A,
657 '127.0.0.1')
658 response.answer.append(rrset)
659
660 for _ in range(count):
661 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
662 self.assertTrue(receivedQuery)
663 self.assertTrue(receivedResponse)
664 receivedQuery.id = query.id
b1bec9f0
RG
665 self.assertEquals(query, receivedQuery)
666 self.assertEquals(response, receivedResponse)
667
668 self.assertTrue(os.path.isfile('dnsdist.log'))
669 self.assertTrue(os.stat('dnsdist.log').st_size > 0)
670
671class TestAdvancedDNSSEC(DNSDistTest):
672
673 _config_template = """
674 newServer{address="127.0.0.1:%s"}
675 addAction(DNSSECRule(), DropAction())
676 """
677 def testAdvancedDNSSECDrop(self):
678 """
679 Advanced: DNSSEC Rule
680
681 """
682 name = 'dnssec.advanced.tests.powerdns.com.'
683 query = dns.message.make_query(name, 'A', 'IN')
684 doquery = dns.message.make_query(name, 'A', 'IN', want_dnssec=True)
685 response = dns.message.make_response(query)
686 rrset = dns.rrset.from_text(name,
687 3600,
688 dns.rdataclass.IN,
689 dns.rdatatype.A,
690 '127.0.0.1')
691 response.answer.append(rrset)
692
693 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
694 self.assertTrue(receivedQuery)
695 self.assertTrue(receivedResponse)
696 receivedQuery.id = query.id
b1bec9f0
RG
697 self.assertEquals(query, receivedQuery)
698 self.assertEquals(response, receivedResponse)
699
700 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
701 self.assertTrue(receivedQuery)
702 self.assertTrue(receivedResponse)
703 receivedQuery.id = query.id
b1bec9f0
RG
704 self.assertEquals(query, receivedQuery)
705 self.assertEquals(response, receivedResponse)
706
707 (_, receivedResponse) = self.sendUDPQuery(doquery, response)
708 self.assertEquals(receivedResponse, None)
709 (_, receivedResponse) = self.sendTCPQuery(doquery, response)
710 self.assertEquals(receivedResponse, None)
711
712class TestAdvancedQClass(DNSDistTest):
713
714 _config_template = """
715 newServer{address="127.0.0.1:%s"}
55baa1f2 716 addAction(QClassRule(DNSClass.CHAOS), DropAction())
b1bec9f0
RG
717 """
718 def testAdvancedQClassChaosDrop(self):
719 """
720 Advanced: Drop QClass CHAOS
721
722 """
723 name = 'qclasschaos.advanced.tests.powerdns.com.'
724 query = dns.message.make_query(name, 'TXT', 'CHAOS')
b1bec9f0 725
55baa1f2 726 (_, receivedResponse) = self.sendUDPQuery(query, response=None)
b1bec9f0 727 self.assertEquals(receivedResponse, None)
55baa1f2 728 (_, receivedResponse) = self.sendTCPQuery(query, response=None)
b1bec9f0
RG
729 self.assertEquals(receivedResponse, None)
730
731 def testAdvancedQClassINAllow(self):
732 """
733 Advanced: Allow QClass IN
734
735 """
736 name = 'qclassin.advanced.tests.powerdns.com.'
737 query = dns.message.make_query(name, 'A', 'IN')
738 response = dns.message.make_response(query)
739 rrset = dns.rrset.from_text(name,
740 3600,
741 dns.rdataclass.IN,
742 dns.rdatatype.A,
743 '127.0.0.1')
744 response.answer.append(rrset)
745
746 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
747 self.assertTrue(receivedQuery)
748 self.assertTrue(receivedResponse)
749 receivedQuery.id = query.id
b1bec9f0
RG
750 self.assertEquals(query, receivedQuery)
751 self.assertEquals(response, receivedResponse)
752
753 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
754 self.assertTrue(receivedQuery)
755 self.assertTrue(receivedResponse)
756 receivedQuery.id = query.id
b1bec9f0
RG
757 self.assertEquals(query, receivedQuery)
758 self.assertEquals(response, receivedResponse)
88d05ca1 759
55baa1f2
RG
760class TestAdvancedOpcode(DNSDistTest):
761
762 _config_template = """
763 newServer{address="127.0.0.1:%s"}
764 addAction(OpcodeRule(DNSOpcode.Notify), DropAction())
765 """
766 def testAdvancedOpcodeNotifyDrop(self):
767 """
768 Advanced: Drop Opcode NOTIFY
769
770 """
771 name = 'opcodenotify.advanced.tests.powerdns.com.'
772 query = dns.message.make_query(name, 'A', 'IN')
773 query.set_opcode(dns.opcode.NOTIFY)
774
775 (_, receivedResponse) = self.sendUDPQuery(query, response=None)
776 self.assertEquals(receivedResponse, None)
777 (_, receivedResponse) = self.sendTCPQuery(query, response=None)
778 self.assertEquals(receivedResponse, None)
779
780 def testAdvancedOpcodeUpdateINAllow(self):
781 """
782 Advanced: Allow Opcode UPDATE
783
784 """
785 name = 'opcodeupdate.advanced.tests.powerdns.com.'
786 query = dns.message.make_query(name, 'A', 'IN')
787 query.set_opcode(dns.opcode.UPDATE)
788 response = dns.message.make_response(query)
789 rrset = dns.rrset.from_text(name,
790 3600,
791 dns.rdataclass.IN,
792 dns.rdatatype.A,
793 '127.0.0.1')
794 response.answer.append(rrset)
795
796 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
797 self.assertTrue(receivedQuery)
798 self.assertTrue(receivedResponse)
799 receivedQuery.id = query.id
800 self.assertEquals(query, receivedQuery)
801 self.assertEquals(response, receivedResponse)
802
803 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
804 self.assertTrue(receivedQuery)
805 self.assertTrue(receivedResponse)
806 receivedQuery.id = query.id
807 self.assertEquals(query, receivedQuery)
808 self.assertEquals(response, receivedResponse)
46a839bf 809
88d05ca1
RG
810class TestAdvancedNonTerminalRule(DNSDistTest):
811
812 _config_template = """
813 newServer{address="127.0.0.1:%s", pool="real"}
814 addAction(AllRule(), DisableValidationAction())
815 addAction(AllRule(), PoolAction("real"))
816 addAction(AllRule(), DropAction())
817 """
818 def testAdvancedNonTerminalRules(self):
819 """
820 Advanced: Non terminal rules
821
822 We check that DisableValidationAction() is applied
823 but does not stop the processing, then that
824 PoolAction() is applied _and_ stop the processing.
825 """
826 name = 'nonterminal.advanced.tests.powerdns.com.'
827 query = dns.message.make_query(name, 'A', 'IN')
828 expectedQuery = dns.message.make_query(name, 'A', 'IN')
829 expectedQuery.flags |= dns.flags.CD
830 response = dns.message.make_response(query)
831 rrset = dns.rrset.from_text(name,
832 3600,
833 dns.rdataclass.IN,
834 dns.rdatatype.A,
46a839bf 835 '192.0.2.1')
88d05ca1
RG
836 response.answer.append(rrset)
837
838 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
839 self.assertTrue(receivedQuery)
840 self.assertTrue(receivedResponse)
841 receivedQuery.id = expectedQuery.id
842 self.assertEquals(expectedQuery, receivedQuery)
843 self.assertEquals(response, receivedResponse)
844
845 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
846 self.assertTrue(receivedQuery)
847 self.assertTrue(receivedResponse)
848 receivedQuery.id = expectedQuery.id
849 self.assertEquals(expectedQuery, receivedQuery)
850 self.assertEquals(response, receivedResponse)
46a839bf
RG
851
852class TestAdvancedStringOnlyServer(DNSDistTest):
853
854 _config_template = """
855 newServer("127.0.0.1:%s")
856 """
857
858 def testAdvancedStringOnlyServer(self):
859 """
860 Advanced: "string-only" server is placed in the default pool
861 """
862 name = 'string-only-server.advanced.tests.powerdns.com.'
863 query = dns.message.make_query(name, 'A', 'IN')
864 response = dns.message.make_response(query)
865 rrset = dns.rrset.from_text(name,
866 3600,
867 dns.rdataclass.IN,
868 dns.rdatatype.A,
869 '192.0.2.1')
870 response.answer.append(rrset)
871
872 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
873 self.assertTrue(receivedQuery)
874 self.assertTrue(receivedResponse)
875 receivedQuery.id = query.id
876 self.assertEquals(query, receivedQuery)
877 self.assertEquals(response, receivedResponse)
878
879 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
880 self.assertTrue(receivedQuery)
881 self.assertTrue(receivedResponse)
882 receivedQuery.id = query.id
883 self.assertEquals(query, receivedQuery)
884 self.assertEquals(response, receivedResponse)
0f72fd5c
RG
885
886class TestAdvancedRestoreFlagsOnSelfResponse(DNSDistTest):
887
888 _config_template = """
889 addAction(AllRule(), DisableValidationAction())
890 addAction(AllRule(), SpoofAction("192.0.2.1"))
891 newServer{address="127.0.0.1:%s"}
892 """
893
894 def testAdvancedRestoreFlagsOnSpoofResponse(self):
895 """
896 Advanced: Restore flags on spoofed response
897
898 Send a query with CD flag cleared, dnsdist is
899 instructed to set it, then to spoof the response,
900 check that response has the flag cleared.
901 """
902 name = 'spoofed.restoreflags.advanced.tests.powerdns.com.'
903 query = dns.message.make_query(name, 'A', 'IN')
904 # dnsdist set RA = RD for spoofed responses
905 query.flags &= ~dns.flags.RD
0f72fd5c
RG
906
907 response = dns.message.make_response(query)
908 rrset = dns.rrset.from_text(name,
909 60,
910 dns.rdataclass.IN,
911 dns.rdatatype.A,
912 '192.0.2.1')
913 response.answer.append(rrset)
914
915 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
916 self.assertTrue(receivedResponse)
917 self.assertEquals(response, receivedResponse)
918
919 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
920 self.assertTrue(receivedResponse)
921 self.assertEquals(response, receivedResponse)
856c35e3
RG
922
923class TestAdvancedQPS(DNSDistTest):
924
925 _config_template = """
8499caaf 926 addAction("qps.advanced.tests.powerdns.com", QPSAction(10))
856c35e3
RG
927 newServer{address="127.0.0.1:%s"}
928 """
929
930 def testAdvancedQPSLimit(self):
931 """
932 Advanced: QPS Limit
933
934 Send queries to "qps.advanced.tests.powerdns.com."
935 check that dnsdist drops queries when the max QPS has been reached.
936 """
937 maxQPS = 10
938 name = 'qps.advanced.tests.powerdns.com.'
939 query = dns.message.make_query(name, 'A', 'IN')
940 response = dns.message.make_response(query)
941 rrset = dns.rrset.from_text(name,
942 60,
943 dns.rdataclass.IN,
944 dns.rdatatype.A,
945 '192.0.2.1')
946 response.answer.append(rrset)
947
948 for _ in range(maxQPS):
949 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
950 receivedQuery.id = query.id
951 self.assertEquals(query, receivedQuery)
952 self.assertEquals(response, receivedResponse)
953
954 # we should now be dropped
955 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
956 self.assertEquals(receivedResponse, None)
957
958 time.sleep(1)
959
960 # again, over TCP this time
961 for _ in range(maxQPS):
962 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
963 receivedQuery.id = query.id
964 self.assertEquals(query, receivedQuery)
965 self.assertEquals(response, receivedResponse)
966
967
968 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
969 self.assertEquals(receivedResponse, None)
970
971class TestAdvancedQPSNone(DNSDistTest):
972
973 _config_template = """
8499caaf 974 addAction("qpsnone.advanced.tests.powerdns.com", QPSAction(100))
55baa1f2 975 addAction(AllRule(), RCodeAction(dnsdist.REFUSED))
856c35e3
RG
976 newServer{address="127.0.0.1:%s"}
977 """
978
979 def testAdvancedQPSNone(self):
980 """
981 Advanced: Not matching QPS returns None, not Allow
982
983 Send queries to "qps.advanced.tests.powerdns.com."
984 check that the rule returns None when the QPS has not been
985 reached, not Allow.
986 """
987 name = 'qpsnone.advanced.tests.powerdns.com.'
988 query = dns.message.make_query(name, 'A', 'IN')
989 expectedResponse = dns.message.make_response(query)
990 expectedResponse.set_rcode(dns.rcode.REFUSED)
991
992 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
993 self.assertEquals(receivedResponse, expectedResponse)
994
995 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
996 self.assertEquals(receivedResponse, expectedResponse)
36da3ecd
RG
997
998class TestAdvancedNMGRule(DNSDistTest):
999
1000 _config_template = """
1001 allowed = newNMG()
1002 allowed:addMask("192.0.2.1/32")
55baa1f2 1003 addAction(NotRule(NetmaskGroupRule(allowed)), RCodeAction(dnsdist.REFUSED))
36da3ecd
RG
1004 newServer{address="127.0.0.1:%s"}
1005 """
1006
1007 def testAdvancedNMGRule(self):
1008 """
1009 Advanced: NMGRule should refuse our queries
1010
1011 Send queries to "nmgrule.advanced.tests.powerdns.com.",
1012 check that we are getting a REFUSED response.
1013 """
1014 name = 'nmgrule.advanced.tests.powerdns.com.'
1015 query = dns.message.make_query(name, 'A', 'IN')
1016 expectedResponse = dns.message.make_response(query)
1017 expectedResponse.set_rcode(dns.rcode.REFUSED)
1018
1019 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1020 self.assertEquals(receivedResponse, expectedResponse)
1021
1022 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1023 self.assertEquals(receivedResponse, expectedResponse)
55baa1f2 1024
a8205923 1025class TestDSTPortRule(DNSDistTest):
1026
1027 _config_params = ['_dnsDistPort', '_testServerPort']
1028 _config_template = """
1029 addAction(DSTPortRule(%d), RCodeAction(dnsdist.REFUSED))
1030 newServer{address="127.0.0.1:%s"}
1031 """
1032
1033 def testDSTPortRule(self):
1034 """
1035 Advanced: DSTPortRule should capture our queries
1036
1037 Send queries to "dstportrule.advanced.tests.powerdns.com.",
1038 check that we are getting a REFUSED response.
1039 """
1040
1041 name = 'dstportrule.advanced.tests.powerdns.com.'
1042 query = dns.message.make_query(name, 'A', 'IN')
1043 expectedResponse = dns.message.make_response(query)
1044 expectedResponse.set_rcode(dns.rcode.REFUSED)
1045
1046 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1047 self.assertEquals(receivedResponse, expectedResponse)
1048
1049 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1050 self.assertEquals(receivedResponse, expectedResponse)
1051
57c61ce9
RG
1052class TestAdvancedLabelsCountRule(DNSDistTest):
1053
1054 _config_template = """
1055 addAction(QNameLabelsCountRule(5,6), RCodeAction(dnsdist.REFUSED))
1056 newServer{address="127.0.0.1:%s"}
1057 """
1058
1059 def testAdvancedLabelsCountRule(self):
1060 """
1061 Advanced: QNameLabelsCountRule(5,6)
1062 """
1063 # 6 labels, we should be fine
1064 name = 'ok.labelscount.advanced.tests.powerdns.com.'
1065 query = dns.message.make_query(name, 'A', 'IN')
1066 response = dns.message.make_response(query)
1067 rrset = dns.rrset.from_text(name,
1068 3600,
1069 dns.rdataclass.IN,
1070 dns.rdatatype.A,
1071 '192.0.2.1')
1072 response.answer.append(rrset)
1073
1074 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1075 self.assertTrue(receivedQuery)
1076 self.assertTrue(receivedResponse)
1077 receivedQuery.id = query.id
1078 self.assertEquals(query, receivedQuery)
1079 self.assertEquals(response, receivedResponse)
1080
1081 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1082 self.assertTrue(receivedQuery)
1083 self.assertTrue(receivedResponse)
1084 receivedQuery.id = query.id
1085 self.assertEquals(query, receivedQuery)
1086 self.assertEquals(response, receivedResponse)
1087
1088 # more than 6 labels, the query should be refused
1089 name = 'not.ok.labelscount.advanced.tests.powerdns.com.'
1090 query = dns.message.make_query(name, 'A', 'IN')
1091 expectedResponse = dns.message.make_response(query)
1092 expectedResponse.set_rcode(dns.rcode.REFUSED)
1093
1094 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1095 self.assertEquals(receivedResponse, expectedResponse)
1096
1097 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1098 self.assertEquals(receivedResponse, expectedResponse)
1099
1100 # less than 5 labels, the query should be refused
1101 name = 'labelscountadvanced.tests.powerdns.com.'
1102 query = dns.message.make_query(name, 'A', 'IN')
1103 expectedResponse = dns.message.make_response(query)
1104 expectedResponse.set_rcode(dns.rcode.REFUSED)
1105
1106 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1107 self.assertEquals(receivedResponse, expectedResponse)
1108
1109 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1110 self.assertEquals(receivedResponse, expectedResponse)
1111
1112class TestAdvancedWireLengthRule(DNSDistTest):
1113
1114 _config_template = """
1115 addAction(QNameWireLengthRule(54,56), RCodeAction(dnsdist.REFUSED))
1116 newServer{address="127.0.0.1:%s"}
1117 """
1118
1119 def testAdvancedWireLengthRule(self):
1120 """
1121 Advanced: QNameWireLengthRule(54,56)
1122 """
1123 name = 'longenough.qnamewirelength.advanced.tests.powerdns.com.'
1124 query = dns.message.make_query(name, 'A', 'IN')
1125 response = dns.message.make_response(query)
1126 rrset = dns.rrset.from_text(name,
1127 3600,
1128 dns.rdataclass.IN,
1129 dns.rdatatype.A,
1130 '192.0.2.1')
1131 response.answer.append(rrset)
1132
1133 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1134 self.assertTrue(receivedQuery)
1135 self.assertTrue(receivedResponse)
1136 receivedQuery.id = query.id
1137 self.assertEquals(query, receivedQuery)
1138 self.assertEquals(response, receivedResponse)
1139
1140 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1141 self.assertTrue(receivedQuery)
1142 self.assertTrue(receivedResponse)
1143 receivedQuery.id = query.id
1144 self.assertEquals(query, receivedQuery)
1145 self.assertEquals(response, receivedResponse)
1146
1147 # too short, the query should be refused
1148 name = 'short.qnamewirelength.advanced.tests.powerdns.com.'
1149 query = dns.message.make_query(name, 'A', 'IN')
1150 expectedResponse = dns.message.make_response(query)
1151 expectedResponse.set_rcode(dns.rcode.REFUSED)
1152
1153 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1154 self.assertEquals(receivedResponse, expectedResponse)
1155
1156 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1157 self.assertEquals(receivedResponse, expectedResponse)
1158
1159 # too long, the query should be refused
1160 name = 'toolongtobevalid.qnamewirelength.advanced.tests.powerdns.com.'
1161 query = dns.message.make_query(name, 'A', 'IN')
1162 expectedResponse = dns.message.make_response(query)
1163 expectedResponse.set_rcode(dns.rcode.REFUSED)
1164
1165 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1166 self.assertEquals(receivedResponse, expectedResponse)
1167
1168 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1169 self.assertEquals(receivedResponse, expectedResponse)
69389510
RG
1170
1171class TestAdvancedIncludeDir(DNSDistTest):
1172
1173 _config_template = """
1174 -- this directory contains a file allowing includedir.advanced.tests.powerdns.com.
1175 includeDirectory('test-include-dir')
69389510
RG
1176 newServer{address="127.0.0.1:%s"}
1177 """
1178
1179 def testAdvancedIncludeDirAllowed(self):
1180 """
1181 Advanced: includeDirectory()
1182 """
1183 name = 'includedir.advanced.tests.powerdns.com.'
1184 query = dns.message.make_query(name, 'A', 'IN')
1185 response = dns.message.make_response(query)
1186 rrset = dns.rrset.from_text(name,
1187 3600,
1188 dns.rdataclass.IN,
1189 dns.rdatatype.A,
1190 '192.0.2.1')
1191 response.answer.append(rrset)
1192
1193 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1194 self.assertTrue(receivedQuery)
1195 self.assertTrue(receivedResponse)
1196 receivedQuery.id = query.id
1197 self.assertEquals(query, receivedQuery)
1198 self.assertEquals(response, receivedResponse)
1199
1200 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1201 self.assertTrue(receivedQuery)
1202 self.assertTrue(receivedResponse)
1203 receivedQuery.id = query.id
1204 self.assertEquals(query, receivedQuery)
1205 self.assertEquals(response, receivedResponse)
1206
1207 # this one should be refused
1208 name = 'notincludedir.advanced.tests.powerdns.com.'
1209 query = dns.message.make_query(name, 'A', 'IN')
1210 expectedResponse = dns.message.make_response(query)
1211 expectedResponse.set_rcode(dns.rcode.REFUSED)
1212
1213 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1214 self.assertEquals(receivedResponse, expectedResponse)
1215
1216 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1217 self.assertEquals(receivedResponse, expectedResponse)
b82f0bc2
RG
1218
1219class TestAdvancedLuaDO(DNSDistTest):
1220
1221 _config_template = """
1222 function nxDOLua(dq)
1223 if dq:getDO() then
1224 return DNSAction.Nxdomain, ""
1225 end
1226 return DNSAction.None, ""
1227 end
a2ff35e3 1228 addAction(AllRule(), LuaAction(nxDOLua))
b82f0bc2
RG
1229 newServer{address="127.0.0.1:%s"}
1230 """
1231
1232 def testNxDOViaLua(self):
1233 """
1234 Advanced: Nx DO queries via Lua
1235 """
1236 name = 'nxdo.advanced.tests.powerdns.com.'
1237 query = dns.message.make_query(name, 'A', 'IN')
1238 response = dns.message.make_response(query)
1239 rrset = dns.rrset.from_text(name,
1240 3600,
1241 dns.rdataclass.IN,
1242 dns.rdatatype.AAAA,
1243 '::1')
1244 response.answer.append(rrset)
1245 queryWithDO = dns.message.make_query(name, 'A', 'IN', want_dnssec=True)
1246 doResponse = dns.message.make_response(queryWithDO)
1247 doResponse.set_rcode(dns.rcode.NXDOMAIN)
1248
1249 # without DO
1250 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1251 self.assertTrue(receivedQuery)
1252 self.assertTrue(receivedResponse)
1253 receivedQuery.id = query.id
1254 self.assertEquals(query, receivedQuery)
1255 self.assertEquals(receivedResponse, response)
1256
1257 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1258 self.assertTrue(receivedQuery)
1259 self.assertTrue(receivedResponse)
1260 receivedQuery.id = query.id
1261 self.assertEquals(query, receivedQuery)
1262 self.assertEquals(receivedResponse, response)
1263
1264 # with DO
1265 (_, receivedResponse) = self.sendUDPQuery(queryWithDO, response=None, useQueue=False)
1266 self.assertTrue(receivedResponse)
1267 doResponse.id = receivedResponse.id
b82f0bc2
RG
1268 self.assertEquals(receivedResponse, doResponse)
1269
1270 (_, receivedResponse) = self.sendTCPQuery(queryWithDO, response=None, useQueue=False)
1271 self.assertTrue(receivedResponse)
1272 doResponse.id = receivedResponse.id
1273 self.assertEquals(receivedResponse, doResponse)
26b86deb 1274
c4f5aeff
RG
1275class TestAdvancedLuaRefused(DNSDistTest):
1276
1277 _config_template = """
1278 function refuse(dq)
1279 return DNSAction.Refused, ""
1280 end
a2ff35e3 1281 addAction(AllRule(), LuaAction(refuse))
c4f5aeff
RG
1282 newServer{address="127.0.0.1:%s"}
1283 """
1284
1285 def testRefusedViaLua(self):
1286 """
1287 Advanced: Refused via Lua
1288 """
1289 name = 'refused.advanced.tests.powerdns.com.'
1290 query = dns.message.make_query(name, 'A', 'IN')
1291 response = dns.message.make_response(query)
1292 rrset = dns.rrset.from_text(name,
1293 3600,
1294 dns.rdataclass.IN,
1295 dns.rdatatype.AAAA,
1296 '::1')
1297 response.answer.append(rrset)
1298 refusedResponse = dns.message.make_response(query)
1299 refusedResponse.set_rcode(dns.rcode.REFUSED)
1300
1301 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1302 self.assertTrue(receivedResponse)
1303 refusedResponse.id = receivedResponse.id
1304 self.assertEquals(receivedResponse, refusedResponse)
63cdc73d
CHB
1305
1306 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1307 self.assertTrue(receivedResponse)
1308 refusedResponse.id = receivedResponse.id
1309 self.assertEquals(receivedResponse, refusedResponse)
1310
1311class TestAdvancedLuaActionReturnSyntax(DNSDistTest):
1312
1313 _config_template = """
1314 function refuse(dq)
1315 return DNSAction.Refused
1316 end
1317 addAction(AllRule(), LuaAction(refuse))
1318 newServer{address="127.0.0.1:%s"}
1319 """
1320
1321 def testRefusedWithEmptyRule(self):
1322 """
1323 Advanced: Short syntax for LuaAction return values
1324 """
0b3789ef 1325 name = 'short.refused.advanced.tests.powerdns.com.'
63cdc73d
CHB
1326 query = dns.message.make_query(name, 'A', 'IN')
1327 response = dns.message.make_response(query)
1328 rrset = dns.rrset.from_text(name,
1329 3600,
1330 dns.rdataclass.IN,
1331 dns.rdatatype.AAAA,
1332 '::1')
1333 response.answer.append(rrset)
1334 refusedResponse = dns.message.make_response(query)
1335 refusedResponse.set_rcode(dns.rcode.REFUSED)
1336
1337 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1338 self.assertTrue(receivedResponse)
1339 refusedResponse.id = receivedResponse.id
1340 self.assertEquals(receivedResponse, refusedResponse)
c4f5aeff
RG
1341
1342 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1343 self.assertTrue(receivedResponse)
1344 refusedResponse.id = receivedResponse.id
1345 self.assertEquals(receivedResponse, refusedResponse)
1346
1347class TestAdvancedLuaTruncated(DNSDistTest):
1348
1349 _config_template = """
1350 function trunc(dq)
1351 if not dq.tcp then
1352 return DNSAction.Truncate, ""
1353 end
1354 return DNSAction.None, ""
1355 end
a2ff35e3 1356 addAction(AllRule(), LuaAction(trunc))
c4f5aeff
RG
1357 newServer{address="127.0.0.1:%s"}
1358 """
1359
1360 def testTCViaLua(self):
1361 """
1362 Advanced: TC via Lua
1363 """
1364 name = 'tc.advanced.tests.powerdns.com.'
1365 query = dns.message.make_query(name, 'A', 'IN')
1366 response = dns.message.make_response(query)
1367 rrset = dns.rrset.from_text(name,
1368 3600,
1369 dns.rdataclass.IN,
1370 dns.rdatatype.AAAA,
1371 '::1')
1372 response.answer.append(rrset)
1373
1374 truncatedResponse = dns.message.make_response(query)
1375 truncatedResponse.flags |= dns.flags.TC
1376
1377 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1378 self.assertTrue(receivedResponse)
1379 truncatedResponse.id = receivedResponse.id
1380 self.assertEquals(receivedResponse, truncatedResponse)
1381
1382 # no truncation over TCP
1383 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1384 self.assertTrue(receivedQuery)
1385 self.assertTrue(receivedResponse)
1386 receivedQuery.id = query.id
1387 self.assertEquals(query, receivedQuery)
1388 self.assertEquals(receivedResponse, response)
1389
26b86deb
RG
1390class TestStatNodeRespRingSince(DNSDistTest):
1391
1392 _consoleKey = DNSDistTest.generateConsoleKey()
b4f23783 1393 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
26b86deb
RG
1394 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
1395 _config_template = """
1396 setKey("%s")
1397 controlSocket("127.0.0.1:%s")
1398 s1 = newServer{address="127.0.0.1:%s"}
1399 s1:setUp()
1400 function visitor(node, self, childstat)
1401 table.insert(nodesSeen, node.fullname)
1402 end
1403 """
1404
1405 def testStatNodeRespRingSince(self):
1406 """
1407 Advanced: StatNodeRespRing with optional since parameter
1408
1409 """
1410 name = 'statnodesince.advanced.tests.powerdns.com.'
1411 query = dns.message.make_query(name, 'A', 'IN')
1412 response = dns.message.make_response(query)
1413 rrset = dns.rrset.from_text(name,
1414 1,
1415 dns.rdataclass.IN,
1416 dns.rdatatype.A,
1417 '127.0.0.1')
1418 response.answer.append(rrset)
1419
1420 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1421 self.assertTrue(receivedQuery)
1422 self.assertTrue(receivedResponse)
1423 receivedQuery.id = query.id
1424 self.assertEquals(query, receivedQuery)
1425 self.assertEquals(response, receivedResponse)
1426
1427 self.sendConsoleCommand("nodesSeen = {}")
1428 self.sendConsoleCommand("statNodeRespRing(visitor)")
1429 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1430 nodes = nodes.strip("\n")
26b86deb
RG
1431 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1432advanced.tests.powerdns.com.
1433tests.powerdns.com.
1434powerdns.com.
1435com.""")
1436
1437 self.sendConsoleCommand("nodesSeen = {}")
1438 self.sendConsoleCommand("statNodeRespRing(visitor, 0)")
1439 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1440 nodes = nodes.strip("\n")
26b86deb
RG
1441 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1442advanced.tests.powerdns.com.
1443tests.powerdns.com.
1444powerdns.com.
1445com.""")
1446
1447 time.sleep(5)
1448
1449 self.sendConsoleCommand("nodesSeen = {}")
1450 self.sendConsoleCommand("statNodeRespRing(visitor)")
1451 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1452 nodes = nodes.strip("\n")
26b86deb
RG
1453 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1454advanced.tests.powerdns.com.
1455tests.powerdns.com.
1456powerdns.com.
1457com.""")
1458
1459 self.sendConsoleCommand("nodesSeen = {}")
1460 self.sendConsoleCommand("statNodeRespRing(visitor, 5)")
1461 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1462 nodes = nodes.strip("\n")
26b86deb
RG
1463 self.assertEquals(nodes, """""")
1464
1465 self.sendConsoleCommand("nodesSeen = {}")
1466 self.sendConsoleCommand("statNodeRespRing(visitor, 10)")
1467 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1468 nodes = nodes.strip("\n")
26b86deb
RG
1469 self.assertEquals(nodes, """statnodesince.advanced.tests.powerdns.com.
1470advanced.tests.powerdns.com.
1471tests.powerdns.com.
1472powerdns.com.
1473com.""")
7caebbb2
RG
1474
1475class TestAdvancedRD(DNSDistTest):
1476
1477 _config_template = """
1478 addAction(RDRule(), RCodeAction(dnsdist.REFUSED))
1479 newServer{address="127.0.0.1:%s"}
1480 """
1481
1482 def testAdvancedRDRefused(self):
1483 """
1484 Advanced: RD query is refused
1485 """
1486 name = 'rd.advanced.tests.powerdns.com.'
1487 query = dns.message.make_query(name, 'A', 'IN')
1488 expectedResponse = dns.message.make_response(query)
1489 expectedResponse.set_rcode(dns.rcode.REFUSED)
1490
1491 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1492 self.assertEquals(receivedResponse, expectedResponse)
1493
1494 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1495 self.assertEquals(receivedResponse, expectedResponse)
1496
1497 def testAdvancedNoRDAllowed(self):
1498 """
1499 Advanced: No-RD query is allowed
1500 """
1501 name = 'no-rd.advanced.tests.powerdns.com.'
1502 query = dns.message.make_query(name, 'A', 'IN')
1503 query.flags &= ~dns.flags.RD
1504 response = dns.message.make_response(query)
1505
1506 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1507 receivedQuery.id = query.id
1508 self.assertEquals(receivedQuery, query)
1509 self.assertEquals(receivedResponse, response)
1510
1511 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1512 receivedQuery.id = query.id
1513 self.assertEquals(receivedQuery, query)
1514 self.assertEquals(receivedResponse, response)
b052847c
RG
1515
1516class TestAdvancedGetLocalPort(DNSDistTest):
1517
1518 _config_template = """
1519 function answerBasedOnLocalPort(dq)
1520 local port = dq.localaddr:getPort()
1521 return DNSAction.Spoof, "port-was-"..port..".local-port.advanced.tests.powerdns.com."
1522 end
a2ff35e3 1523 addAction("local-port.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
b052847c
RG
1524 newServer{address="127.0.0.1:%s"}
1525 """
1526
1527 def testAdvancedGetLocalPort(self):
1528 """
1529 Advanced: Return CNAME containing the local port
1530 """
1531 name = 'local-port.advanced.tests.powerdns.com.'
1532 query = dns.message.make_query(name, 'A', 'IN')
1533 # dnsdist set RA = RD for spoofed responses
1534 query.flags &= ~dns.flags.RD
1535
1536 response = dns.message.make_response(query)
1537 rrset = dns.rrset.from_text(name,
1538 60,
1539 dns.rdataclass.IN,
1540 dns.rdatatype.CNAME,
1541 'port-was-{}.local-port.advanced.tests.powerdns.com.'.format(self._dnsDistPort))
1542 response.answer.append(rrset)
1543
1544 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1545 self.assertEquals(receivedResponse, response)
1546
1547 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1548 self.assertEquals(receivedResponse, response)
1549
1550class TestAdvancedGetLocalPortOnAnyBind(DNSDistTest):
1551
1552 _config_template = """
1553 function answerBasedOnLocalPort(dq)
1554 local port = dq.localaddr:getPort()
1555 return DNSAction.Spoof, "port-was-"..port..".local-port-any.advanced.tests.powerdns.com."
1556 end
a2ff35e3 1557 addAction("local-port-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
b052847c
RG
1558 newServer{address="127.0.0.1:%s"}
1559 """
1560 _dnsDistListeningAddr = "0.0.0.0"
1561
1562 def testAdvancedGetLocalPortOnAnyBind(self):
1563 """
1564 Advanced: Return CNAME containing the local port for an ANY bind
1565 """
1566 name = 'local-port-any.advanced.tests.powerdns.com.'
1567 query = dns.message.make_query(name, 'A', 'IN')
1568 # dnsdist set RA = RD for spoofed responses
1569 query.flags &= ~dns.flags.RD
1570
1571 response = dns.message.make_response(query)
1572 rrset = dns.rrset.from_text(name,
1573 60,
1574 dns.rdataclass.IN,
1575 dns.rdatatype.CNAME,
1576 'port-was-{}.local-port-any.advanced.tests.powerdns.com.'.format(self._dnsDistPort))
1577 response.answer.append(rrset)
1578
1579 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1580 self.assertEquals(receivedResponse, response)
1581
1582 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1583 self.assertEquals(receivedResponse, response)
29b6a412 1584
f93e2327
RG
1585class TestAdvancedGetLocalAddressOnAnyBind(DNSDistTest):
1586
1587 _config_template = """
1588 function answerBasedOnLocalAddress(dq)
1589 local dest = dq.localaddr:toString()
1590 local i, j = string.find(dest, "[0-9.]+")
1591 local addr = string.sub(dest, i, j)
1592 local dashAddr = string.gsub(addr, "[.]", "-")
1593 return DNSAction.Spoof, "address-was-"..dashAddr..".local-address-any.advanced.tests.powerdns.com."
1594 end
1595 addAction("local-address-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalAddress))
1596 newServer{address="127.0.0.1:%s"}
1597 """
1598 _dnsDistListeningAddr = "0.0.0.0"
1599
1600 def testAdvancedGetLocalAddressOnAnyBind(self):
1601 """
1602 Advanced: Return CNAME containing the local address for an ANY bind
1603 """
1604 name = 'local-address-any.advanced.tests.powerdns.com.'
1605 query = dns.message.make_query(name, 'A', 'IN')
1606 # dnsdist set RA = RD for spoofed responses
1607 query.flags &= ~dns.flags.RD
1608
1609 response = dns.message.make_response(query)
1610 rrset = dns.rrset.from_text(name,
1611 60,
1612 dns.rdataclass.IN,
1613 dns.rdatatype.CNAME,
1614 'address-was-127-0-0-1.local-address-any.advanced.tests.powerdns.com.')
1615 response.answer.append(rrset)
1616
1617 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1618 self.assertEquals(receivedResponse, response)
1619
1620 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
1621 self.assertEquals(receivedResponse, response)
1622
29b6a412
CH
1623class TestAdvancedLuaTempFailureTTL(DNSDistTest):
1624
1625 _config_template = """
1626 function testAction(dq)
1627 if dq.tempFailureTTL ~= nil then
1628 return DNSAction.Spoof, "initially.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1629 end
1630 dq.tempFailureTTL = 30
1631 if dq.tempFailureTTL ~= 30 then
1632 return DNSAction.Spoof, "after.set.not.expected.value.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1633 end
1634 dq.tempFailureTTL = nil
1635 if dq.tempFailureTTL ~= nil then
1636 return DNSAction.Spoof, "after.unset.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1637 end
1638 return DNSAction.None, ""
1639 end
1640 addAction(AllRule(), LuaAction(testAction))
1641 newServer{address="127.0.0.1:%s"}
1642 """
1643
1644 def testTempFailureTTLBinding(self):
1645 """
cdc2fb01 1646 Advanced: Exercise dq.tempFailureTTL Lua binding
29b6a412
CH
1647 """
1648 name = 'tempfailurettlbinding.advanced.tests.powerdns.com.'
1649 query = dns.message.make_query(name, 'A', 'IN')
1650 response = dns.message.make_response(query)
1651 rrset = dns.rrset.from_text(name,
1652 3600,
1653 dns.rdataclass.IN,
1654 dns.rdatatype.AAAA,
1655 '::1')
1656 response.answer.append(rrset)
1657
1658 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1659 self.assertTrue(receivedQuery)
1660 self.assertTrue(receivedResponse)
1661 receivedQuery.id = query.id
1662 self.assertEquals(query, receivedQuery)
1663 self.assertEquals(receivedResponse, response)
4bfdbd34
PD
1664
1665class TestAdvancedEDNSOptionRule(DNSDistTest):
1666
1667 _config_template = """
1668 newServer{address="127.0.0.1:%s"}
6bb92a06 1669 addAction(EDNSOptionRule(EDNSOptionCode.ECS), DropAction())
4bfdbd34
PD
1670 """
1671
1672 def testDropped(self):
1673 """
cdc2fb01 1674 Advanced: A question with ECS is dropped
4bfdbd34
PD
1675 """
1676
1677 name = 'ednsoptionrule.advanced.tests.powerdns.com.'
1678
1679 ecso = clientsubnetoption.ClientSubnetOption('127.0.0.1', 24)
1680 query = dns.message.make_query(name, 'A', 'IN', use_edns=True, options=[ecso], payload=512)
1681
1682 (_, receivedResponse) = self.sendUDPQuery(query, response=None)
1683 self.assertEquals(receivedResponse, None)
1684 (_, receivedResponse) = self.sendTCPQuery(query, response=None)
1685 self.assertEquals(receivedResponse, None)
1686
1687 def testReplied(self):
1688 """
cdc2fb01 1689 Advanced: A question without ECS is answered
4bfdbd34
PD
1690 """
1691
1692 name = 'ednsoptionrule.advanced.tests.powerdns.com.'
1693
1694 # both with EDNS
1695 query = dns.message.make_query(name, 'A', 'IN', use_edns=True, options=[], payload=512)
1696 response = dns.message.make_response(query)
1697
1698 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1699 self.assertTrue(receivedQuery)
1700 self.assertTrue(receivedResponse)
1701
1702 receivedQuery.id = query.id
1703 self.assertEquals(query, receivedQuery)
1704 self.assertEquals(receivedResponse, response)
1705
1706 # and with no EDNS at all
1707 query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
1708 response = dns.message.make_response(query)
1709
1710 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1711 self.assertTrue(receivedQuery)
1712 self.assertTrue(receivedResponse)
1713
1714 receivedQuery.id = query.id
1715 self.assertEquals(query, receivedQuery)
1716 self.assertEquals(receivedResponse, response)
bcc47804
RG
1717
1718class TestAdvancedAllowHeaderOnly(DNSDistTest):
1719
1720 _config_template = """
1721 newServer{address="127.0.0.1:%s"}
1722 setAllowEmptyResponse(true)
1723 """
1724
1725 def testHeaderOnlyRefused(self):
1726 """
1727 Advanced: Header-only refused response
1728 """
1729 name = 'header-only-refused-response.advanced.tests.powerdns.com.'
1730 query = dns.message.make_query(name, 'A', 'IN')
1731 response = dns.message.make_response(query)
1732 response.set_rcode(dns.rcode.REFUSED)
1733 response.question = []
1734
1735 for method in ("sendUDPQuery", "sendTCPQuery"):
1736 sender = getattr(self, method)
1737 (receivedQuery, receivedResponse) = sender(query, response)
1738 self.assertTrue(receivedQuery)
1739 receivedQuery.id = query.id
1740 self.assertEquals(query, receivedQuery)
1741 self.assertEquals(receivedResponse, response)
1742
1743 def testHeaderOnlyNoErrorResponse(self):
1744 """
1745 Advanced: Header-only NoError response should be allowed
1746 """
1747 name = 'header-only-noerror-response.advanced.tests.powerdns.com.'
1748 query = dns.message.make_query(name, 'A', 'IN')
1749 response = dns.message.make_response(query)
1750 response.question = []
1751
1752 for method in ("sendUDPQuery", "sendTCPQuery"):
1753 sender = getattr(self, method)
1754 (receivedQuery, receivedResponse) = sender(query, response)
1755 self.assertTrue(receivedQuery)
1756 receivedQuery.id = query.id
1757 self.assertEquals(query, receivedQuery)
1758 self.assertEquals(receivedResponse, response)
1759
1760 def testHeaderOnlyNXDResponse(self):
1761 """
1762 Advanced: Header-only NXD response should be allowed
1763 """
1764 name = 'header-only-nxd-response.advanced.tests.powerdns.com.'
1765 query = dns.message.make_query(name, 'A', 'IN')
1766 response = dns.message.make_response(query)
1767 response.set_rcode(dns.rcode.NXDOMAIN)
1768 response.question = []
1769
1770 for method in ("sendUDPQuery", "sendTCPQuery"):
1771 sender = getattr(self, method)
1772 (receivedQuery, receivedResponse) = sender(query, response)
1773 self.assertTrue(receivedQuery)
1774 receivedQuery.id = query.id
1775 self.assertEquals(query, receivedQuery)
1776 self.assertEquals(receivedResponse, response)
f61e6149
RG
1777
1778class TestAdvancedEDNSVersionnRule(DNSDistTest):
1779
1780 _config_template = """
1781 newServer{address="127.0.0.1:%s"}
1782 addAction(EDNSVersionRule(0), ERCodeAction(dnsdist.BADVERS))
1783 """
1784
1785 def testDropped(self):
1786 """
1787 Advanced: A question with ECS version larger than 0 is dropped
1788 """
1789
1790 name = 'ednsversionrule.advanced.tests.powerdns.com.'
1791
1792 query = dns.message.make_query(name, 'A', 'IN', use_edns=1)
1793 expectedResponse = dns.message.make_response(query)
1794 expectedResponse.set_rcode(dns.rcode.BADVERS)
1795
1796 for method in ("sendUDPQuery", "sendTCPQuery"):
1797 sender = getattr(self, method)
1798 (_, receivedResponse) = sender(query, response=None)
1799 self.assertEquals(receivedResponse, expectedResponse)
1800
1801 def testNoEDNS0Pass(self):
1802 """
1803 Advanced: A question with ECS version 0 goes through
1804 """
1805
1806 name = 'ednsversionrule.advanced.tests.powerdns.com.'
1807
1808 query = dns.message.make_query(name, 'A', 'IN', use_edns=True)
1809 response = dns.message.make_response(query)
1810
1811 for method in ("sendUDPQuery", "sendTCPQuery"):
1812 sender = getattr(self, method)
1813 (receivedQuery, receivedResponse) = sender(query, response)
1814 receivedQuery.id = query.id
1815 self.assertEquals(query, receivedQuery)
1816 self.assertEquals(receivedResponse, response)
1817
1818 def testReplied(self):
1819 """
1820 Advanced: A question without ECS goes through
1821 """
1822
1823 name = 'ednsoptionrule.advanced.tests.powerdns.com.'
1824
1825 query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
1826 response = dns.message.make_response(query)
1827
1828 for method in ("sendUDPQuery", "sendTCPQuery"):
1829 sender = getattr(self, method)
1830 (receivedQuery, receivedResponse) = sender(query, response)
1831 receivedQuery.id = query.id
1832 self.assertEquals(query, receivedQuery)
1833 self.assertEquals(receivedResponse, response)
488fd7c8
RG
1834
1835class TestSetRules(DNSDistTest):
1836
1837 _consoleKey = DNSDistTest.generateConsoleKey()
1838 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
1839 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
1840 _config_template = """
1841 setKey("%s")
1842 controlSocket("127.0.0.1:%s")
1843 newServer{address="127.0.0.1:%s"}
1844 addAction(AllRule(), SpoofAction("192.0.2.1"))
1845 """
1846
1847 def testClearThenSetRules(self):
1848 """
1849 Advanced: Clear rules, set rules
1850
1851 """
1852 name = 'clearthensetrules.advanced.tests.powerdns.com.'
1853 query = dns.message.make_query(name, 'A', 'IN')
1854 # dnsdist set RA = RD for spoofed responses
1855 query.flags &= ~dns.flags.RD
1856 expectedResponse = dns.message.make_response(query)
1857 rrset = dns.rrset.from_text(name,
1858 60,
1859 dns.rdataclass.IN,
1860 dns.rdatatype.A,
1861 '192.0.2.1')
1862 expectedResponse.answer.append(rrset)
1863
1864 for method in ("sendUDPQuery", "sendTCPQuery"):
1865 sender = getattr(self, method)
1866
1867 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1868 self.assertTrue(receivedResponse)
1869 self.assertEquals(expectedResponse, receivedResponse)
1870
1871 # clear all the rules, we should not be spoofing and get a SERVFAIL from the responder instead
1872 self.sendConsoleCommand("clearRules()")
1873
1874 expectedResponse = dns.message.make_response(query)
1875 expectedResponse.set_rcode(dns.rcode.SERVFAIL)
1876
1877 for method in ("sendUDPQuery", "sendTCPQuery"):
1878 sender = getattr(self, method)
1879
1880 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1881 self.assertTrue(receivedResponse)
1882 self.assertEquals(expectedResponse, receivedResponse)
1883
1884 # insert a new spoofing rule
1885 self.sendConsoleCommand("setRules({ newRuleAction(AllRule(), SpoofAction(\"192.0.2.2\")) })")
1886
1887 expectedResponse = dns.message.make_response(query)
1888 rrset = dns.rrset.from_text(name,
1889 60,
1890 dns.rdataclass.IN,
1891 dns.rdatatype.A,
1892 '192.0.2.2')
1893 expectedResponse.answer.append(rrset)
1894
1895 for method in ("sendUDPQuery", "sendTCPQuery"):
1896 sender = getattr(self, method)
1897
1898 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1899 self.assertTrue(receivedResponse)
1900 self.assertEquals(expectedResponse, receivedResponse)