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