]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Advanced.py
e4d4c636dd73f21c44a17c5b7eada7c028ea8973
3 from datetime
import datetime
, timedelta
8 import clientsubnetoption
9 from dnsdisttests
import DNSDistTest
11 class TestAdvancedAllow(DNSDistTest
):
13 _config_template
= """
14 addAction(AllRule(), NoneAction())
15 addAction(makeRule("allowed.advanced.tests.powerdns.com."), AllowAction())
16 addAction(AllRule(), DropAction())
17 newServer{address="127.0.0.1:%s"}
20 def testAdvancedAllow(self
):
22 Advanced: Allowed qname is not dropped
24 A query for allowed.advanced.tests.powerdns.com. should be allowed
25 while others should be dropped.
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
,
35 response
.answer
.append(rrset
)
37 for method
in ("sendUDPQuery", "sendTCPQuery"):
38 sender
= getattr(self
, method
)
39 (receivedQuery
, receivedResponse
) = sender(query
, response
)
40 self
.assertTrue(receivedQuery
)
41 self
.assertTrue(receivedResponse
)
42 receivedQuery
.id = query
.id
43 self
.assertEquals(query
, receivedQuery
)
44 self
.assertEquals(response
, receivedResponse
)
46 def testAdvancedAllowDropped(self
):
48 Advanced: Not allowed qname is dropped
50 A query for notallowed.advanced.tests.powerdns.com. should be dropped.
52 name
= 'notallowed.advanced.tests.powerdns.com.'
53 query
= dns
.message
.make_query(name
, 'A', 'IN')
55 for method
in ("sendUDPQuery", "sendTCPQuery"):
56 sender
= getattr(self
, method
)
57 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
59 class TestAdvancedFixupCase(DNSDistTest
):
61 _config_template
= """
64 newServer{address="127.0.0.1:%s"}
67 def testAdvancedFixupCase(self
):
71 Send a query with lower and upper chars,
72 make the backend return a lowercase version,
73 check that dnsdist fixes the response.
75 name
= 'fiXuPCasE.advanced.tests.powerdns.com.'
76 query
= dns
.message
.make_query(name
, 'A', 'IN')
77 lowercasequery
= dns
.message
.make_query(name
.lower(), 'A', 'IN')
78 response
= dns
.message
.make_response(lowercasequery
)
79 expectedResponse
= dns
.message
.make_response(query
)
80 rrset
= dns
.rrset
.from_text(name
,
85 response
.answer
.append(rrset
)
86 expectedResponse
.answer
.append(rrset
)
88 for method
in ("sendUDPQuery", "sendTCPQuery"):
89 sender
= getattr(self
, method
)
90 (receivedQuery
, receivedResponse
) = sender(query
, response
)
91 self
.assertTrue(receivedQuery
)
92 self
.assertTrue(receivedResponse
)
93 receivedQuery
.id = query
.id
94 self
.assertEquals(query
, receivedQuery
)
95 self
.assertEquals(expectedResponse
, receivedResponse
)
97 class TestAdvancedRemoveRD(DNSDistTest
):
99 _config_template
= """
100 addAction("norecurse.advanced.tests.powerdns.com.", NoRecurseAction())
101 newServer{address="127.0.0.1:%s"}
104 def testAdvancedNoRD(self
):
108 Send a query with RD,
109 check that dnsdist clears the RD flag.
111 name
= 'norecurse.advanced.tests.powerdns.com.'
112 query
= dns
.message
.make_query(name
, 'A', 'IN')
113 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
114 expectedQuery
.flags
&= ~dns
.flags
.RD
116 response
= dns
.message
.make_response(query
)
117 rrset
= dns
.rrset
.from_text(name
,
122 response
.answer
.append(rrset
)
124 for method
in ("sendUDPQuery", "sendTCPQuery"):
125 sender
= getattr(self
, method
)
126 (receivedQuery
, receivedResponse
) = sender(query
, response
)
127 self
.assertTrue(receivedQuery
)
128 self
.assertTrue(receivedResponse
)
129 receivedQuery
.id = expectedQuery
.id
130 self
.assertEquals(expectedQuery
, receivedQuery
)
131 self
.assertEquals(response
, receivedResponse
)
133 def testAdvancedKeepRD(self
):
135 Advanced: No RD canary
137 Send a query with RD for a canary domain,
138 check that dnsdist does not clear the RD flag.
140 name
= 'keeprecurse.advanced.tests.powerdns.com.'
141 query
= dns
.message
.make_query(name
, 'A', 'IN')
143 response
= dns
.message
.make_response(query
)
144 rrset
= dns
.rrset
.from_text(name
,
149 response
.answer
.append(rrset
)
151 for method
in ("sendUDPQuery", "sendTCPQuery"):
152 sender
= getattr(self
, method
)
153 (receivedQuery
, receivedResponse
) = sender(query
, response
)
154 self
.assertTrue(receivedQuery
)
155 self
.assertTrue(receivedResponse
)
156 receivedQuery
.id = query
.id
157 self
.assertEquals(query
, receivedQuery
)
158 self
.assertEquals(response
, receivedResponse
)
160 class TestAdvancedAddCD(DNSDistTest
):
162 _config_template
= """
163 addAction("setcd.advanced.tests.powerdns.com.", DisableValidationAction())
164 addAction(makeRule("setcdviaaction.advanced.tests.powerdns.com."), DisableValidationAction())
165 newServer{address="127.0.0.1:%s"}
168 def testAdvancedSetCD(self
):
172 Send a query with CD cleared,
173 check that dnsdist set the CD flag.
175 name
= 'setcd.advanced.tests.powerdns.com.'
176 query
= dns
.message
.make_query(name
, 'A', 'IN')
177 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
178 expectedQuery
.flags |
= dns
.flags
.CD
180 response
= dns
.message
.make_response(query
)
181 rrset
= dns
.rrset
.from_text(name
,
186 response
.answer
.append(rrset
)
188 for method
in ("sendUDPQuery", "sendTCPQuery"):
189 sender
= getattr(self
, method
)
190 (receivedQuery
, receivedResponse
) = sender(query
, response
)
191 self
.assertTrue(receivedQuery
)
192 self
.assertTrue(receivedResponse
)
193 receivedQuery
.id = expectedQuery
.id
194 self
.assertEquals(expectedQuery
, receivedQuery
)
195 self
.assertEquals(response
, receivedResponse
)
197 def testAdvancedSetCDViaAction(self
):
199 Advanced: Set CD via Action
201 Send a query with CD cleared,
202 check that dnsdist set the CD flag.
204 name
= 'setcdviaaction.advanced.tests.powerdns.com.'
205 query
= dns
.message
.make_query(name
, 'A', 'IN')
206 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
207 expectedQuery
.flags |
= dns
.flags
.CD
209 response
= dns
.message
.make_response(query
)
210 rrset
= dns
.rrset
.from_text(name
,
215 response
.answer
.append(rrset
)
217 for method
in ("sendUDPQuery", "sendTCPQuery"):
218 sender
= getattr(self
, method
)
219 (receivedQuery
, receivedResponse
) = sender(query
, response
)
220 self
.assertTrue(receivedQuery
)
221 self
.assertTrue(receivedResponse
)
222 receivedQuery
.id = expectedQuery
.id
223 self
.assertEquals(expectedQuery
, receivedQuery
)
224 self
.assertEquals(response
, receivedResponse
)
226 def testAdvancedKeepNoCD(self
):
228 Advanced: Preserve CD canary
230 Send a query without CD for a canary domain,
231 check that dnsdist does not set the CD flag.
233 name
= 'keepnocd.advanced.tests.powerdns.com.'
234 query
= dns
.message
.make_query(name
, 'A', 'IN')
236 response
= dns
.message
.make_response(query
)
237 rrset
= dns
.rrset
.from_text(name
,
242 response
.answer
.append(rrset
)
244 for method
in ("sendUDPQuery", "sendTCPQuery"):
245 sender
= getattr(self
, method
)
246 (receivedQuery
, receivedResponse
) = sender(query
, response
)
247 self
.assertTrue(receivedQuery
)
248 self
.assertTrue(receivedResponse
)
249 receivedQuery
.id = query
.id
250 self
.assertEquals(query
, receivedQuery
)
251 self
.assertEquals(response
, receivedResponse
)
253 class TestAdvancedClearRD(DNSDistTest
):
255 _config_template
= """
256 addAction("clearrd.advanced.tests.powerdns.com.", NoRecurseAction())
257 addAction(makeRule("clearrdviaaction.advanced.tests.powerdns.com."), NoRecurseAction())
258 newServer{address="127.0.0.1:%s"}
261 def testAdvancedClearRD(self
):
265 Send a query with RD set,
266 check that dnsdist clears the RD flag.
268 name
= 'clearrd.advanced.tests.powerdns.com.'
269 query
= dns
.message
.make_query(name
, 'A', 'IN')
270 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
271 expectedQuery
.flags
&= ~dns
.flags
.RD
273 response
= dns
.message
.make_response(query
)
274 rrset
= dns
.rrset
.from_text(name
,
279 response
.answer
.append(rrset
)
281 for method
in ("sendUDPQuery", "sendTCPQuery"):
282 sender
= getattr(self
, method
)
283 (receivedQuery
, receivedResponse
) = sender(query
, response
)
284 self
.assertTrue(receivedQuery
)
285 self
.assertTrue(receivedResponse
)
286 receivedQuery
.id = expectedQuery
.id
287 self
.assertEquals(expectedQuery
, receivedQuery
)
288 self
.assertEquals(response
, receivedResponse
)
290 def testAdvancedClearRDViaAction(self
):
292 Advanced: Clear RD via Action
294 Send a query with RD set,
295 check that dnsdist clears the RD flag.
297 name
= 'clearrdviaaction.advanced.tests.powerdns.com.'
298 query
= dns
.message
.make_query(name
, 'A', 'IN')
299 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
300 expectedQuery
.flags
&= ~dns
.flags
.RD
302 response
= dns
.message
.make_response(query
)
303 rrset
= dns
.rrset
.from_text(name
,
308 response
.answer
.append(rrset
)
310 for method
in ("sendUDPQuery", "sendTCPQuery"):
311 sender
= getattr(self
, method
)
312 (receivedQuery
, receivedResponse
) = sender(query
, response
)
313 self
.assertTrue(receivedQuery
)
314 self
.assertTrue(receivedResponse
)
315 receivedQuery
.id = expectedQuery
.id
316 self
.assertEquals(expectedQuery
, receivedQuery
)
317 self
.assertEquals(response
, receivedResponse
)
319 def testAdvancedKeepRD(self
):
321 Advanced: Preserve RD canary
323 Send a query with RD for a canary domain,
324 check that dnsdist does not clear the RD flag.
326 name
= 'keeprd.advanced.tests.powerdns.com.'
327 query
= dns
.message
.make_query(name
, 'A', 'IN')
329 response
= dns
.message
.make_response(query
)
330 rrset
= dns
.rrset
.from_text(name
,
335 response
.answer
.append(rrset
)
337 for method
in ("sendUDPQuery", "sendTCPQuery"):
338 sender
= getattr(self
, method
)
339 (receivedQuery
, receivedResponse
) = sender(query
, response
)
340 self
.assertTrue(receivedQuery
)
341 self
.assertTrue(receivedResponse
)
342 receivedQuery
.id = query
.id
343 self
.assertEquals(query
, receivedQuery
)
344 self
.assertEquals(response
, receivedResponse
)
347 class TestAdvancedACL(DNSDistTest
):
349 _config_template
= """
350 newServer{address="127.0.0.1:%s"}
352 _acl
= ['192.0.2.1/32']
354 def testACLBlocked(self
):
356 Advanced: ACL blocked
358 Send an A query to "tests.powerdns.com.",
359 we expect no response since 127.0.0.1 is not on the
362 name
= 'tests.powerdns.com.'
363 query
= dns
.message
.make_query(name
, 'A', 'IN')
365 for method
in ("sendUDPQuery", "sendTCPQuery"):
366 sender
= getattr(self
, method
)
367 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
368 self
.assertEquals(receivedResponse
, None)
370 class TestAdvancedDelay(DNSDistTest
):
372 _config_template
= """
373 addAction(AllRule(), DelayAction(1000))
374 newServer{address="127.0.0.1:%s"}
377 def testDelayed(self
):
381 Send an A query to "tests.powerdns.com.",
382 check that the response delay is longer than 1000 ms
383 over UDP, less than that over TCP.
385 name
= 'tests.powerdns.com.'
386 query
= dns
.message
.make_query(name
, 'A', 'IN')
387 response
= dns
.message
.make_response(query
)
388 rrset
= dns
.rrset
.from_text(name
,
393 response
.answer
.append(rrset
)
395 begin
= datetime
.now()
396 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
398 receivedQuery
.id = query
.id
399 self
.assertEquals(query
, receivedQuery
)
400 self
.assertEquals(response
, receivedResponse
)
401 self
.assertTrue((end
- begin
) > timedelta(0, 1))
403 begin
= datetime
.now()
404 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
406 receivedQuery
.id = query
.id
407 self
.assertEquals(query
, receivedQuery
)
408 self
.assertEquals(response
, receivedResponse
)
409 self
.assertTrue((end
- begin
) < timedelta(0, 1))
412 class TestAdvancedTruncateAnyAndTCP(DNSDistTest
):
414 _config_template
= """
416 addAction(AndRule({QTypeRule("ANY"), TCPRule(true)}), TCAction())
417 newServer{address="127.0.0.1:%s"}
419 def testTruncateAnyOverTCP(self
):
421 Advanced: Truncate ANY over TCP
423 Send an ANY query to "anytruncatetcp.advanced.tests.powerdns.com.",
424 should be truncated over TCP, not over UDP (yes, it makes no sense,
427 name
= 'anytruncatetcp.advanced.tests.powerdns.com.'
428 query
= dns
.message
.make_query(name
, 'ANY', 'IN')
429 # dnsdist sets RA = RD for TC responses
430 query
.flags
&= ~dns
.flags
.RD
432 response
= dns
.message
.make_response(query
)
433 rrset
= dns
.rrset
.from_text(name
,
439 response
.answer
.append(rrset
)
441 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
442 self
.assertTrue(receivedQuery
)
443 self
.assertTrue(receivedResponse
)
444 receivedQuery
.id = query
.id
445 self
.assertEquals(query
, receivedQuery
)
446 self
.assertEquals(receivedResponse
, response
)
448 expectedResponse
= dns
.message
.make_response(query
)
449 expectedResponse
.flags |
= dns
.flags
.TC
451 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
452 self
.assertEquals(receivedResponse
, expectedResponse
)
454 class TestAdvancedAndNot(DNSDistTest
):
456 _config_template
= """
457 addAction(AndRule({NotRule(QTypeRule("A")), TCPRule(false)}), RCodeAction(DNSRCode.NOTIMP))
458 newServer{address="127.0.0.1:%s"}
460 def testAOverUDPReturnsNotImplementedCanary(self
):
462 Advanced: !A && UDP canary
464 dnsdist is configured to reply 'not implemented' for query
465 over UDP AND !qtype A.
466 We send an A query over UDP and TCP, and check that the
469 name
= 'andnot.advanced.tests.powerdns.com.'
470 query
= dns
.message
.make_query(name
, 'A', 'IN')
471 response
= dns
.message
.make_response(query
)
472 rrset
= dns
.rrset
.from_text(name
,
477 response
.answer
.append(rrset
)
479 for method
in ("sendUDPQuery", "sendTCPQuery"):
480 sender
= getattr(self
, method
)
481 (receivedQuery
, receivedResponse
) = sender(query
, response
)
482 self
.assertTrue(receivedQuery
)
483 self
.assertTrue(receivedResponse
)
484 receivedQuery
.id = query
.id
485 self
.assertEquals(query
, receivedQuery
)
486 self
.assertEquals(receivedResponse
, response
)
488 def testAOverUDPReturnsNotImplemented(self
):
492 dnsdist is configured to reply 'not implemented' for query
493 over UDP AND !qtype A.
494 We send a TXT query over UDP and TCP, and check that the
495 response is OK for TCP and 'not implemented' for UDP.
497 name
= 'andnot.advanced.tests.powerdns.com.'
498 query
= dns
.message
.make_query(name
, 'TXT', 'IN')
499 # dnsdist sets RA = RD for TC responses
500 query
.flags
&= ~dns
.flags
.RD
502 expectedResponse
= dns
.message
.make_response(query
)
503 expectedResponse
.set_rcode(dns
.rcode
.NOTIMP
)
505 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
506 self
.assertEquals(receivedResponse
, expectedResponse
)
508 response
= dns
.message
.make_response(query
)
509 rrset
= dns
.rrset
.from_text(name
,
513 'nothing to see here')
514 response
.answer
.append(rrset
)
516 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
517 self
.assertTrue(receivedQuery
)
518 self
.assertTrue(receivedResponse
)
519 receivedQuery
.id = query
.id
520 self
.assertEquals(query
, receivedQuery
)
521 self
.assertEquals(receivedResponse
, response
)
523 class TestAdvancedOr(DNSDistTest
):
525 _config_template
= """
526 addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(DNSRCode.NOTIMP))
527 newServer{address="127.0.0.1:%s"}
529 def testAAAAOverUDPReturnsNotImplemented(self
):
531 Advanced: A || UDP: AAAA
533 dnsdist is configured to reply 'not implemented' for query
535 We send an AAAA query over UDP and TCP, and check that the
536 response is 'not implemented' for UDP and OK for TCP.
538 name
= 'aorudp.advanced.tests.powerdns.com.'
539 query
= dns
.message
.make_query(name
, 'AAAA', 'IN')
540 query
.flags
&= ~dns
.flags
.RD
541 response
= dns
.message
.make_response(query
)
542 rrset
= dns
.rrset
.from_text(name
,
547 response
.answer
.append(rrset
)
549 expectedResponse
= dns
.message
.make_response(query
)
550 expectedResponse
.set_rcode(dns
.rcode
.NOTIMP
)
552 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
553 self
.assertEquals(receivedResponse
, expectedResponse
)
555 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
556 self
.assertTrue(receivedQuery
)
557 self
.assertTrue(receivedResponse
)
558 receivedQuery
.id = query
.id
559 self
.assertEquals(query
, receivedQuery
)
560 self
.assertEquals(receivedResponse
, response
)
562 def testAOverUDPReturnsNotImplemented(self
):
564 Advanced: A || UDP: A
566 dnsdist is configured to reply 'not implemented' for query
568 We send an A query over UDP and TCP, and check that the
569 response is 'not implemented' for both.
571 name
= 'aorudp.advanced.tests.powerdns.com.'
572 query
= dns
.message
.make_query(name
, 'A', 'IN')
573 query
.flags
&= ~dns
.flags
.RD
575 expectedResponse
= dns
.message
.make_response(query
)
576 expectedResponse
.set_rcode(dns
.rcode
.NOTIMP
)
578 for method
in ("sendUDPQuery", "sendTCPQuery"):
579 sender
= getattr(self
, method
)
580 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
581 self
.assertEquals(receivedResponse
, expectedResponse
)
584 class TestAdvancedLogAction(DNSDistTest
):
586 _config_template
= """
587 newServer{address="127.0.0.1:%s"}
588 addAction(AllRule(), LogAction("dnsdist.log", false))
590 def testAdvancedLogAction(self
):
592 Advanced: Log all queries
596 name
= 'logaction.advanced.tests.powerdns.com.'
597 query
= dns
.message
.make_query(name
, 'A', 'IN')
598 response
= dns
.message
.make_response(query
)
599 rrset
= dns
.rrset
.from_text(name
,
604 response
.answer
.append(rrset
)
606 for _
in range(count
):
607 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
608 self
.assertTrue(receivedQuery
)
609 self
.assertTrue(receivedResponse
)
610 receivedQuery
.id = query
.id
611 self
.assertEquals(query
, receivedQuery
)
612 self
.assertEquals(response
, receivedResponse
)
614 self
.assertTrue(os
.path
.isfile('dnsdist.log'))
615 self
.assertTrue(os
.stat('dnsdist.log').st_size
> 0)
617 class TestAdvancedDNSSEC(DNSDistTest
):
619 _config_template
= """
620 newServer{address="127.0.0.1:%s"}
621 addAction(DNSSECRule(), DropAction())
623 def testAdvancedDNSSECDrop(self
):
625 Advanced: DNSSEC Rule
628 name
= 'dnssec.advanced.tests.powerdns.com.'
629 query
= dns
.message
.make_query(name
, 'A', 'IN')
630 doquery
= dns
.message
.make_query(name
, 'A', 'IN', want_dnssec
=True)
631 response
= dns
.message
.make_response(query
)
632 rrset
= dns
.rrset
.from_text(name
,
637 response
.answer
.append(rrset
)
639 for method
in ("sendUDPQuery", "sendTCPQuery"):
640 sender
= getattr(self
, method
)
641 (receivedQuery
, receivedResponse
) = sender(query
, response
)
642 self
.assertTrue(receivedQuery
)
643 self
.assertTrue(receivedResponse
)
644 receivedQuery
.id = query
.id
645 self
.assertEquals(query
, receivedQuery
)
646 self
.assertEquals(response
, receivedResponse
)
648 for method
in ("sendUDPQuery", "sendTCPQuery"):
649 sender
= getattr(self
, method
)
650 (_
, receivedResponse
) = sender(doquery
, response
)
651 self
.assertEquals(receivedResponse
, None)
653 class TestAdvancedQClass(DNSDistTest
):
655 _config_template
= """
656 newServer{address="127.0.0.1:%s"}
657 addAction(QClassRule(DNSClass.CHAOS), DropAction())
659 def testAdvancedQClassChaosDrop(self
):
661 Advanced: Drop QClass CHAOS
664 name
= 'qclasschaos.advanced.tests.powerdns.com.'
665 query
= dns
.message
.make_query(name
, 'TXT', 'CHAOS')
667 for method
in ("sendUDPQuery", "sendTCPQuery"):
668 sender
= getattr(self
, method
)
669 (_
, receivedResponse
) = sender(query
, response
=None)
670 self
.assertEquals(receivedResponse
, None)
672 def testAdvancedQClassINAllow(self
):
674 Advanced: Allow QClass IN
677 name
= 'qclassin.advanced.tests.powerdns.com.'
678 query
= dns
.message
.make_query(name
, 'A', 'IN')
679 response
= dns
.message
.make_response(query
)
680 rrset
= dns
.rrset
.from_text(name
,
685 response
.answer
.append(rrset
)
687 for method
in ("sendUDPQuery", "sendTCPQuery"):
688 sender
= getattr(self
, method
)
689 (receivedQuery
, receivedResponse
) = sender(query
, response
)
690 self
.assertTrue(receivedQuery
)
691 self
.assertTrue(receivedResponse
)
692 receivedQuery
.id = query
.id
693 self
.assertEquals(query
, receivedQuery
)
694 self
.assertEquals(response
, receivedResponse
)
696 class TestAdvancedOpcode(DNSDistTest
):
698 _config_template
= """
699 newServer{address="127.0.0.1:%s"}
700 addAction(OpcodeRule(DNSOpcode.Notify), DropAction())
702 def testAdvancedOpcodeNotifyDrop(self
):
704 Advanced: Drop Opcode NOTIFY
707 name
= 'opcodenotify.advanced.tests.powerdns.com.'
708 query
= dns
.message
.make_query(name
, 'A', 'IN')
709 query
.set_opcode(dns
.opcode
.NOTIFY
)
711 for method
in ("sendUDPQuery", "sendTCPQuery"):
712 sender
= getattr(self
, method
)
713 (_
, receivedResponse
) = sender(query
, response
=None)
714 self
.assertEquals(receivedResponse
, None)
716 def testAdvancedOpcodeUpdateINAllow(self
):
718 Advanced: Allow Opcode UPDATE
721 name
= 'opcodeupdate.advanced.tests.powerdns.com.'
722 query
= dns
.message
.make_query(name
, 'A', 'IN')
723 query
.set_opcode(dns
.opcode
.UPDATE
)
724 response
= dns
.message
.make_response(query
)
725 rrset
= dns
.rrset
.from_text(name
,
730 response
.answer
.append(rrset
)
732 for method
in ("sendUDPQuery", "sendTCPQuery"):
733 sender
= getattr(self
, method
)
734 (receivedQuery
, receivedResponse
) = sender(query
, response
)
735 self
.assertTrue(receivedQuery
)
736 self
.assertTrue(receivedResponse
)
737 receivedQuery
.id = query
.id
738 self
.assertEquals(query
, receivedQuery
)
739 self
.assertEquals(response
, receivedResponse
)
741 class TestAdvancedNonTerminalRule(DNSDistTest
):
743 _config_template
= """
744 newServer{address="127.0.0.1:%s", pool="real"}
745 addAction(AllRule(), DisableValidationAction())
746 addAction(AllRule(), PoolAction("real"))
747 addAction(AllRule(), DropAction())
749 def testAdvancedNonTerminalRules(self
):
751 Advanced: Non terminal rules
753 We check that DisableValidationAction() is applied
754 but does not stop the processing, then that
755 PoolAction() is applied _and_ stop the processing.
757 name
= 'nonterminal.advanced.tests.powerdns.com.'
758 query
= dns
.message
.make_query(name
, 'A', 'IN')
759 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
760 expectedQuery
.flags |
= dns
.flags
.CD
761 response
= dns
.message
.make_response(query
)
762 rrset
= dns
.rrset
.from_text(name
,
767 response
.answer
.append(rrset
)
769 for method
in ("sendUDPQuery", "sendTCPQuery"):
770 sender
= getattr(self
, method
)
771 (receivedQuery
, receivedResponse
) = sender(query
, response
)
772 self
.assertTrue(receivedQuery
)
773 self
.assertTrue(receivedResponse
)
774 receivedQuery
.id = expectedQuery
.id
775 self
.assertEquals(expectedQuery
, receivedQuery
)
776 self
.assertEquals(response
, receivedResponse
)
778 class TestAdvancedStringOnlyServer(DNSDistTest
):
780 _config_template
= """
781 newServer("127.0.0.1:%s")
784 def testAdvancedStringOnlyServer(self
):
786 Advanced: "string-only" server is placed in the default pool
788 name
= 'string-only-server.advanced.tests.powerdns.com.'
789 query
= dns
.message
.make_query(name
, 'A', 'IN')
790 response
= dns
.message
.make_response(query
)
791 rrset
= dns
.rrset
.from_text(name
,
796 response
.answer
.append(rrset
)
798 for method
in ("sendUDPQuery", "sendTCPQuery"):
799 sender
= getattr(self
, method
)
800 (receivedQuery
, receivedResponse
) = sender(query
, response
)
801 self
.assertTrue(receivedQuery
)
802 self
.assertTrue(receivedResponse
)
803 receivedQuery
.id = query
.id
804 self
.assertEquals(query
, receivedQuery
)
805 self
.assertEquals(response
, receivedResponse
)
807 class TestAdvancedRestoreFlagsOnSelfResponse(DNSDistTest
):
809 _config_template
= """
810 addAction(AllRule(), DisableValidationAction())
811 addAction(AllRule(), SpoofAction("192.0.2.1"))
812 newServer{address="127.0.0.1:%s"}
815 def testAdvancedRestoreFlagsOnSpoofResponse(self
):
817 Advanced: Restore flags on spoofed response
819 Send a query with CD flag cleared, dnsdist is
820 instructed to set it, then to spoof the response,
821 check that response has the flag cleared.
823 name
= 'spoofed.restoreflags.advanced.tests.powerdns.com.'
824 query
= dns
.message
.make_query(name
, 'A', 'IN')
825 # dnsdist set RA = RD for spoofed responses
826 query
.flags
&= ~dns
.flags
.RD
828 response
= dns
.message
.make_response(query
)
829 rrset
= dns
.rrset
.from_text(name
,
834 response
.answer
.append(rrset
)
836 for method
in ("sendUDPQuery", "sendTCPQuery"):
837 sender
= getattr(self
, method
)
838 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
839 self
.assertTrue(receivedResponse
)
840 self
.assertEquals(response
, receivedResponse
)
842 class TestAdvancedQPS(DNSDistTest
):
844 _config_template
= """
845 addAction("qps.advanced.tests.powerdns.com", QPSAction(10))
846 newServer{address="127.0.0.1:%s"}
849 def testAdvancedQPSLimit(self
):
853 Send queries to "qps.advanced.tests.powerdns.com."
854 check that dnsdist drops queries when the max QPS has been reached.
857 name
= 'qps.advanced.tests.powerdns.com.'
858 query
= dns
.message
.make_query(name
, 'A', 'IN')
859 response
= dns
.message
.make_response(query
)
860 rrset
= dns
.rrset
.from_text(name
,
865 response
.answer
.append(rrset
)
867 for _
in range(maxQPS
):
868 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
869 receivedQuery
.id = query
.id
870 self
.assertEquals(query
, receivedQuery
)
871 self
.assertEquals(response
, receivedResponse
)
873 # we should now be dropped
874 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
875 self
.assertEquals(receivedResponse
, None)
879 # again, over TCP this time
880 for _
in range(maxQPS
):
881 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
882 receivedQuery
.id = query
.id
883 self
.assertEquals(query
, receivedQuery
)
884 self
.assertEquals(response
, receivedResponse
)
887 (_
, receivedResponse
) = self
.sendTCPQuery(query
, response
=None, useQueue
=False)
888 self
.assertEquals(receivedResponse
, None)
890 class TestAdvancedQPSNone(DNSDistTest
):
892 _config_template
= """
893 addAction("qpsnone.advanced.tests.powerdns.com", QPSAction(100))
894 addAction(AllRule(), RCodeAction(DNSRCode.REFUSED))
895 newServer{address="127.0.0.1:%s"}
898 def testAdvancedQPSNone(self
):
900 Advanced: Not matching QPS returns None, not Allow
902 Send queries to "qps.advanced.tests.powerdns.com."
903 check that the rule returns None when the QPS has not been
906 name
= 'qpsnone.advanced.tests.powerdns.com.'
907 query
= dns
.message
.make_query(name
, 'A', 'IN')
908 query
.flags
&= ~dns
.flags
.RD
909 expectedResponse
= dns
.message
.make_response(query
)
910 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
912 for method
in ("sendUDPQuery", "sendTCPQuery"):
913 sender
= getattr(self
, method
)
914 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
915 self
.assertEquals(receivedResponse
, expectedResponse
)
917 class TestAdvancedNMGRule(DNSDistTest
):
919 _config_template
= """
921 allowed:addMask("192.0.2.1/32")
922 addAction(NotRule(NetmaskGroupRule(allowed)), RCodeAction(DNSRCode.REFUSED))
923 newServer{address="127.0.0.1:%s"}
926 def testAdvancedNMGRule(self
):
928 Advanced: NMGRule should refuse our queries
930 Send queries to "nmgrule.advanced.tests.powerdns.com.",
931 check that we are getting a REFUSED response.
933 name
= 'nmgrule.advanced.tests.powerdns.com.'
934 query
= dns
.message
.make_query(name
, 'A', 'IN')
935 query
.flags
&= ~dns
.flags
.RD
936 expectedResponse
= dns
.message
.make_response(query
)
937 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
939 for method
in ("sendUDPQuery", "sendTCPQuery"):
940 sender
= getattr(self
, method
)
941 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
942 self
.assertEquals(receivedResponse
, expectedResponse
)
944 class TestDSTPortRule(DNSDistTest
):
946 _config_params
= ['_dnsDistPort', '_testServerPort']
947 _config_template
= """
948 addAction(DSTPortRule(%d), RCodeAction(DNSRCode.REFUSED))
949 newServer{address="127.0.0.1:%s"}
952 def testDSTPortRule(self
):
954 Advanced: DSTPortRule should capture our queries
956 Send queries to "dstportrule.advanced.tests.powerdns.com.",
957 check that we are getting a REFUSED response.
960 name
= 'dstportrule.advanced.tests.powerdns.com.'
961 query
= dns
.message
.make_query(name
, 'A', 'IN')
962 query
.flags
&= ~dns
.flags
.RD
963 expectedResponse
= dns
.message
.make_response(query
)
964 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
966 for method
in ("sendUDPQuery", "sendTCPQuery"):
967 sender
= getattr(self
, method
)
968 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
969 self
.assertEquals(receivedResponse
, expectedResponse
)
971 class TestAdvancedLabelsCountRule(DNSDistTest
):
973 _config_template
= """
974 addAction(QNameLabelsCountRule(5,6), RCodeAction(DNSRCode.REFUSED))
975 newServer{address="127.0.0.1:%s"}
978 def testAdvancedLabelsCountRule(self
):
980 Advanced: QNameLabelsCountRule(5,6)
982 # 6 labels, we should be fine
983 name
= 'ok.labelscount.advanced.tests.powerdns.com.'
984 query
= dns
.message
.make_query(name
, 'A', 'IN')
985 response
= dns
.message
.make_response(query
)
986 rrset
= dns
.rrset
.from_text(name
,
991 response
.answer
.append(rrset
)
993 for method
in ("sendUDPQuery", "sendTCPQuery"):
994 sender
= getattr(self
, method
)
995 (receivedQuery
, receivedResponse
) = sender(query
, response
)
996 self
.assertTrue(receivedQuery
)
997 self
.assertTrue(receivedResponse
)
998 receivedQuery
.id = query
.id
999 self
.assertEquals(query
, receivedQuery
)
1000 self
.assertEquals(response
, receivedResponse
)
1002 # more than 6 labels, the query should be refused
1003 name
= 'not.ok.labelscount.advanced.tests.powerdns.com.'
1004 query
= dns
.message
.make_query(name
, 'A', 'IN')
1005 query
.flags
&= ~dns
.flags
.RD
1006 expectedResponse
= dns
.message
.make_response(query
)
1007 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1009 for method
in ("sendUDPQuery", "sendTCPQuery"):
1010 sender
= getattr(self
, method
)
1011 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1012 self
.assertEquals(receivedResponse
, expectedResponse
)
1014 # less than 5 labels, the query should be refused
1015 name
= 'labelscountadvanced.tests.powerdns.com.'
1016 query
= dns
.message
.make_query(name
, 'A', 'IN')
1017 query
.flags
&= ~dns
.flags
.RD
1018 expectedResponse
= dns
.message
.make_response(query
)
1019 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1021 for method
in ("sendUDPQuery", "sendTCPQuery"):
1022 sender
= getattr(self
, method
)
1023 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1024 self
.assertEquals(receivedResponse
, expectedResponse
)
1026 class TestAdvancedWireLengthRule(DNSDistTest
):
1028 _config_template
= """
1029 addAction(QNameWireLengthRule(54,56), RCodeAction(DNSRCode.REFUSED))
1030 newServer{address="127.0.0.1:%s"}
1033 def testAdvancedWireLengthRule(self
):
1035 Advanced: QNameWireLengthRule(54,56)
1037 name
= 'longenough.qnamewirelength.advanced.tests.powerdns.com.'
1038 query
= dns
.message
.make_query(name
, 'A', 'IN')
1039 response
= dns
.message
.make_response(query
)
1040 rrset
= dns
.rrset
.from_text(name
,
1045 response
.answer
.append(rrset
)
1047 for method
in ("sendUDPQuery", "sendTCPQuery"):
1048 sender
= getattr(self
, method
)
1049 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1050 self
.assertTrue(receivedQuery
)
1051 self
.assertTrue(receivedResponse
)
1052 receivedQuery
.id = query
.id
1053 self
.assertEquals(query
, receivedQuery
)
1054 self
.assertEquals(response
, receivedResponse
)
1056 # too short, the query should be refused
1057 name
= 'short.qnamewirelength.advanced.tests.powerdns.com.'
1058 query
= dns
.message
.make_query(name
, 'A', 'IN')
1059 query
.flags
&= ~dns
.flags
.RD
1060 expectedResponse
= dns
.message
.make_response(query
)
1061 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1063 for method
in ("sendUDPQuery", "sendTCPQuery"):
1064 sender
= getattr(self
, method
)
1065 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1066 self
.assertEquals(receivedResponse
, expectedResponse
)
1068 # too long, the query should be refused
1069 name
= 'toolongtobevalid.qnamewirelength.advanced.tests.powerdns.com.'
1070 query
= dns
.message
.make_query(name
, 'A', 'IN')
1071 query
.flags
&= ~dns
.flags
.RD
1072 expectedResponse
= dns
.message
.make_response(query
)
1073 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1075 for method
in ("sendUDPQuery", "sendTCPQuery"):
1076 sender
= getattr(self
, method
)
1077 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1078 self
.assertEquals(receivedResponse
, expectedResponse
)
1080 class TestAdvancedIncludeDir(DNSDistTest
):
1082 _config_template
= """
1083 -- this directory contains a file allowing includedir.advanced.tests.powerdns.com.
1084 includeDirectory('test-include-dir')
1085 newServer{address="127.0.0.1:%s"}
1088 def testAdvancedIncludeDirAllowed(self
):
1090 Advanced: includeDirectory()
1092 name
= 'includedir.advanced.tests.powerdns.com.'
1093 query
= dns
.message
.make_query(name
, 'A', 'IN')
1094 response
= dns
.message
.make_response(query
)
1095 rrset
= dns
.rrset
.from_text(name
,
1100 response
.answer
.append(rrset
)
1102 for method
in ("sendUDPQuery", "sendTCPQuery"):
1103 sender
= getattr(self
, method
)
1104 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1105 self
.assertTrue(receivedQuery
)
1106 self
.assertTrue(receivedResponse
)
1107 receivedQuery
.id = query
.id
1108 self
.assertEquals(query
, receivedQuery
)
1109 self
.assertEquals(response
, receivedResponse
)
1111 # this one should be refused
1112 name
= 'notincludedir.advanced.tests.powerdns.com.'
1113 query
= dns
.message
.make_query(name
, 'A', 'IN')
1114 query
.flags
&= ~dns
.flags
.RD
1115 expectedResponse
= dns
.message
.make_response(query
)
1116 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1118 for method
in ("sendUDPQuery", "sendTCPQuery"):
1119 sender
= getattr(self
, method
)
1120 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1121 self
.assertEquals(receivedResponse
, expectedResponse
)
1123 class TestAdvancedLuaDO(DNSDistTest
):
1125 _config_template
= """
1126 function nxDOLua(dq)
1128 return DNSAction.Nxdomain, ""
1130 return DNSAction.None, ""
1132 addAction(AllRule(), LuaAction(nxDOLua))
1133 newServer{address="127.0.0.1:%s"}
1136 def testNxDOViaLua(self
):
1138 Advanced: Nx DO queries via Lua
1140 name
= 'nxdo.advanced.tests.powerdns.com.'
1141 query
= dns
.message
.make_query(name
, 'A', 'IN')
1142 response
= dns
.message
.make_response(query
)
1143 rrset
= dns
.rrset
.from_text(name
,
1148 response
.answer
.append(rrset
)
1149 queryWithDO
= dns
.message
.make_query(name
, 'A', 'IN', want_dnssec
=True)
1150 doResponse
= dns
.message
.make_response(queryWithDO
)
1151 doResponse
.set_rcode(dns
.rcode
.NXDOMAIN
)
1154 for method
in ("sendUDPQuery", "sendTCPQuery"):
1155 sender
= getattr(self
, method
)
1156 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1157 self
.assertTrue(receivedQuery
)
1158 self
.assertTrue(receivedResponse
)
1159 receivedQuery
.id = query
.id
1160 self
.assertEquals(query
, receivedQuery
)
1161 self
.assertEquals(receivedResponse
, response
)
1164 for method
in ("sendUDPQuery", "sendTCPQuery"):
1165 sender
= getattr(self
, method
)
1166 (_
, receivedResponse
) = sender(queryWithDO
, response
=None, useQueue
=False)
1167 self
.assertTrue(receivedResponse
)
1168 doResponse
.id = receivedResponse
.id
1169 self
.assertEquals(receivedResponse
, doResponse
)
1171 class TestAdvancedLuaRefused(DNSDistTest
):
1173 _config_template
= """
1175 return DNSAction.Refused, ""
1177 addAction(AllRule(), LuaAction(refuse))
1178 newServer{address="127.0.0.1:%s"}
1181 def testRefusedViaLua(self
):
1183 Advanced: Refused via Lua
1185 name
= 'refused.advanced.tests.powerdns.com.'
1186 query
= dns
.message
.make_query(name
, 'A', 'IN')
1187 response
= dns
.message
.make_response(query
)
1188 rrset
= dns
.rrset
.from_text(name
,
1193 response
.answer
.append(rrset
)
1194 refusedResponse
= dns
.message
.make_response(query
)
1195 refusedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1197 for method
in ("sendUDPQuery", "sendTCPQuery"):
1198 sender
= getattr(self
, method
)
1199 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1200 self
.assertTrue(receivedResponse
)
1201 refusedResponse
.id = receivedResponse
.id
1202 self
.assertEquals(receivedResponse
, refusedResponse
)
1204 class TestAdvancedLuaActionReturnSyntax(DNSDistTest
):
1206 _config_template
= """
1208 return DNSAction.Refused
1210 addAction(AllRule(), LuaAction(refuse))
1211 newServer{address="127.0.0.1:%s"}
1214 def testRefusedWithEmptyRule(self
):
1216 Advanced: Short syntax for LuaAction return values
1218 name
= 'short.refused.advanced.tests.powerdns.com.'
1219 query
= dns
.message
.make_query(name
, 'A', 'IN')
1220 response
= dns
.message
.make_response(query
)
1221 rrset
= dns
.rrset
.from_text(name
,
1226 response
.answer
.append(rrset
)
1227 refusedResponse
= dns
.message
.make_response(query
)
1228 refusedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1230 for method
in ("sendUDPQuery", "sendTCPQuery"):
1231 sender
= getattr(self
, method
)
1232 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1233 self
.assertTrue(receivedResponse
)
1234 refusedResponse
.id = receivedResponse
.id
1235 self
.assertEquals(receivedResponse
, refusedResponse
)
1237 class TestAdvancedLuaTruncated(DNSDistTest
):
1239 _config_template
= """
1242 return DNSAction.Truncate, ""
1244 return DNSAction.None, ""
1246 addAction(AllRule(), LuaAction(trunc))
1247 newServer{address="127.0.0.1:%s"}
1250 def testTCViaLua(self
):
1252 Advanced: TC via Lua
1254 name
= 'tc.advanced.tests.powerdns.com.'
1255 query
= dns
.message
.make_query(name
, 'A', 'IN')
1256 # dnsdist sets RA = RD for TC responses
1257 query
.flags
&= ~dns
.flags
.RD
1258 response
= dns
.message
.make_response(query
)
1259 rrset
= dns
.rrset
.from_text(name
,
1264 response
.answer
.append(rrset
)
1266 truncatedResponse
= dns
.message
.make_response(query
)
1267 truncatedResponse
.flags |
= dns
.flags
.TC
1269 (_
, receivedResponse
) = self
.sendUDPQuery(query
, response
=None, useQueue
=False)
1270 self
.assertTrue(receivedResponse
)
1271 truncatedResponse
.id = receivedResponse
.id
1272 self
.assertEquals(receivedResponse
, truncatedResponse
)
1274 # no truncation over TCP
1275 (receivedQuery
, receivedResponse
) = self
.sendTCPQuery(query
, response
)
1276 self
.assertTrue(receivedQuery
)
1277 self
.assertTrue(receivedResponse
)
1278 receivedQuery
.id = query
.id
1279 self
.assertEquals(query
, receivedQuery
)
1280 self
.assertEquals(receivedResponse
, response
)
1282 class TestStatNodeRespRingSince(DNSDistTest
):
1284 _consoleKey
= DNSDistTest
.generateConsoleKey()
1285 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
1286 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
1287 _config_template
= """
1289 controlSocket("127.0.0.1:%s")
1290 s1 = newServer{address="127.0.0.1:%s"}
1292 function visitor(node, self, childstat)
1293 table.insert(nodesSeen, node.fullname)
1297 def testStatNodeRespRingSince(self
):
1299 Advanced: StatNodeRespRing with optional since parameter
1302 name
= 'statnodesince.advanced.tests.powerdns.com.'
1303 query
= dns
.message
.make_query(name
, 'A', 'IN')
1304 response
= dns
.message
.make_response(query
)
1305 rrset
= dns
.rrset
.from_text(name
,
1310 response
.answer
.append(rrset
)
1312 (receivedQuery
, receivedResponse
) = self
.sendUDPQuery(query
, response
)
1313 self
.assertTrue(receivedQuery
)
1314 self
.assertTrue(receivedResponse
)
1315 receivedQuery
.id = query
.id
1316 self
.assertEquals(query
, receivedQuery
)
1317 self
.assertEquals(response
, receivedResponse
)
1319 self
.sendConsoleCommand("nodesSeen = {}")
1320 self
.sendConsoleCommand("statNodeRespRing(visitor)")
1321 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1322 nodes
= nodes
.strip("\n")
1323 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1324 advanced.tests.powerdns.com.
1329 self
.sendConsoleCommand("nodesSeen = {}")
1330 self
.sendConsoleCommand("statNodeRespRing(visitor, 0)")
1331 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1332 nodes
= nodes
.strip("\n")
1333 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1334 advanced.tests.powerdns.com.
1341 self
.sendConsoleCommand("nodesSeen = {}")
1342 self
.sendConsoleCommand("statNodeRespRing(visitor)")
1343 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1344 nodes
= nodes
.strip("\n")
1345 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1346 advanced.tests.powerdns.com.
1351 self
.sendConsoleCommand("nodesSeen = {}")
1352 self
.sendConsoleCommand("statNodeRespRing(visitor, 5)")
1353 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1354 nodes
= nodes
.strip("\n")
1355 self
.assertEquals(nodes
, """""")
1357 self
.sendConsoleCommand("nodesSeen = {}")
1358 self
.sendConsoleCommand("statNodeRespRing(visitor, 10)")
1359 nodes
= self
.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
1360 nodes
= nodes
.strip("\n")
1361 self
.assertEquals(nodes
, """statnodesince.advanced.tests.powerdns.com.
1362 advanced.tests.powerdns.com.
1367 class TestAdvancedRD(DNSDistTest
):
1369 _config_template
= """
1370 addAction(RDRule(), RCodeAction(DNSRCode.REFUSED))
1371 newServer{address="127.0.0.1:%s"}
1374 def testAdvancedRDRefused(self
):
1376 Advanced: RD query is refused
1378 name
= 'rd.advanced.tests.powerdns.com.'
1379 query
= dns
.message
.make_query(name
, 'A', 'IN')
1380 expectedResponse
= dns
.message
.make_response(query
)
1381 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
1382 expectedResponse
.flags |
= dns
.flags
.RA
1384 for method
in ("sendUDPQuery", "sendTCPQuery"):
1385 sender
= getattr(self
, method
)
1386 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1387 self
.assertEquals(receivedResponse
, expectedResponse
)
1389 def testAdvancedNoRDAllowed(self
):
1391 Advanced: No-RD query is allowed
1393 name
= 'no-rd.advanced.tests.powerdns.com.'
1394 query
= dns
.message
.make_query(name
, 'A', 'IN')
1395 query
.flags
&= ~dns
.flags
.RD
1396 response
= dns
.message
.make_response(query
)
1398 for method
in ("sendUDPQuery", "sendTCPQuery"):
1399 sender
= getattr(self
, method
)
1400 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1401 receivedQuery
.id = query
.id
1402 self
.assertEquals(receivedQuery
, query
)
1403 self
.assertEquals(receivedResponse
, response
)
1405 class TestAdvancedGetLocalPort(DNSDistTest
):
1407 _config_template
= """
1408 function answerBasedOnLocalPort(dq)
1409 local port = dq.localaddr:getPort()
1410 return DNSAction.Spoof, "port-was-"..port..".local-port.advanced.tests.powerdns.com."
1412 addAction("local-port.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
1413 newServer{address="127.0.0.1:%s"}
1416 def testAdvancedGetLocalPort(self
):
1418 Advanced: Return CNAME containing the local port
1420 name
= 'local-port.advanced.tests.powerdns.com.'
1421 query
= dns
.message
.make_query(name
, 'A', 'IN')
1422 # dnsdist set RA = RD for spoofed responses
1423 query
.flags
&= ~dns
.flags
.RD
1425 response
= dns
.message
.make_response(query
)
1426 rrset
= dns
.rrset
.from_text(name
,
1429 dns
.rdatatype
.CNAME
,
1430 'port-was-{}.local-port.advanced.tests.powerdns.com.'.format(self
._dnsDistPort
))
1431 response
.answer
.append(rrset
)
1433 for method
in ("sendUDPQuery", "sendTCPQuery"):
1434 sender
= getattr(self
, method
)
1435 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1436 self
.assertEquals(receivedResponse
, response
)
1438 class TestAdvancedGetLocalPortOnAnyBind(DNSDistTest
):
1440 _config_template
= """
1441 function answerBasedOnLocalPort(dq)
1442 local port = dq.localaddr:getPort()
1443 return DNSAction.Spoof, "port-was-"..port..".local-port-any.advanced.tests.powerdns.com."
1445 addAction("local-port-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
1446 newServer{address="127.0.0.1:%s"}
1448 _dnsDistListeningAddr
= "0.0.0.0"
1450 def testAdvancedGetLocalPortOnAnyBind(self
):
1452 Advanced: Return CNAME containing the local port for an ANY bind
1454 name
= 'local-port-any.advanced.tests.powerdns.com.'
1455 query
= dns
.message
.make_query(name
, 'A', 'IN')
1456 # dnsdist set RA = RD for spoofed responses
1457 query
.flags
&= ~dns
.flags
.RD
1459 response
= dns
.message
.make_response(query
)
1460 rrset
= dns
.rrset
.from_text(name
,
1463 dns
.rdatatype
.CNAME
,
1464 'port-was-{}.local-port-any.advanced.tests.powerdns.com.'.format(self
._dnsDistPort
))
1465 response
.answer
.append(rrset
)
1467 for method
in ("sendUDPQuery", "sendTCPQuery"):
1468 sender
= getattr(self
, method
)
1469 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1470 self
.assertEquals(receivedResponse
, response
)
1472 class TestAdvancedGetLocalAddressOnAnyBind(DNSDistTest
):
1474 _config_template
= """
1475 function answerBasedOnLocalAddress(dq)
1476 local dest = dq.localaddr:toString()
1477 local i, j = string.find(dest, "[0-9.]+")
1478 local addr = string.sub(dest, i, j)
1479 local dashAddr = string.gsub(addr, "[.]", "-")
1480 return DNSAction.Spoof, "address-was-"..dashAddr..".local-address-any.advanced.tests.powerdns.com."
1482 addAction("local-address-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalAddress))
1483 newServer{address="127.0.0.1:%s"}
1485 _dnsDistListeningAddr
= "0.0.0.0"
1487 def testAdvancedGetLocalAddressOnAnyBind(self
):
1489 Advanced: Return CNAME containing the local address for an ANY bind
1491 name
= 'local-address-any.advanced.tests.powerdns.com.'
1492 query
= dns
.message
.make_query(name
, 'A', 'IN')
1493 # dnsdist set RA = RD for spoofed responses
1494 query
.flags
&= ~dns
.flags
.RD
1496 response
= dns
.message
.make_response(query
)
1497 rrset
= dns
.rrset
.from_text(name
,
1500 dns
.rdatatype
.CNAME
,
1501 'address-was-127-0-0-1.local-address-any.advanced.tests.powerdns.com.')
1502 response
.answer
.append(rrset
)
1504 for method
in ("sendUDPQuery", "sendTCPQuery"):
1505 sender
= getattr(self
, method
)
1506 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1507 self
.assertEquals(receivedResponse
, response
)
1509 class TestAdvancedLuaTempFailureTTL(DNSDistTest
):
1511 _config_template
= """
1512 function testAction(dq)
1513 if dq.tempFailureTTL ~= nil then
1514 return DNSAction.Spoof, "initially.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1516 dq.tempFailureTTL = 30
1517 if dq.tempFailureTTL ~= 30 then
1518 return DNSAction.Spoof, "after.set.not.expected.value.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1520 dq.tempFailureTTL = nil
1521 if dq.tempFailureTTL ~= nil then
1522 return DNSAction.Spoof, "after.unset.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1524 return DNSAction.None, ""
1526 addAction(AllRule(), LuaAction(testAction))
1527 newServer{address="127.0.0.1:%s"}
1530 def testTempFailureTTLBinding(self
):
1532 Advanced: Exercise dq.tempFailureTTL Lua binding
1534 name
= 'tempfailurettlbinding.advanced.tests.powerdns.com.'
1535 query
= dns
.message
.make_query(name
, 'A', 'IN')
1536 response
= dns
.message
.make_response(query
)
1537 rrset
= dns
.rrset
.from_text(name
,
1542 response
.answer
.append(rrset
)
1544 for method
in ("sendUDPQuery", "sendTCPQuery"):
1545 sender
= getattr(self
, method
)
1546 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1547 self
.assertTrue(receivedQuery
)
1548 self
.assertTrue(receivedResponse
)
1549 receivedQuery
.id = query
.id
1550 self
.assertEquals(query
, receivedQuery
)
1551 self
.assertEquals(receivedResponse
, response
)
1553 class TestAdvancedEDNSOptionRule(DNSDistTest
):
1555 _config_template
= """
1556 newServer{address="127.0.0.1:%s"}
1557 addAction(EDNSOptionRule(EDNSOptionCode.ECS), DropAction())
1560 def testDropped(self
):
1562 Advanced: A question with ECS is dropped
1565 name
= 'ednsoptionrule.advanced.tests.powerdns.com.'
1567 ecso
= clientsubnetoption
.ClientSubnetOption('127.0.0.1', 24)
1568 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, options
=[ecso
], payload
=512)
1570 for method
in ("sendUDPQuery", "sendTCPQuery"):
1571 sender
= getattr(self
, method
)
1572 (_
, receivedResponse
) = sender(query
, response
=None)
1573 self
.assertEquals(receivedResponse
, None)
1575 def testReplied(self
):
1577 Advanced: A question without ECS is answered
1580 name
= 'ednsoptionrule.advanced.tests.powerdns.com.'
1583 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True, options
=[], payload
=512)
1584 response
= dns
.message
.make_response(query
)
1586 for method
in ("sendUDPQuery", "sendTCPQuery"):
1587 sender
= getattr(self
, method
)
1588 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1589 self
.assertTrue(receivedQuery
)
1590 self
.assertTrue(receivedResponse
)
1592 receivedQuery
.id = query
.id
1593 self
.assertEquals(query
, receivedQuery
)
1594 self
.assertEquals(receivedResponse
, response
)
1596 # and with no EDNS at all
1597 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=False)
1598 response
= dns
.message
.make_response(query
)
1600 for method
in ("sendUDPQuery", "sendTCPQuery"):
1601 sender
= getattr(self
, method
)
1602 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1603 self
.assertTrue(receivedQuery
)
1604 self
.assertTrue(receivedResponse
)
1606 receivedQuery
.id = query
.id
1607 self
.assertEquals(query
, receivedQuery
)
1608 self
.assertEquals(receivedResponse
, response
)
1610 class TestAdvancedAllowHeaderOnly(DNSDistTest
):
1612 _config_template
= """
1613 newServer{address="127.0.0.1:%s"}
1614 setAllowEmptyResponse(true)
1617 def testHeaderOnlyRefused(self
):
1619 Advanced: Header-only refused response
1621 name
= 'header-only-refused-response.advanced.tests.powerdns.com.'
1622 query
= dns
.message
.make_query(name
, 'A', 'IN')
1623 response
= dns
.message
.make_response(query
)
1624 response
.set_rcode(dns
.rcode
.REFUSED
)
1625 response
.question
= []
1627 for method
in ("sendUDPQuery", "sendTCPQuery"):
1628 sender
= getattr(self
, method
)
1629 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1630 self
.assertTrue(receivedQuery
)
1631 receivedQuery
.id = query
.id
1632 self
.assertEquals(query
, receivedQuery
)
1633 self
.assertEquals(receivedResponse
, response
)
1635 def testHeaderOnlyNoErrorResponse(self
):
1637 Advanced: Header-only NoError response should be allowed
1639 name
= 'header-only-noerror-response.advanced.tests.powerdns.com.'
1640 query
= dns
.message
.make_query(name
, 'A', 'IN')
1641 response
= dns
.message
.make_response(query
)
1642 response
.question
= []
1644 for method
in ("sendUDPQuery", "sendTCPQuery"):
1645 sender
= getattr(self
, method
)
1646 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1647 self
.assertTrue(receivedQuery
)
1648 receivedQuery
.id = query
.id
1649 self
.assertEquals(query
, receivedQuery
)
1650 self
.assertEquals(receivedResponse
, response
)
1652 def testHeaderOnlyNXDResponse(self
):
1654 Advanced: Header-only NXD response should be allowed
1656 name
= 'header-only-nxd-response.advanced.tests.powerdns.com.'
1657 query
= dns
.message
.make_query(name
, 'A', 'IN')
1658 response
= dns
.message
.make_response(query
)
1659 response
.set_rcode(dns
.rcode
.NXDOMAIN
)
1660 response
.question
= []
1662 for method
in ("sendUDPQuery", "sendTCPQuery"):
1663 sender
= getattr(self
, method
)
1664 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1665 self
.assertTrue(receivedQuery
)
1666 receivedQuery
.id = query
.id
1667 self
.assertEquals(query
, receivedQuery
)
1668 self
.assertEquals(receivedResponse
, response
)
1670 class TestAdvancedEDNSVersionRule(DNSDistTest
):
1672 _config_template
= """
1673 newServer{address="127.0.0.1:%s"}
1674 addAction(EDNSVersionRule(0), ERCodeAction(DNSRCode.BADVERS))
1677 def testBadVers(self
):
1679 Advanced: A question with ECS version larger than 0 yields BADVERS
1682 name
= 'ednsversionrule.advanced.tests.powerdns.com.'
1684 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=1)
1685 query
.flags
&= ~dns
.flags
.RD
1686 expectedResponse
= dns
.message
.make_response(query
)
1687 expectedResponse
.set_rcode(dns
.rcode
.BADVERS
)
1689 for method
in ("sendUDPQuery", "sendTCPQuery"):
1690 sender
= getattr(self
, method
)
1691 (_
, receivedResponse
) = sender(query
, response
=None)
1692 self
.assertEquals(receivedResponse
, expectedResponse
)
1694 def testNoEDNS0Pass(self
):
1696 Advanced: A question with ECS version 0 goes through
1699 name
= 'ednsversionrule.advanced.tests.powerdns.com.'
1701 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=True)
1702 response
= dns
.message
.make_response(query
)
1704 for method
in ("sendUDPQuery", "sendTCPQuery"):
1705 sender
= getattr(self
, method
)
1706 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1707 receivedQuery
.id = query
.id
1708 self
.assertEquals(query
, receivedQuery
)
1709 self
.assertEquals(receivedResponse
, response
)
1711 def testReplied(self
):
1713 Advanced: A question without ECS goes through
1716 name
= 'ednsoptionrule.advanced.tests.powerdns.com.'
1718 query
= dns
.message
.make_query(name
, 'A', 'IN', use_edns
=False)
1719 response
= dns
.message
.make_response(query
)
1721 for method
in ("sendUDPQuery", "sendTCPQuery"):
1722 sender
= getattr(self
, method
)
1723 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1724 receivedQuery
.id = query
.id
1725 self
.assertEquals(query
, receivedQuery
)
1726 self
.assertEquals(receivedResponse
, response
)
1728 class TestSetRules(DNSDistTest
):
1730 _consoleKey
= DNSDistTest
.generateConsoleKey()
1731 _consoleKeyB64
= base64
.b64encode(_consoleKey
).decode('ascii')
1732 _config_params
= ['_consoleKeyB64', '_consolePort', '_testServerPort']
1733 _config_template
= """
1735 controlSocket("127.0.0.1:%s")
1736 newServer{address="127.0.0.1:%s"}
1737 addAction(AllRule(), SpoofAction("192.0.2.1"))
1740 def testClearThenSetRules(self
):
1742 Advanced: Clear rules, set rules
1745 name
= 'clearthensetrules.advanced.tests.powerdns.com.'
1746 query
= dns
.message
.make_query(name
, 'A', 'IN')
1747 # dnsdist set RA = RD for spoofed responses
1748 query
.flags
&= ~dns
.flags
.RD
1749 expectedResponse
= dns
.message
.make_response(query
)
1750 rrset
= dns
.rrset
.from_text(name
,
1755 expectedResponse
.answer
.append(rrset
)
1757 for method
in ("sendUDPQuery", "sendTCPQuery"):
1758 sender
= getattr(self
, method
)
1760 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1761 self
.assertTrue(receivedResponse
)
1762 self
.assertEquals(expectedResponse
, receivedResponse
)
1764 # clear all the rules, we should not be spoofing and get a SERVFAIL from the responder instead
1765 self
.sendConsoleCommand("clearRules()")
1767 expectedResponse
= dns
.message
.make_response(query
)
1768 expectedResponse
.set_rcode(dns
.rcode
.SERVFAIL
)
1770 for method
in ("sendUDPQuery", "sendTCPQuery"):
1771 sender
= getattr(self
, method
)
1773 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1774 self
.assertTrue(receivedResponse
)
1775 self
.assertEquals(expectedResponse
, receivedResponse
)
1777 # insert a new spoofing rule
1778 self
.sendConsoleCommand("setRules({ newRuleAction(AllRule(), SpoofAction(\"192.0.2.2\")) })")
1780 expectedResponse
= dns
.message
.make_response(query
)
1781 rrset
= dns
.rrset
.from_text(name
,
1786 expectedResponse
.answer
.append(rrset
)
1788 for method
in ("sendUDPQuery", "sendTCPQuery"):
1789 sender
= getattr(self
, method
)
1791 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1792 self
.assertTrue(receivedResponse
)
1793 self
.assertEquals(expectedResponse
, receivedResponse
)
1795 class TestAdvancedContinueAction(DNSDistTest
):
1797 _config_template
= """
1798 newServer{address="127.0.0.1:%s", pool="mypool"}
1799 addAction("nocontinue.continue-action.advanced.tests.powerdns.com.", PoolAction("mypool"))
1800 addAction("continue.continue-action.advanced.tests.powerdns.com.", ContinueAction(PoolAction("mypool")))
1801 addAction(AllRule(), DisableValidationAction())
1804 def testNoContinue(self
):
1806 Advanced: Query routed to pool, PoolAction should be terminal
1809 name
= 'nocontinue.continue-action.advanced.tests.powerdns.com.'
1811 query
= dns
.message
.make_query(name
, 'A', 'IN')
1812 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
1814 response
= dns
.message
.make_response(query
)
1815 expectedResponse
= dns
.message
.make_response(query
)
1817 for method
in ("sendUDPQuery", "sendTCPQuery"):
1818 sender
= getattr(self
, method
)
1819 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1820 self
.assertEquals(receivedQuery
, expectedQuery
)
1821 self
.assertEquals(receivedResponse
, expectedResponse
)
1823 def testNoContinue(self
):
1825 Advanced: Query routed to pool, ContinueAction() should not stop the processing
1828 name
= 'continue.continue-action.advanced.tests.powerdns.com.'
1830 query
= dns
.message
.make_query(name
, 'A', 'IN')
1831 expectedQuery
= dns
.message
.make_query(name
, 'A', 'IN')
1832 expectedQuery
.flags |
= dns
.flags
.CD
1834 response
= dns
.message
.make_response(query
)
1835 expectedResponse
= dns
.message
.make_response(query
)
1837 for method
in ("sendUDPQuery", "sendTCPQuery"):
1838 sender
= getattr(self
, method
)
1839 (receivedQuery
, receivedResponse
) = sender(query
, response
)
1840 expectedQuery
.id = receivedQuery
.id
1841 self
.assertEquals(receivedQuery
, expectedQuery
)
1842 print(receivedResponse
)
1843 print(expectedResponse
)
1844 self
.assertEquals(receivedResponse
, expectedResponse
)
1846 class TestAdvancedSetNegativeAndSOA(DNSDistTest
):
1848 _config_template
= """
1849 addAction("nxd.setnegativeandsoa.advanced.tests.powerdns.com.", SetNegativeAndSOAAction(true, "auth.", 42, "mname", "rname", 5, 4, 3, 2, 1))
1850 addAction("nodata.setnegativeandsoa.advanced.tests.powerdns.com.", SetNegativeAndSOAAction(false, "another-auth.", 42, "mname", "rname", 1, 2, 3, 4, 5))
1851 newServer{address="127.0.0.1:%s"}
1854 def testAdvancedNegativeAndSOANXD(self
):
1856 Advanced: SetNegativeAndSOAAction NXD
1858 name
= 'nxd.setnegativeandsoa.advanced.tests.powerdns.com.'
1859 query
= dns
.message
.make_query(name
, 'A', 'IN')
1860 expectedResponse
= dns
.message
.make_response(query
)
1861 expectedResponse
.set_rcode(dns
.rcode
.NXDOMAIN
)
1862 soa
= dns
.rrset
.from_text("auth",
1866 'mname. rname. 5 4 3 2 1')
1867 expectedResponse
.additional
.append(soa
)
1869 for method
in ("sendUDPQuery", "sendTCPQuery"):
1870 sender
= getattr(self
, method
)
1871 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1872 self
.assertEquals(receivedResponse
, expectedResponse
)
1874 def testAdvancedNegativeAndSOANoData(self
):
1876 Advanced: SetNegativeAndSOAAction NoData
1878 name
= 'nodata.setnegativeandsoa.advanced.tests.powerdns.com.'
1879 query
= dns
.message
.make_query(name
, 'A', 'IN')
1880 expectedResponse
= dns
.message
.make_response(query
)
1881 expectedResponse
.set_rcode(dns
.rcode
.NOERROR
)
1882 soa
= dns
.rrset
.from_text("another-auth",
1886 'mname. rname. 1 2 3 4 5')
1887 expectedResponse
.additional
.append(soa
)
1889 for method
in ("sendUDPQuery", "sendTCPQuery"):
1890 sender
= getattr(self
, method
)
1891 (_
, receivedResponse
) = sender(query
, response
=None, useQueue
=False)
1892 self
.assertEquals(receivedResponse
, expectedResponse
)