]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_Advanced.py
Merge pull request #3731 from rgacogne/dnsdist-policies-doc
[thirdparty/pdns.git] / regression-tests.dnsdist / test_Advanced.py
CommitLineData
ec5f5c6b
RG
1#!/usr/bin/env python
2from datetime import datetime, timedelta
ec5f5c6b 3import os
856c35e3 4import time
b1bec9f0 5import dns
ec5f5c6b
RG
6from dnsdisttests import DNSDistTest
7
b1bec9f0
RG
8class TestAdvancedAllow(DNSDistTest):
9
10 _config_template = """
11 addAction(makeRule("allowed.advanced.tests.powerdns.com."), AllowAction())
12 addAction(AllRule(), DropAction())
13 newServer{address="127.0.0.1:%s"}
14 """
15
16 def testAdvancedAllow(self):
17 """
18 Advanced: Allowed qname is not dropped
19
20 A query for allowed.advanced.tests.powerdns.com. should be allowed
21 while others should be dropped.
22 """
23 name = 'allowed.advanced.tests.powerdns.com.'
24 query = dns.message.make_query(name, 'A', 'IN')
25 response = dns.message.make_response(query)
26 rrset = dns.rrset.from_text(name,
27 3600,
28 dns.rdataclass.IN,
29 dns.rdatatype.A,
30 '127.0.0.1')
31 response.answer.append(rrset)
32
33 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
34 self.assertTrue(receivedQuery)
35 self.assertTrue(receivedResponse)
36 receivedQuery.id = query.id
37 self.assertEquals(query, receivedQuery)
38 self.assertEquals(response, receivedResponse)
39
40 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
41 self.assertTrue(receivedQuery)
42 self.assertTrue(receivedResponse)
43 receivedQuery.id = query.id
44 self.assertEquals(query, receivedQuery)
45 self.assertEquals(response, receivedResponse)
46
47 def testAdvancedAllowDropped(self):
48 """
49 Advanced: Not allowed qname is dropped
50
51 A query for notallowed.advanced.tests.powerdns.com. should be dropped.
52 """
53 name = 'notallowed.advanced.tests.powerdns.com.'
54 query = dns.message.make_query(name, 'A', 'IN')
55 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
56 self.assertEquals(receivedResponse, None)
57
58 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
59 self.assertEquals(receivedResponse, None)
60
ec5f5c6b
RG
61class TestAdvancedFixupCase(DNSDistTest):
62
ec5f5c6b
RG
63 _config_template = """
64 truncateTC(true)
65 fixupCase(true)
66 newServer{address="127.0.0.1:%s"}
67 """
68
ec5f5c6b
RG
69 def testAdvancedFixupCase(self):
70 """
617dfe22
RG
71 Advanced: Fixup Case
72
ec5f5c6b
RG
73 Send a query with lower and upper chars,
74 make the backend return a lowercase version,
75 check that dnsdist fixes the response.
76 """
77 name = 'fiXuPCasE.advanced.tests.powerdns.com.'
78 query = dns.message.make_query(name, 'A', 'IN')
79 lowercasequery = dns.message.make_query(name.lower(), 'A', 'IN')
80 response = dns.message.make_response(lowercasequery)
81 expectedResponse = dns.message.make_response(query)
82 rrset = dns.rrset.from_text(name,
83 3600,
84 dns.rdataclass.IN,
85 dns.rdatatype.A,
86 '127.0.0.1')
87 response.answer.append(rrset)
88 expectedResponse.answer.append(rrset)
89
90 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
91 self.assertTrue(receivedQuery)
92 self.assertTrue(receivedResponse)
93 receivedQuery.id = query.id
ec5f5c6b
RG
94 self.assertEquals(query, receivedQuery)
95 self.assertEquals(expectedResponse, receivedResponse)
96
97 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
98 self.assertTrue(receivedQuery)
99 self.assertTrue(receivedResponse)
100 receivedQuery.id = query.id
ec5f5c6b
RG
101 self.assertEquals(query, receivedQuery)
102 self.assertEquals(expectedResponse, receivedResponse)
103
104
105class TestAdvancedRemoveRD(DNSDistTest):
106
ec5f5c6b
RG
107 _config_template = """
108 addNoRecurseRule("norecurse.advanced.tests.powerdns.com.")
109 newServer{address="127.0.0.1:%s"}
110 """
111
ec5f5c6b
RG
112 def testAdvancedNoRD(self):
113 """
617dfe22
RG
114 Advanced: No RD
115
ec5f5c6b
RG
116 Send a query with RD,
117 check that dnsdist clears the RD flag.
118 """
119 name = 'norecurse.advanced.tests.powerdns.com.'
120 query = dns.message.make_query(name, 'A', 'IN')
121 expectedQuery = dns.message.make_query(name, 'A', 'IN')
122 expectedQuery.flags &= ~dns.flags.RD
123
124 response = dns.message.make_response(query)
125 rrset = dns.rrset.from_text(name,
126 3600,
127 dns.rdataclass.IN,
128 dns.rdatatype.A,
129 '127.0.0.1')
130 response.answer.append(rrset)
131
132 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
133 self.assertTrue(receivedQuery)
134 self.assertTrue(receivedResponse)
135 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
136 self.assertEquals(expectedQuery, receivedQuery)
137 self.assertEquals(response, receivedResponse)
138
139 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
140 self.assertTrue(receivedQuery)
141 self.assertTrue(receivedResponse)
142 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
143 self.assertEquals(expectedQuery, receivedQuery)
144 self.assertEquals(response, receivedResponse)
145
146 def testAdvancedKeepRD(self):
147 """
617dfe22
RG
148 Advanced: No RD canary
149
ec5f5c6b
RG
150 Send a query with RD for a canary domain,
151 check that dnsdist does not clear the RD flag.
152 """
153 name = 'keeprecurse.advanced.tests.powerdns.com.'
154 query = dns.message.make_query(name, 'A', 'IN')
155
156 response = dns.message.make_response(query)
157 rrset = dns.rrset.from_text(name,
158 3600,
159 dns.rdataclass.IN,
160 dns.rdatatype.A,
161 '127.0.0.1')
162 response.answer.append(rrset)
163
164 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
165 self.assertTrue(receivedQuery)
166 self.assertTrue(receivedResponse)
167 receivedQuery.id = query.id
ec5f5c6b
RG
168 self.assertEquals(query, receivedQuery)
169 self.assertEquals(response, receivedResponse)
170
171 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
172 self.assertTrue(receivedQuery)
173 self.assertTrue(receivedResponse)
174 receivedQuery.id = query.id
ec5f5c6b
RG
175 self.assertEquals(query, receivedQuery)
176 self.assertEquals(response, receivedResponse)
177
178
179class TestAdvancedAddCD(DNSDistTest):
180
ec5f5c6b
RG
181 _config_template = """
182 addDisableValidationRule("setcd.advanced.tests.powerdns.com.")
b1bec9f0 183 addAction(makeRule("setcdviaaction.advanced.tests.powerdns.com."), DisableValidationAction())
ec5f5c6b
RG
184 newServer{address="127.0.0.1:%s"}
185 """
186
ec5f5c6b
RG
187 def testAdvancedSetCD(self):
188 """
617dfe22
RG
189 Advanced: Set CD
190
ec5f5c6b
RG
191 Send a query with CD cleared,
192 check that dnsdist set the CD flag.
193 """
194 name = 'setcd.advanced.tests.powerdns.com.'
195 query = dns.message.make_query(name, 'A', 'IN')
b1bec9f0
RG
196 expectedQuery = dns.message.make_query(name, 'A', 'IN')
197 expectedQuery.flags |= dns.flags.CD
198
199 response = dns.message.make_response(query)
200 rrset = dns.rrset.from_text(name,
201 3600,
202 dns.rdataclass.IN,
203 dns.rdatatype.A,
204 '127.0.0.1')
205 response.answer.append(rrset)
206
207 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
208 self.assertTrue(receivedQuery)
209 self.assertTrue(receivedResponse)
210 receivedQuery.id = expectedQuery.id
211 self.assertEquals(expectedQuery, receivedQuery)
212 self.assertEquals(response, receivedResponse)
213
214 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
215 self.assertTrue(receivedQuery)
216 self.assertTrue(receivedResponse)
217 receivedQuery.id = expectedQuery.id
218 self.assertEquals(expectedQuery, receivedQuery)
219 self.assertEquals(response, receivedResponse)
220
221 def testAdvancedSetCDViaAction(self):
222 """
223 Advanced: Set CD via Action
224
225 Send a query with CD cleared,
226 check that dnsdist set the CD flag.
227 """
228 name = 'setcdviaaction.advanced.tests.powerdns.com.'
229 query = dns.message.make_query(name, 'A', 'IN')
230 expectedQuery = dns.message.make_query(name, 'A', 'IN')
ec5f5c6b
RG
231 expectedQuery.flags |= dns.flags.CD
232
233 response = dns.message.make_response(query)
234 rrset = dns.rrset.from_text(name,
235 3600,
236 dns.rdataclass.IN,
237 dns.rdatatype.A,
238 '127.0.0.1')
239 response.answer.append(rrset)
240
241 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
242 self.assertTrue(receivedQuery)
243 self.assertTrue(receivedResponse)
244 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
245 self.assertEquals(expectedQuery, receivedQuery)
246 self.assertEquals(response, receivedResponse)
247
248 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
249 self.assertTrue(receivedQuery)
250 self.assertTrue(receivedResponse)
251 receivedQuery.id = expectedQuery.id
ec5f5c6b
RG
252 self.assertEquals(expectedQuery, receivedQuery)
253 self.assertEquals(response, receivedResponse)
254
255 def testAdvancedKeepNoCD(self):
256 """
617dfe22
RG
257 Advanced: Preserve CD canary
258
ec5f5c6b
RG
259 Send a query without CD for a canary domain,
260 check that dnsdist does not set the CD flag.
261 """
262 name = 'keepnocd.advanced.tests.powerdns.com.'
263 query = dns.message.make_query(name, 'A', 'IN')
264
265 response = dns.message.make_response(query)
266 rrset = dns.rrset.from_text(name,
267 3600,
268 dns.rdataclass.IN,
269 dns.rdatatype.A,
270 '127.0.0.1')
271 response.answer.append(rrset)
272
273 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
274 self.assertTrue(receivedQuery)
275 self.assertTrue(receivedResponse)
276 receivedQuery.id = query.id
ec5f5c6b
RG
277 self.assertEquals(query, receivedQuery)
278 self.assertEquals(response, receivedResponse)
279
280 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
281 self.assertTrue(receivedQuery)
282 self.assertTrue(receivedResponse)
283 receivedQuery.id = query.id
ec5f5c6b
RG
284 self.assertEquals(query, receivedQuery)
285 self.assertEquals(response, receivedResponse)
286
b1bec9f0
RG
287class TestAdvancedClearRD(DNSDistTest):
288
289 _config_template = """
290 addNoRecurseRule("clearrd.advanced.tests.powerdns.com.")
291 addAction(makeRule("clearrdviaaction.advanced.tests.powerdns.com."), NoRecurseAction())
292 newServer{address="127.0.0.1:%s"}
293 """
294
295 def testAdvancedClearRD(self):
296 """
297 Advanced: Clear RD
298
299 Send a query with RD set,
300 check that dnsdist clears the RD flag.
301 """
302 name = 'clearrd.advanced.tests.powerdns.com.'
303 query = dns.message.make_query(name, 'A', 'IN')
304 expectedQuery = dns.message.make_query(name, 'A', 'IN')
305 expectedQuery.flags &= ~dns.flags.RD
306
307 response = dns.message.make_response(query)
308 rrset = dns.rrset.from_text(name,
309 3600,
310 dns.rdataclass.IN,
311 dns.rdatatype.A,
312 '127.0.0.1')
313 response.answer.append(rrset)
314
315 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
316 self.assertTrue(receivedQuery)
317 self.assertTrue(receivedResponse)
318 receivedQuery.id = expectedQuery.id
319 self.assertEquals(expectedQuery, receivedQuery)
320 self.assertEquals(response, receivedResponse)
321
322 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
323 self.assertTrue(receivedQuery)
324 self.assertTrue(receivedResponse)
325 receivedQuery.id = expectedQuery.id
326 self.assertEquals(expectedQuery, receivedQuery)
327 self.assertEquals(response, receivedResponse)
328
329 def testAdvancedClearRDViaAction(self):
330 """
331 Advanced: Clear RD via Action
332
333 Send a query with RD set,
334 check that dnsdist clears the RD flag.
335 """
336 name = 'clearrdviaaction.advanced.tests.powerdns.com.'
337 query = dns.message.make_query(name, 'A', 'IN')
338 expectedQuery = dns.message.make_query(name, 'A', 'IN')
339 expectedQuery.flags &= ~dns.flags.RD
340
341 response = dns.message.make_response(query)
342 rrset = dns.rrset.from_text(name,
343 3600,
344 dns.rdataclass.IN,
345 dns.rdatatype.A,
346 '127.0.0.1')
347 response.answer.append(rrset)
348
349 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
350 self.assertTrue(receivedQuery)
351 self.assertTrue(receivedResponse)
352 receivedQuery.id = expectedQuery.id
353 self.assertEquals(expectedQuery, receivedQuery)
354 self.assertEquals(response, receivedResponse)
355
356 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
357 self.assertTrue(receivedQuery)
358 self.assertTrue(receivedResponse)
359 receivedQuery.id = expectedQuery.id
360 self.assertEquals(expectedQuery, receivedQuery)
361 self.assertEquals(response, receivedResponse)
362
363 def testAdvancedKeepRD(self):
364 """
365 Advanced: Preserve RD canary
366
367 Send a query with RD for a canary domain,
368 check that dnsdist does not clear the RD flag.
369 """
370 name = 'keeprd.advanced.tests.powerdns.com.'
371 query = dns.message.make_query(name, 'A', 'IN')
372
373 response = dns.message.make_response(query)
374 rrset = dns.rrset.from_text(name,
375 3600,
376 dns.rdataclass.IN,
377 dns.rdatatype.A,
378 '127.0.0.1')
379 response.answer.append(rrset)
380
381 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
382 self.assertTrue(receivedQuery)
383 self.assertTrue(receivedResponse)
384 receivedQuery.id = query.id
385 self.assertEquals(query, receivedQuery)
386 self.assertEquals(response, receivedResponse)
387
388 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
389 self.assertTrue(receivedQuery)
390 self.assertTrue(receivedResponse)
391 receivedQuery.id = query.id
392 self.assertEquals(query, receivedQuery)
393 self.assertEquals(response, receivedResponse)
394
ec5f5c6b
RG
395
396class TestAdvancedACL(DNSDistTest):
397
ec5f5c6b
RG
398 _config_template = """
399 newServer{address="127.0.0.1:%s"}
400 """
18a0e7c6 401 _acl = ['192.0.2.1/32']
ec5f5c6b
RG
402
403 def testACLBlocked(self):
404 """
617dfe22
RG
405 Advanced: ACL blocked
406
ec5f5c6b
RG
407 Send an A query to "tests.powerdns.com.",
408 we expect no response since 127.0.0.1 is not on the
409 ACL.
410 """
903853f4 411 name = 'tests.powerdns.com.'
7791f83a 412 query = dns.message.make_query(name, 'A', 'IN')
7791f83a
RG
413
414 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
903853f4 415 self.assertEquals(receivedResponse, None)
7791f83a
RG
416
417 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
903853f4
RG
418 self.assertEquals(receivedResponse, None)
419
420class TestAdvancedDelay(DNSDistTest):
421
422 _config_template = """
423 addAction(AllRule(), DelayAction(1000))
424 newServer{address="127.0.0.1:%s"}
425 """
7791f83a 426
903853f4 427 def testDelayed(self):
7791f83a 428 """
903853f4 429 Advanced: Delayed
7791f83a 430
903853f4
RG
431 Send an A query to "tests.powerdns.com.",
432 check that the response delay is longer than 1000 ms
433 over UDP, less than that over TCP.
7791f83a 434 """
903853f4
RG
435 name = 'tests.powerdns.com.'
436 query = dns.message.make_query(name, 'A', 'IN')
437 response = dns.message.make_response(query)
7791f83a
RG
438 rrset = dns.rrset.from_text(name,
439 60,
440 dns.rdataclass.IN,
903853f4
RG
441 dns.rdatatype.A,
442 '192.0.2.1')
443 response.answer.append(rrset)
7791f83a 444
903853f4
RG
445 begin = datetime.now()
446 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
447 end = datetime.now()
448 receivedQuery.id = query.id
449 self.assertEquals(query, receivedQuery)
450 self.assertEquals(response, receivedResponse)
451 self.assertTrue((end - begin) > timedelta(0, 1))
452
453 begin = datetime.now()
454 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
455 end = datetime.now()
456 receivedQuery.id = query.id
457 self.assertEquals(query, receivedQuery)
458 self.assertEquals(response, receivedResponse)
459 self.assertTrue((end - begin) < timedelta(0, 1))
7791f83a 460
e7a1029c
RG
461
462class TestAdvancedTruncateAnyAndTCP(DNSDistTest):
463
464 _config_template = """
465 truncateTC(false)
466 addAction(AndRule({QTypeRule("ANY"), TCPRule(true)}), TCAction())
467 newServer{address="127.0.0.1:%s"}
468 """
469 def testTruncateAnyOverTCP(self):
470 """
471 Advanced: Truncate ANY over TCP
472
b1bec9f0 473 Send an ANY query to "anytruncatetcp.advanced.tests.powerdns.com.",
e7a1029c
RG
474 should be truncated over TCP, not over UDP (yes, it makes no sense,
475 deal with it).
476 """
b1bec9f0 477 name = 'anytruncatetcp.advanced.tests.powerdns.com.'
e7a1029c
RG
478 query = dns.message.make_query(name, 'ANY', 'IN')
479
480 response = dns.message.make_response(query)
481 rrset = dns.rrset.from_text(name,
482 3600,
483 dns.rdataclass.IN,
484 dns.rdatatype.A,
485 '127.0.0.1')
486
487 response.answer.append(rrset)
488
489 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
490 self.assertTrue(receivedQuery)
491 self.assertTrue(receivedResponse)
492 receivedQuery.id = query.id
e7a1029c
RG
493 self.assertEquals(query, receivedQuery)
494 self.assertEquals(receivedResponse, response)
495
496 expectedResponse = dns.message.make_response(query)
497 expectedResponse.flags |= dns.flags.TC
498
499 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
e7a1029c
RG
500 self.assertEquals(receivedResponse, expectedResponse)
501
502class TestAdvancedAndNot(DNSDistTest):
503
504 _config_template = """
505 addAction(AndRule({NotRule(QTypeRule("A")), TCPRule(false)}), RCodeAction(4))
506 newServer{address="127.0.0.1:%s"}
507 """
508 def testAOverUDPReturnsNotImplementedCanary(self):
509 """
510 Advanced: !A && UDP canary
511
512 dnsdist is configured to reply 'not implemented' for query
513 over UDP AND !qtype A.
514 We send an A query over UDP and TCP, and check that the
515 response is OK.
516 """
b1bec9f0 517 name = 'andnot.advanced.tests.powerdns.com.'
e7a1029c
RG
518 query = dns.message.make_query(name, 'A', 'IN')
519 response = dns.message.make_response(query)
520 rrset = dns.rrset.from_text(name,
521 3600,
522 dns.rdataclass.IN,
523 dns.rdatatype.A,
524 '127.0.0.1')
525 response.answer.append(rrset)
526
527 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
528 self.assertTrue(receivedQuery)
529 self.assertTrue(receivedResponse)
530 receivedQuery.id = query.id
e7a1029c
RG
531 self.assertEquals(query, receivedQuery)
532 self.assertEquals(receivedResponse, response)
533
534 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
535 self.assertTrue(receivedQuery)
536 self.assertTrue(receivedResponse)
537 receivedQuery.id = query.id
e7a1029c
RG
538 self.assertEquals(query, receivedQuery)
539 self.assertEquals(receivedResponse, response)
540
541 def testAOverUDPReturnsNotImplemented(self):
542 """
543 Advanced: !A && UDP
544
545 dnsdist is configured to reply 'not implemented' for query
546 over UDP AND !qtype A.
547 We send a TXT query over UDP and TCP, and check that the
548 response is OK for TCP and 'not implemented' for UDP.
549 """
b1bec9f0 550 name = 'andnot.advanced.tests.powerdns.com.'
e7a1029c
RG
551 query = dns.message.make_query(name, 'TXT', 'IN')
552
553 expectedResponse = dns.message.make_response(query)
554 expectedResponse.set_rcode(dns.rcode.NOTIMP)
555
556 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
e7a1029c
RG
557 self.assertEquals(receivedResponse, expectedResponse)
558
559 response = dns.message.make_response(query)
560 rrset = dns.rrset.from_text(name,
561 3600,
562 dns.rdataclass.IN,
563 dns.rdatatype.TXT,
564 'nothing to see here')
565 response.answer.append(rrset)
566
567 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
568 self.assertTrue(receivedQuery)
569 self.assertTrue(receivedResponse)
570 receivedQuery.id = query.id
e7a1029c
RG
571 self.assertEquals(query, receivedQuery)
572 self.assertEquals(receivedResponse, response)
573
574class TestAdvancedOr(DNSDistTest):
575
576 _config_template = """
577 addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(4))
578 newServer{address="127.0.0.1:%s"}
579 """
580 def testAAAAOverUDPReturnsNotImplemented(self):
581 """
582 Advanced: A || UDP: AAAA
583
584 dnsdist is configured to reply 'not implemented' for query
585 over UDP OR qtype A.
586 We send an AAAA query over UDP and TCP, and check that the
587 response is 'not implemented' for UDP and OK for TCP.
588 """
b1bec9f0 589 name = 'aorudp.advanced.tests.powerdns.com.'
e7a1029c
RG
590 query = dns.message.make_query(name, 'AAAA', 'IN')
591 response = dns.message.make_response(query)
592 rrset = dns.rrset.from_text(name,
593 3600,
594 dns.rdataclass.IN,
595 dns.rdatatype.AAAA,
596 '::1')
597 response.answer.append(rrset)
598
599 expectedResponse = dns.message.make_response(query)
600 expectedResponse.set_rcode(dns.rcode.NOTIMP)
601
602 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
e7a1029c
RG
603 self.assertEquals(receivedResponse, expectedResponse)
604
605 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
606 self.assertTrue(receivedQuery)
607 self.assertTrue(receivedResponse)
608 receivedQuery.id = query.id
e7a1029c
RG
609 self.assertEquals(query, receivedQuery)
610 self.assertEquals(receivedResponse, response)
611
612 def testAOverUDPReturnsNotImplemented(self):
613 """
614 Advanced: A || UDP: A
615
616 dnsdist is configured to reply 'not implemented' for query
617 over UDP OR qtype A.
618 We send an A query over UDP and TCP, and check that the
619 response is 'not implemented' for both.
620 """
b1bec9f0 621 name = 'aorudp.advanced.tests.powerdns.com.'
e7a1029c
RG
622 query = dns.message.make_query(name, 'A', 'IN')
623
624 expectedResponse = dns.message.make_response(query)
625 expectedResponse.set_rcode(dns.rcode.NOTIMP)
626
627 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
e7a1029c
RG
628 self.assertEquals(receivedResponse, expectedResponse)
629
630 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
e7a1029c 631 self.assertEquals(receivedResponse, expectedResponse)
886e2cf2 632
b1bec9f0
RG
633
634class TestAdvancedLogAction(DNSDistTest):
635
636 _config_template = """
637 newServer{address="127.0.0.1:%s"}
638 addAction(AllRule(), LogAction("dnsdist.log", false))
639 """
640 def testAdvancedLogAction(self):
641 """
642 Advanced: Log all queries
643
644 """
645 count = 50
646 name = 'logaction.advanced.tests.powerdns.com.'
647 query = dns.message.make_query(name, 'A', 'IN')
648 response = dns.message.make_response(query)
649 rrset = dns.rrset.from_text(name,
650 3600,
651 dns.rdataclass.IN,
652 dns.rdatatype.A,
653 '127.0.0.1')
654 response.answer.append(rrset)
655
656 for _ in range(count):
657 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
658 self.assertTrue(receivedQuery)
659 self.assertTrue(receivedResponse)
660 receivedQuery.id = query.id
b1bec9f0
RG
661 self.assertEquals(query, receivedQuery)
662 self.assertEquals(response, receivedResponse)
663
664 self.assertTrue(os.path.isfile('dnsdist.log'))
665 self.assertTrue(os.stat('dnsdist.log').st_size > 0)
666
667class TestAdvancedDNSSEC(DNSDistTest):
668
669 _config_template = """
670 newServer{address="127.0.0.1:%s"}
671 addAction(DNSSECRule(), DropAction())
672 """
673 def testAdvancedDNSSECDrop(self):
674 """
675 Advanced: DNSSEC Rule
676
677 """
678 name = 'dnssec.advanced.tests.powerdns.com.'
679 query = dns.message.make_query(name, 'A', 'IN')
680 doquery = dns.message.make_query(name, 'A', 'IN', want_dnssec=True)
681 response = dns.message.make_response(query)
682 rrset = dns.rrset.from_text(name,
683 3600,
684 dns.rdataclass.IN,
685 dns.rdatatype.A,
686 '127.0.0.1')
687 response.answer.append(rrset)
688
689 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
690 self.assertTrue(receivedQuery)
691 self.assertTrue(receivedResponse)
692 receivedQuery.id = query.id
b1bec9f0
RG
693 self.assertEquals(query, receivedQuery)
694 self.assertEquals(response, receivedResponse)
695
696 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
697 self.assertTrue(receivedQuery)
698 self.assertTrue(receivedResponse)
699 receivedQuery.id = query.id
b1bec9f0
RG
700 self.assertEquals(query, receivedQuery)
701 self.assertEquals(response, receivedResponse)
702
703 (_, receivedResponse) = self.sendUDPQuery(doquery, response)
704 self.assertEquals(receivedResponse, None)
705 (_, receivedResponse) = self.sendTCPQuery(doquery, response)
706 self.assertEquals(receivedResponse, None)
707
708class TestAdvancedQClass(DNSDistTest):
709
710 _config_template = """
711 newServer{address="127.0.0.1:%s"}
712 addAction(QClassRule(3), DropAction())
713 """
714 def testAdvancedQClassChaosDrop(self):
715 """
716 Advanced: Drop QClass CHAOS
717
718 """
719 name = 'qclasschaos.advanced.tests.powerdns.com.'
720 query = dns.message.make_query(name, 'TXT', 'CHAOS')
721 response = dns.message.make_response(query)
722 rrset = dns.rrset.from_text(name,
723 3600,
724 dns.rdataclass.CH,
725 dns.rdatatype.TXT,
726 'hop')
727 response.answer.append(rrset)
728
729 (_, receivedResponse) = self.sendUDPQuery(query, response)
730 self.assertEquals(receivedResponse, None)
731 (_, receivedResponse) = self.sendTCPQuery(query, response)
732 self.assertEquals(receivedResponse, None)
733
734 def testAdvancedQClassINAllow(self):
735 """
736 Advanced: Allow QClass IN
737
738 """
739 name = 'qclassin.advanced.tests.powerdns.com.'
740 query = dns.message.make_query(name, 'A', 'IN')
741 response = dns.message.make_response(query)
742 rrset = dns.rrset.from_text(name,
743 3600,
744 dns.rdataclass.IN,
745 dns.rdatatype.A,
746 '127.0.0.1')
747 response.answer.append(rrset)
748
749 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
750 self.assertTrue(receivedQuery)
751 self.assertTrue(receivedResponse)
752 receivedQuery.id = query.id
b1bec9f0
RG
753 self.assertEquals(query, receivedQuery)
754 self.assertEquals(response, receivedResponse)
755
756 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
757 self.assertTrue(receivedQuery)
758 self.assertTrue(receivedResponse)
759 receivedQuery.id = query.id
b1bec9f0
RG
760 self.assertEquals(query, receivedQuery)
761 self.assertEquals(response, receivedResponse)
88d05ca1 762
46a839bf 763
88d05ca1
RG
764class TestAdvancedNonTerminalRule(DNSDistTest):
765
766 _config_template = """
767 newServer{address="127.0.0.1:%s", pool="real"}
768 addAction(AllRule(), DisableValidationAction())
769 addAction(AllRule(), PoolAction("real"))
770 addAction(AllRule(), DropAction())
771 """
772 def testAdvancedNonTerminalRules(self):
773 """
774 Advanced: Non terminal rules
775
776 We check that DisableValidationAction() is applied
777 but does not stop the processing, then that
778 PoolAction() is applied _and_ stop the processing.
779 """
780 name = 'nonterminal.advanced.tests.powerdns.com.'
781 query = dns.message.make_query(name, 'A', 'IN')
782 expectedQuery = dns.message.make_query(name, 'A', 'IN')
783 expectedQuery.flags |= dns.flags.CD
784 response = dns.message.make_response(query)
785 rrset = dns.rrset.from_text(name,
786 3600,
787 dns.rdataclass.IN,
788 dns.rdatatype.A,
46a839bf 789 '192.0.2.1')
88d05ca1
RG
790 response.answer.append(rrset)
791
792 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
793 self.assertTrue(receivedQuery)
794 self.assertTrue(receivedResponse)
795 receivedQuery.id = expectedQuery.id
796 self.assertEquals(expectedQuery, receivedQuery)
797 self.assertEquals(response, receivedResponse)
798
799 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
800 self.assertTrue(receivedQuery)
801 self.assertTrue(receivedResponse)
802 receivedQuery.id = expectedQuery.id
803 self.assertEquals(expectedQuery, receivedQuery)
804 self.assertEquals(response, receivedResponse)
46a839bf
RG
805
806class TestAdvancedStringOnlyServer(DNSDistTest):
807
808 _config_template = """
809 newServer("127.0.0.1:%s")
810 """
811
812 def testAdvancedStringOnlyServer(self):
813 """
814 Advanced: "string-only" server is placed in the default pool
815 """
816 name = 'string-only-server.advanced.tests.powerdns.com.'
817 query = dns.message.make_query(name, 'A', 'IN')
818 response = dns.message.make_response(query)
819 rrset = dns.rrset.from_text(name,
820 3600,
821 dns.rdataclass.IN,
822 dns.rdatatype.A,
823 '192.0.2.1')
824 response.answer.append(rrset)
825
826 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
827 self.assertTrue(receivedQuery)
828 self.assertTrue(receivedResponse)
829 receivedQuery.id = query.id
830 self.assertEquals(query, receivedQuery)
831 self.assertEquals(response, receivedResponse)
832
833 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
834 self.assertTrue(receivedQuery)
835 self.assertTrue(receivedResponse)
836 receivedQuery.id = query.id
837 self.assertEquals(query, receivedQuery)
838 self.assertEquals(response, receivedResponse)
0f72fd5c
RG
839
840class TestAdvancedRestoreFlagsOnSelfResponse(DNSDistTest):
841
842 _config_template = """
843 addAction(AllRule(), DisableValidationAction())
844 addAction(AllRule(), SpoofAction("192.0.2.1"))
845 newServer{address="127.0.0.1:%s"}
846 """
847
848 def testAdvancedRestoreFlagsOnSpoofResponse(self):
849 """
850 Advanced: Restore flags on spoofed response
851
852 Send a query with CD flag cleared, dnsdist is
853 instructed to set it, then to spoof the response,
854 check that response has the flag cleared.
855 """
856 name = 'spoofed.restoreflags.advanced.tests.powerdns.com.'
857 query = dns.message.make_query(name, 'A', 'IN')
858 # dnsdist set RA = RD for spoofed responses
859 query.flags &= ~dns.flags.RD
860 expectedQuery = dns.message.make_query(name, 'A', 'IN')
861
862 response = dns.message.make_response(query)
863 rrset = dns.rrset.from_text(name,
864 60,
865 dns.rdataclass.IN,
866 dns.rdatatype.A,
867 '192.0.2.1')
868 response.answer.append(rrset)
869
870 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
871 self.assertTrue(receivedResponse)
872 self.assertEquals(response, receivedResponse)
873
874 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
875 self.assertTrue(receivedResponse)
876 self.assertEquals(response, receivedResponse)
856c35e3
RG
877
878class TestAdvancedQPS(DNSDistTest):
879
880 _config_template = """
881 addQPSLimit("qps.advanced.tests.powerdns.com", 10)
882 newServer{address="127.0.0.1:%s"}
883 """
884
885 def testAdvancedQPSLimit(self):
886 """
887 Advanced: QPS Limit
888
889 Send queries to "qps.advanced.tests.powerdns.com."
890 check that dnsdist drops queries when the max QPS has been reached.
891 """
892 maxQPS = 10
893 name = 'qps.advanced.tests.powerdns.com.'
894 query = dns.message.make_query(name, 'A', 'IN')
895 response = dns.message.make_response(query)
896 rrset = dns.rrset.from_text(name,
897 60,
898 dns.rdataclass.IN,
899 dns.rdatatype.A,
900 '192.0.2.1')
901 response.answer.append(rrset)
902
903 for _ in range(maxQPS):
904 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
905 receivedQuery.id = query.id
906 self.assertEquals(query, receivedQuery)
907 self.assertEquals(response, receivedResponse)
908
909 # we should now be dropped
910 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
911 self.assertEquals(receivedResponse, None)
912
913 time.sleep(1)
914
915 # again, over TCP this time
916 for _ in range(maxQPS):
917 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
918 receivedQuery.id = query.id
919 self.assertEquals(query, receivedQuery)
920 self.assertEquals(response, receivedResponse)
921
922
923 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
924 self.assertEquals(receivedResponse, None)
925
926class TestAdvancedQPSNone(DNSDistTest):
927
928 _config_template = """
929 addQPSLimit("qpsnone.advanced.tests.powerdns.com", 100)
930 addAction(AllRule(), RCodeAction(5))
931 newServer{address="127.0.0.1:%s"}
932 """
933
934 def testAdvancedQPSNone(self):
935 """
936 Advanced: Not matching QPS returns None, not Allow
937
938 Send queries to "qps.advanced.tests.powerdns.com."
939 check that the rule returns None when the QPS has not been
940 reached, not Allow.
941 """
942 name = 'qpsnone.advanced.tests.powerdns.com.'
943 query = dns.message.make_query(name, 'A', 'IN')
944 expectedResponse = dns.message.make_response(query)
945 expectedResponse.set_rcode(dns.rcode.REFUSED)
946
947 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
948 self.assertEquals(receivedResponse, expectedResponse)
949
950 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
951 self.assertEquals(receivedResponse, expectedResponse)