]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_Advanced.py
Merge pull request #11028 from Habbie/auth-4.4.1-secpoll-docs
[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
9fe42298 7import unittest
b1bec9f0 8import dns
4bfdbd34 9import clientsubnetoption
346410cd 10import cookiesoption
ec5f5c6b
RG
11from dnsdisttests import DNSDistTest
12
b1bec9f0
RG
13class TestAdvancedAllow(DNSDistTest):
14
15 _config_template = """
bc084a31 16 addAction(AllRule(), NoneAction())
b1bec9f0
RG
17 addAction(makeRule("allowed.advanced.tests.powerdns.com."), AllowAction())
18 addAction(AllRule(), DropAction())
19 newServer{address="127.0.0.1:%s"}
20 """
21
22 def testAdvancedAllow(self):
23 """
24 Advanced: Allowed qname is not dropped
25
26 A query for allowed.advanced.tests.powerdns.com. should be allowed
27 while others should be dropped.
28 """
29 name = 'allowed.advanced.tests.powerdns.com.'
30 query = dns.message.make_query(name, 'A', 'IN')
31 response = dns.message.make_response(query)
32 rrset = dns.rrset.from_text(name,
33 3600,
34 dns.rdataclass.IN,
35 dns.rdatatype.A,
36 '127.0.0.1')
37 response.answer.append(rrset)
38
6ca2e796
RG
39 for method in ("sendUDPQuery", "sendTCPQuery"):
40 sender = getattr(self, method)
41 (receivedQuery, receivedResponse) = sender(query, response)
42 self.assertTrue(receivedQuery)
43 self.assertTrue(receivedResponse)
44 receivedQuery.id = query.id
4bfebc93
CH
45 self.assertEqual(query, receivedQuery)
46 self.assertEqual(response, receivedResponse)
b1bec9f0
RG
47
48 def testAdvancedAllowDropped(self):
49 """
50 Advanced: Not allowed qname is dropped
51
52 A query for notallowed.advanced.tests.powerdns.com. should be dropped.
53 """
54 name = 'notallowed.advanced.tests.powerdns.com.'
55 query = dns.message.make_query(name, 'A', 'IN')
b1bec9f0 56
6ca2e796
RG
57 for method in ("sendUDPQuery", "sendTCPQuery"):
58 sender = getattr(self, method)
59 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 60 self.assertEqual(receivedResponse, None)
b1bec9f0 61
ec5f5c6b
RG
62class TestAdvancedFixupCase(DNSDistTest):
63
ec5f5c6b
RG
64 _config_template = """
65 truncateTC(true)
66 fixupCase(true)
67 newServer{address="127.0.0.1:%s"}
68 """
69
ec5f5c6b
RG
70 def testAdvancedFixupCase(self):
71 """
617dfe22
RG
72 Advanced: Fixup Case
73
ec5f5c6b
RG
74 Send a query with lower and upper chars,
75 make the backend return a lowercase version,
76 check that dnsdist fixes the response.
77 """
78 name = 'fiXuPCasE.advanced.tests.powerdns.com.'
79 query = dns.message.make_query(name, 'A', 'IN')
80 lowercasequery = dns.message.make_query(name.lower(), 'A', 'IN')
81 response = dns.message.make_response(lowercasequery)
82 expectedResponse = dns.message.make_response(query)
83 rrset = dns.rrset.from_text(name,
84 3600,
85 dns.rdataclass.IN,
86 dns.rdatatype.A,
87 '127.0.0.1')
88 response.answer.append(rrset)
89 expectedResponse.answer.append(rrset)
90
6ca2e796
RG
91 for method in ("sendUDPQuery", "sendTCPQuery"):
92 sender = getattr(self, method)
93 (receivedQuery, receivedResponse) = sender(query, response)
94 self.assertTrue(receivedQuery)
95 self.assertTrue(receivedResponse)
96 receivedQuery.id = query.id
4bfebc93
CH
97 self.assertEqual(query, receivedQuery)
98 self.assertEqual(expectedResponse, receivedResponse)
ec5f5c6b
RG
99
100class TestAdvancedRemoveRD(DNSDistTest):
101
ec5f5c6b 102 _config_template = """
198d8159 103 addAction("norecurse.advanced.tests.powerdns.com.", SetNoRecurseAction())
ec5f5c6b
RG
104 newServer{address="127.0.0.1:%s"}
105 """
106
ec5f5c6b
RG
107 def testAdvancedNoRD(self):
108 """
617dfe22
RG
109 Advanced: No RD
110
ec5f5c6b
RG
111 Send a query with RD,
112 check that dnsdist clears the RD flag.
113 """
114 name = 'norecurse.advanced.tests.powerdns.com.'
115 query = dns.message.make_query(name, 'A', 'IN')
116 expectedQuery = dns.message.make_query(name, 'A', 'IN')
117 expectedQuery.flags &= ~dns.flags.RD
118
119 response = dns.message.make_response(query)
120 rrset = dns.rrset.from_text(name,
121 3600,
122 dns.rdataclass.IN,
123 dns.rdatatype.A,
124 '127.0.0.1')
125 response.answer.append(rrset)
126
6ca2e796
RG
127 for method in ("sendUDPQuery", "sendTCPQuery"):
128 sender = getattr(self, method)
129 (receivedQuery, receivedResponse) = sender(query, response)
130 self.assertTrue(receivedQuery)
131 self.assertTrue(receivedResponse)
132 receivedQuery.id = expectedQuery.id
4bfebc93
CH
133 self.assertEqual(expectedQuery, receivedQuery)
134 self.assertEqual(response, receivedResponse)
ec5f5c6b
RG
135
136 def testAdvancedKeepRD(self):
137 """
617dfe22
RG
138 Advanced: No RD canary
139
ec5f5c6b
RG
140 Send a query with RD for a canary domain,
141 check that dnsdist does not clear the RD flag.
142 """
143 name = 'keeprecurse.advanced.tests.powerdns.com.'
144 query = dns.message.make_query(name, 'A', 'IN')
145
146 response = dns.message.make_response(query)
147 rrset = dns.rrset.from_text(name,
148 3600,
149 dns.rdataclass.IN,
150 dns.rdatatype.A,
151 '127.0.0.1')
152 response.answer.append(rrset)
153
6ca2e796
RG
154 for method in ("sendUDPQuery", "sendTCPQuery"):
155 sender = getattr(self, method)
156 (receivedQuery, receivedResponse) = sender(query, response)
157 self.assertTrue(receivedQuery)
158 self.assertTrue(receivedResponse)
159 receivedQuery.id = query.id
4bfebc93
CH
160 self.assertEqual(query, receivedQuery)
161 self.assertEqual(response, receivedResponse)
ec5f5c6b
RG
162
163class TestAdvancedAddCD(DNSDistTest):
164
ec5f5c6b 165 _config_template = """
198d8159 166 addAction("setcd.advanced.tests.powerdns.com.", SetDisableValidationAction())
ec5f5c6b
RG
167 newServer{address="127.0.0.1:%s"}
168 """
169
ec5f5c6b
RG
170 def testAdvancedSetCD(self):
171 """
617dfe22
RG
172 Advanced: Set CD
173
ec5f5c6b
RG
174 Send a query with CD cleared,
175 check that dnsdist set the CD flag.
176 """
177 name = 'setcd.advanced.tests.powerdns.com.'
178 query = dns.message.make_query(name, 'A', 'IN')
b1bec9f0
RG
179 expectedQuery = dns.message.make_query(name, 'A', 'IN')
180 expectedQuery.flags |= dns.flags.CD
181
182 response = dns.message.make_response(query)
183 rrset = dns.rrset.from_text(name,
184 3600,
185 dns.rdataclass.IN,
186 dns.rdatatype.A,
187 '127.0.0.1')
188 response.answer.append(rrset)
189
6ca2e796
RG
190 for method in ("sendUDPQuery", "sendTCPQuery"):
191 sender = getattr(self, method)
192 (receivedQuery, receivedResponse) = sender(query, response)
193 self.assertTrue(receivedQuery)
194 self.assertTrue(receivedResponse)
195 receivedQuery.id = expectedQuery.id
4bfebc93
CH
196 self.assertEqual(expectedQuery, receivedQuery)
197 self.assertEqual(response, receivedResponse)
b1bec9f0 198
ec5f5c6b
RG
199 def testAdvancedKeepNoCD(self):
200 """
617dfe22
RG
201 Advanced: Preserve CD canary
202
ec5f5c6b
RG
203 Send a query without CD for a canary domain,
204 check that dnsdist does not set the CD flag.
205 """
206 name = 'keepnocd.advanced.tests.powerdns.com.'
207 query = dns.message.make_query(name, 'A', 'IN')
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 = query.id
4bfebc93
CH
223 self.assertEqual(query, receivedQuery)
224 self.assertEqual(response, receivedResponse)
ec5f5c6b 225
b1bec9f0
RG
226class TestAdvancedClearRD(DNSDistTest):
227
228 _config_template = """
198d8159 229 addAction("clearrd.advanced.tests.powerdns.com.", SetNoRecurseAction())
b1bec9f0
RG
230 newServer{address="127.0.0.1:%s"}
231 """
232
233 def testAdvancedClearRD(self):
234 """
235 Advanced: Clear RD
236
237 Send a query with RD set,
238 check that dnsdist clears the RD flag.
239 """
240 name = 'clearrd.advanced.tests.powerdns.com.'
241 query = dns.message.make_query(name, 'A', 'IN')
242 expectedQuery = dns.message.make_query(name, 'A', 'IN')
243 expectedQuery.flags &= ~dns.flags.RD
244
245 response = dns.message.make_response(query)
246 rrset = dns.rrset.from_text(name,
247 3600,
248 dns.rdataclass.IN,
249 dns.rdatatype.A,
250 '127.0.0.1')
251 response.answer.append(rrset)
252
6ca2e796
RG
253 for method in ("sendUDPQuery", "sendTCPQuery"):
254 sender = getattr(self, method)
255 (receivedQuery, receivedResponse) = sender(query, response)
256 self.assertTrue(receivedQuery)
257 self.assertTrue(receivedResponse)
258 receivedQuery.id = expectedQuery.id
4bfebc93
CH
259 self.assertEqual(expectedQuery, receivedQuery)
260 self.assertEqual(response, receivedResponse)
b1bec9f0
RG
261
262 def testAdvancedKeepRD(self):
263 """
264 Advanced: Preserve RD canary
265
266 Send a query with RD for a canary domain,
267 check that dnsdist does not clear the RD flag.
268 """
269 name = 'keeprd.advanced.tests.powerdns.com.'
270 query = dns.message.make_query(name, 'A', 'IN')
271
272 response = dns.message.make_response(query)
273 rrset = dns.rrset.from_text(name,
274 3600,
275 dns.rdataclass.IN,
276 dns.rdatatype.A,
277 '127.0.0.1')
278 response.answer.append(rrset)
279
6ca2e796
RG
280 for method in ("sendUDPQuery", "sendTCPQuery"):
281 sender = getattr(self, method)
282 (receivedQuery, receivedResponse) = sender(query, response)
283 self.assertTrue(receivedQuery)
284 self.assertTrue(receivedResponse)
285 receivedQuery.id = query.id
4bfebc93
CH
286 self.assertEqual(query, receivedQuery)
287 self.assertEqual(response, receivedResponse)
b1bec9f0 288
ec5f5c6b
RG
289
290class TestAdvancedACL(DNSDistTest):
291
ec5f5c6b
RG
292 _config_template = """
293 newServer{address="127.0.0.1:%s"}
294 """
18a0e7c6 295 _acl = ['192.0.2.1/32']
ec5f5c6b
RG
296
297 def testACLBlocked(self):
298 """
617dfe22
RG
299 Advanced: ACL blocked
300
ec5f5c6b
RG
301 Send an A query to "tests.powerdns.com.",
302 we expect no response since 127.0.0.1 is not on the
303 ACL.
304 """
903853f4 305 name = 'tests.powerdns.com.'
7791f83a 306 query = dns.message.make_query(name, 'A', 'IN')
7791f83a 307
6ca2e796
RG
308 for method in ("sendUDPQuery", "sendTCPQuery"):
309 sender = getattr(self, method)
310 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 311 self.assertEqual(receivedResponse, None)
903853f4
RG
312
313class TestAdvancedDelay(DNSDistTest):
314
315 _config_template = """
316 addAction(AllRule(), DelayAction(1000))
317 newServer{address="127.0.0.1:%s"}
318 """
7791f83a 319
903853f4 320 def testDelayed(self):
7791f83a 321 """
903853f4 322 Advanced: Delayed
7791f83a 323
903853f4
RG
324 Send an A query to "tests.powerdns.com.",
325 check that the response delay is longer than 1000 ms
326 over UDP, less than that over TCP.
7791f83a 327 """
903853f4
RG
328 name = 'tests.powerdns.com.'
329 query = dns.message.make_query(name, 'A', 'IN')
330 response = dns.message.make_response(query)
7791f83a
RG
331 rrset = dns.rrset.from_text(name,
332 60,
333 dns.rdataclass.IN,
903853f4
RG
334 dns.rdatatype.A,
335 '192.0.2.1')
336 response.answer.append(rrset)
7791f83a 337
903853f4
RG
338 begin = datetime.now()
339 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
340 end = datetime.now()
341 receivedQuery.id = query.id
4bfebc93
CH
342 self.assertEqual(query, receivedQuery)
343 self.assertEqual(response, receivedResponse)
903853f4
RG
344 self.assertTrue((end - begin) > timedelta(0, 1))
345
346 begin = datetime.now()
347 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
348 end = datetime.now()
349 receivedQuery.id = query.id
4bfebc93
CH
350 self.assertEqual(query, receivedQuery)
351 self.assertEqual(response, receivedResponse)
903853f4 352 self.assertTrue((end - begin) < timedelta(0, 1))
7791f83a 353
e7a1029c
RG
354class TestAdvancedAndNot(DNSDistTest):
355
356 _config_template = """
d3ec24f9 357 addAction(AndRule({NotRule(QTypeRule("A")), TCPRule(false)}), RCodeAction(DNSRCode.NOTIMP))
e7a1029c
RG
358 newServer{address="127.0.0.1:%s"}
359 """
360 def testAOverUDPReturnsNotImplementedCanary(self):
361 """
362 Advanced: !A && UDP canary
363
364 dnsdist is configured to reply 'not implemented' for query
365 over UDP AND !qtype A.
366 We send an A query over UDP and TCP, and check that the
367 response is OK.
368 """
b1bec9f0 369 name = 'andnot.advanced.tests.powerdns.com.'
e7a1029c
RG
370 query = dns.message.make_query(name, 'A', 'IN')
371 response = dns.message.make_response(query)
372 rrset = dns.rrset.from_text(name,
373 3600,
374 dns.rdataclass.IN,
375 dns.rdatatype.A,
376 '127.0.0.1')
377 response.answer.append(rrset)
378
6ca2e796
RG
379 for method in ("sendUDPQuery", "sendTCPQuery"):
380 sender = getattr(self, method)
381 (receivedQuery, receivedResponse) = sender(query, response)
382 self.assertTrue(receivedQuery)
383 self.assertTrue(receivedResponse)
384 receivedQuery.id = query.id
4bfebc93
CH
385 self.assertEqual(query, receivedQuery)
386 self.assertEqual(receivedResponse, response)
e7a1029c
RG
387
388 def testAOverUDPReturnsNotImplemented(self):
389 """
390 Advanced: !A && UDP
391
392 dnsdist is configured to reply 'not implemented' for query
393 over UDP AND !qtype A.
394 We send a TXT query over UDP and TCP, and check that the
395 response is OK for TCP and 'not implemented' for UDP.
396 """
b1bec9f0 397 name = 'andnot.advanced.tests.powerdns.com.'
e7a1029c 398 query = dns.message.make_query(name, 'TXT', 'IN')
7af22479
RG
399 # dnsdist sets RA = RD for TC responses
400 query.flags &= ~dns.flags.RD
e7a1029c
RG
401
402 expectedResponse = dns.message.make_response(query)
403 expectedResponse.set_rcode(dns.rcode.NOTIMP)
404
405 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
4bfebc93 406 self.assertEqual(receivedResponse, expectedResponse)
e7a1029c
RG
407
408 response = dns.message.make_response(query)
409 rrset = dns.rrset.from_text(name,
410 3600,
411 dns.rdataclass.IN,
412 dns.rdatatype.TXT,
413 'nothing to see here')
414 response.answer.append(rrset)
415
416 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
417 self.assertTrue(receivedQuery)
418 self.assertTrue(receivedResponse)
419 receivedQuery.id = query.id
4bfebc93
CH
420 self.assertEqual(query, receivedQuery)
421 self.assertEqual(receivedResponse, response)
e7a1029c
RG
422
423class TestAdvancedOr(DNSDistTest):
424
425 _config_template = """
d3ec24f9 426 addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(DNSRCode.NOTIMP))
e7a1029c
RG
427 newServer{address="127.0.0.1:%s"}
428 """
429 def testAAAAOverUDPReturnsNotImplemented(self):
430 """
431 Advanced: A || UDP: AAAA
432
433 dnsdist is configured to reply 'not implemented' for query
434 over UDP OR qtype A.
435 We send an AAAA query over UDP and TCP, and check that the
436 response is 'not implemented' for UDP and OK for TCP.
437 """
b1bec9f0 438 name = 'aorudp.advanced.tests.powerdns.com.'
e7a1029c 439 query = dns.message.make_query(name, 'AAAA', 'IN')
7af22479 440 query.flags &= ~dns.flags.RD
e7a1029c
RG
441 response = dns.message.make_response(query)
442 rrset = dns.rrset.from_text(name,
443 3600,
444 dns.rdataclass.IN,
445 dns.rdatatype.AAAA,
446 '::1')
447 response.answer.append(rrset)
448
449 expectedResponse = dns.message.make_response(query)
450 expectedResponse.set_rcode(dns.rcode.NOTIMP)
451
452 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
4bfebc93 453 self.assertEqual(receivedResponse, expectedResponse)
e7a1029c
RG
454
455 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
456 self.assertTrue(receivedQuery)
457 self.assertTrue(receivedResponse)
458 receivedQuery.id = query.id
4bfebc93
CH
459 self.assertEqual(query, receivedQuery)
460 self.assertEqual(receivedResponse, response)
e7a1029c
RG
461
462 def testAOverUDPReturnsNotImplemented(self):
463 """
464 Advanced: A || UDP: A
465
466 dnsdist is configured to reply 'not implemented' for query
467 over UDP OR qtype A.
468 We send an A query over UDP and TCP, and check that the
469 response is 'not implemented' for both.
470 """
b1bec9f0 471 name = 'aorudp.advanced.tests.powerdns.com.'
e7a1029c 472 query = dns.message.make_query(name, 'A', 'IN')
7af22479 473 query.flags &= ~dns.flags.RD
e7a1029c
RG
474
475 expectedResponse = dns.message.make_response(query)
476 expectedResponse.set_rcode(dns.rcode.NOTIMP)
477
6ca2e796
RG
478 for method in ("sendUDPQuery", "sendTCPQuery"):
479 sender = getattr(self, method)
480 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 481 self.assertEqual(receivedResponse, expectedResponse)
886e2cf2 482
b1bec9f0
RG
483
484class TestAdvancedLogAction(DNSDistTest):
485
486 _config_template = """
487 newServer{address="127.0.0.1:%s"}
488 addAction(AllRule(), LogAction("dnsdist.log", false))
489 """
490 def testAdvancedLogAction(self):
491 """
492 Advanced: Log all queries
493
494 """
495 count = 50
496 name = 'logaction.advanced.tests.powerdns.com.'
497 query = dns.message.make_query(name, 'A', 'IN')
498 response = dns.message.make_response(query)
499 rrset = dns.rrset.from_text(name,
500 3600,
501 dns.rdataclass.IN,
502 dns.rdatatype.A,
503 '127.0.0.1')
504 response.answer.append(rrset)
505
506 for _ in range(count):
507 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
508 self.assertTrue(receivedQuery)
509 self.assertTrue(receivedResponse)
510 receivedQuery.id = query.id
4bfebc93
CH
511 self.assertEqual(query, receivedQuery)
512 self.assertEqual(response, receivedResponse)
b1bec9f0
RG
513
514 self.assertTrue(os.path.isfile('dnsdist.log'))
515 self.assertTrue(os.stat('dnsdist.log').st_size > 0)
516
517class TestAdvancedDNSSEC(DNSDistTest):
518
519 _config_template = """
520 newServer{address="127.0.0.1:%s"}
521 addAction(DNSSECRule(), DropAction())
522 """
523 def testAdvancedDNSSECDrop(self):
524 """
525 Advanced: DNSSEC Rule
526
527 """
528 name = 'dnssec.advanced.tests.powerdns.com.'
529 query = dns.message.make_query(name, 'A', 'IN')
530 doquery = dns.message.make_query(name, 'A', 'IN', want_dnssec=True)
531 response = dns.message.make_response(query)
532 rrset = dns.rrset.from_text(name,
533 3600,
534 dns.rdataclass.IN,
535 dns.rdatatype.A,
536 '127.0.0.1')
537 response.answer.append(rrset)
538
6ca2e796
RG
539 for method in ("sendUDPQuery", "sendTCPQuery"):
540 sender = getattr(self, method)
541 (receivedQuery, receivedResponse) = sender(query, response)
542 self.assertTrue(receivedQuery)
543 self.assertTrue(receivedResponse)
544 receivedQuery.id = query.id
4bfebc93
CH
545 self.assertEqual(query, receivedQuery)
546 self.assertEqual(response, receivedResponse)
b1bec9f0 547
6ca2e796
RG
548 for method in ("sendUDPQuery", "sendTCPQuery"):
549 sender = getattr(self, method)
90186270 550 (_, receivedResponse) = sender(doquery, response=None, useQueue=False)
4bfebc93 551 self.assertEqual(receivedResponse, None)
b1bec9f0
RG
552
553class TestAdvancedQClass(DNSDistTest):
554
555 _config_template = """
556 newServer{address="127.0.0.1:%s"}
55baa1f2 557 addAction(QClassRule(DNSClass.CHAOS), DropAction())
b1bec9f0
RG
558 """
559 def testAdvancedQClassChaosDrop(self):
560 """
561 Advanced: Drop QClass CHAOS
562
563 """
564 name = 'qclasschaos.advanced.tests.powerdns.com.'
565 query = dns.message.make_query(name, 'TXT', 'CHAOS')
b1bec9f0 566
6ca2e796
RG
567 for method in ("sendUDPQuery", "sendTCPQuery"):
568 sender = getattr(self, method)
90186270 569 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 570 self.assertEqual(receivedResponse, None)
b1bec9f0
RG
571
572 def testAdvancedQClassINAllow(self):
573 """
574 Advanced: Allow QClass IN
575
576 """
577 name = 'qclassin.advanced.tests.powerdns.com.'
578 query = dns.message.make_query(name, 'A', 'IN')
579 response = dns.message.make_response(query)
580 rrset = dns.rrset.from_text(name,
581 3600,
582 dns.rdataclass.IN,
583 dns.rdatatype.A,
584 '127.0.0.1')
585 response.answer.append(rrset)
586
6ca2e796
RG
587 for method in ("sendUDPQuery", "sendTCPQuery"):
588 sender = getattr(self, method)
589 (receivedQuery, receivedResponse) = sender(query, response)
590 self.assertTrue(receivedQuery)
591 self.assertTrue(receivedResponse)
592 receivedQuery.id = query.id
4bfebc93
CH
593 self.assertEqual(query, receivedQuery)
594 self.assertEqual(response, receivedResponse)
88d05ca1 595
55baa1f2
RG
596class TestAdvancedOpcode(DNSDistTest):
597
598 _config_template = """
599 newServer{address="127.0.0.1:%s"}
600 addAction(OpcodeRule(DNSOpcode.Notify), DropAction())
601 """
602 def testAdvancedOpcodeNotifyDrop(self):
603 """
604 Advanced: Drop Opcode NOTIFY
605
606 """
607 name = 'opcodenotify.advanced.tests.powerdns.com.'
608 query = dns.message.make_query(name, 'A', 'IN')
609 query.set_opcode(dns.opcode.NOTIFY)
610
6ca2e796
RG
611 for method in ("sendUDPQuery", "sendTCPQuery"):
612 sender = getattr(self, method)
90186270 613 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 614 self.assertEqual(receivedResponse, None)
55baa1f2
RG
615
616 def testAdvancedOpcodeUpdateINAllow(self):
617 """
618 Advanced: Allow Opcode UPDATE
619
620 """
621 name = 'opcodeupdate.advanced.tests.powerdns.com.'
6e1f856f 622 query = dns.message.make_query(name, 'SOA', 'IN')
55baa1f2
RG
623 query.set_opcode(dns.opcode.UPDATE)
624 response = dns.message.make_response(query)
625 rrset = dns.rrset.from_text(name,
626 3600,
627 dns.rdataclass.IN,
628 dns.rdatatype.A,
629 '127.0.0.1')
630 response.answer.append(rrset)
631
6ca2e796
RG
632 for method in ("sendUDPQuery", "sendTCPQuery"):
633 sender = getattr(self, method)
634 (receivedQuery, receivedResponse) = sender(query, response)
635 self.assertTrue(receivedQuery)
636 self.assertTrue(receivedResponse)
637 receivedQuery.id = query.id
4bfebc93
CH
638 self.assertEqual(query, receivedQuery)
639 self.assertEqual(response, receivedResponse)
46a839bf 640
88d05ca1
RG
641class TestAdvancedNonTerminalRule(DNSDistTest):
642
643 _config_template = """
644 newServer{address="127.0.0.1:%s", pool="real"}
198d8159 645 addAction(AllRule(), SetDisableValidationAction())
88d05ca1
RG
646 addAction(AllRule(), PoolAction("real"))
647 addAction(AllRule(), DropAction())
648 """
649 def testAdvancedNonTerminalRules(self):
650 """
651 Advanced: Non terminal rules
652
198d8159 653 We check that SetDisableValidationAction() is applied
88d05ca1
RG
654 but does not stop the processing, then that
655 PoolAction() is applied _and_ stop the processing.
656 """
657 name = 'nonterminal.advanced.tests.powerdns.com.'
658 query = dns.message.make_query(name, 'A', 'IN')
659 expectedQuery = dns.message.make_query(name, 'A', 'IN')
660 expectedQuery.flags |= dns.flags.CD
661 response = dns.message.make_response(query)
662 rrset = dns.rrset.from_text(name,
663 3600,
664 dns.rdataclass.IN,
665 dns.rdatatype.A,
46a839bf 666 '192.0.2.1')
88d05ca1
RG
667 response.answer.append(rrset)
668
6ca2e796
RG
669 for method in ("sendUDPQuery", "sendTCPQuery"):
670 sender = getattr(self, method)
671 (receivedQuery, receivedResponse) = sender(query, response)
672 self.assertTrue(receivedQuery)
673 self.assertTrue(receivedResponse)
674 receivedQuery.id = expectedQuery.id
4bfebc93
CH
675 self.assertEqual(expectedQuery, receivedQuery)
676 self.assertEqual(response, receivedResponse)
46a839bf
RG
677
678class TestAdvancedStringOnlyServer(DNSDistTest):
679
680 _config_template = """
681 newServer("127.0.0.1:%s")
682 """
683
684 def testAdvancedStringOnlyServer(self):
685 """
686 Advanced: "string-only" server is placed in the default pool
687 """
688 name = 'string-only-server.advanced.tests.powerdns.com.'
689 query = dns.message.make_query(name, 'A', 'IN')
690 response = dns.message.make_response(query)
691 rrset = dns.rrset.from_text(name,
692 3600,
693 dns.rdataclass.IN,
694 dns.rdatatype.A,
695 '192.0.2.1')
696 response.answer.append(rrset)
697
6ca2e796
RG
698 for method in ("sendUDPQuery", "sendTCPQuery"):
699 sender = getattr(self, method)
700 (receivedQuery, receivedResponse) = sender(query, response)
701 self.assertTrue(receivedQuery)
702 self.assertTrue(receivedResponse)
703 receivedQuery.id = query.id
4bfebc93
CH
704 self.assertEqual(query, receivedQuery)
705 self.assertEqual(response, receivedResponse)
0f72fd5c
RG
706
707class TestAdvancedRestoreFlagsOnSelfResponse(DNSDistTest):
708
709 _config_template = """
198d8159 710 addAction(AllRule(), SetDisableValidationAction())
0f72fd5c
RG
711 addAction(AllRule(), SpoofAction("192.0.2.1"))
712 newServer{address="127.0.0.1:%s"}
713 """
714
715 def testAdvancedRestoreFlagsOnSpoofResponse(self):
716 """
717 Advanced: Restore flags on spoofed response
718
719 Send a query with CD flag cleared, dnsdist is
720 instructed to set it, then to spoof the response,
721 check that response has the flag cleared.
722 """
723 name = 'spoofed.restoreflags.advanced.tests.powerdns.com.'
724 query = dns.message.make_query(name, 'A', 'IN')
725 # dnsdist set RA = RD for spoofed responses
726 query.flags &= ~dns.flags.RD
0f72fd5c
RG
727
728 response = dns.message.make_response(query)
729 rrset = dns.rrset.from_text(name,
730 60,
731 dns.rdataclass.IN,
732 dns.rdatatype.A,
733 '192.0.2.1')
734 response.answer.append(rrset)
735
6ca2e796
RG
736 for method in ("sendUDPQuery", "sendTCPQuery"):
737 sender = getattr(self, method)
738 (_, receivedResponse) = sender(query, response=None, useQueue=False)
739 self.assertTrue(receivedResponse)
4bfebc93 740 self.assertEqual(response, receivedResponse)
6ca2e796 741
856c35e3
RG
742class TestAdvancedQPS(DNSDistTest):
743
744 _config_template = """
8499caaf 745 addAction("qps.advanced.tests.powerdns.com", QPSAction(10))
856c35e3
RG
746 newServer{address="127.0.0.1:%s"}
747 """
748
749 def testAdvancedQPSLimit(self):
750 """
751 Advanced: QPS Limit
752
753 Send queries to "qps.advanced.tests.powerdns.com."
754 check that dnsdist drops queries when the max QPS has been reached.
755 """
756 maxQPS = 10
757 name = 'qps.advanced.tests.powerdns.com.'
758 query = dns.message.make_query(name, 'A', 'IN')
759 response = dns.message.make_response(query)
760 rrset = dns.rrset.from_text(name,
761 60,
762 dns.rdataclass.IN,
763 dns.rdatatype.A,
764 '192.0.2.1')
765 response.answer.append(rrset)
766
767 for _ in range(maxQPS):
768 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
769 receivedQuery.id = query.id
4bfebc93
CH
770 self.assertEqual(query, receivedQuery)
771 self.assertEqual(response, receivedResponse)
856c35e3
RG
772
773 # we should now be dropped
774 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
4bfebc93 775 self.assertEqual(receivedResponse, None)
856c35e3
RG
776
777 time.sleep(1)
778
779 # again, over TCP this time
780 for _ in range(maxQPS):
781 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
782 receivedQuery.id = query.id
4bfebc93
CH
783 self.assertEqual(query, receivedQuery)
784 self.assertEqual(response, receivedResponse)
856c35e3
RG
785
786
787 (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False)
4bfebc93 788 self.assertEqual(receivedResponse, None)
856c35e3
RG
789
790class TestAdvancedQPSNone(DNSDistTest):
791
792 _config_template = """
8499caaf 793 addAction("qpsnone.advanced.tests.powerdns.com", QPSAction(100))
d3ec24f9 794 addAction(AllRule(), RCodeAction(DNSRCode.REFUSED))
856c35e3
RG
795 newServer{address="127.0.0.1:%s"}
796 """
797
798 def testAdvancedQPSNone(self):
799 """
800 Advanced: Not matching QPS returns None, not Allow
801
802 Send queries to "qps.advanced.tests.powerdns.com."
803 check that the rule returns None when the QPS has not been
804 reached, not Allow.
805 """
806 name = 'qpsnone.advanced.tests.powerdns.com.'
807 query = dns.message.make_query(name, 'A', 'IN')
7af22479 808 query.flags &= ~dns.flags.RD
856c35e3
RG
809 expectedResponse = dns.message.make_response(query)
810 expectedResponse.set_rcode(dns.rcode.REFUSED)
811
6ca2e796
RG
812 for method in ("sendUDPQuery", "sendTCPQuery"):
813 sender = getattr(self, method)
814 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 815 self.assertEqual(receivedResponse, expectedResponse)
36da3ecd
RG
816
817class TestAdvancedNMGRule(DNSDistTest):
818
819 _config_template = """
820 allowed = newNMG()
821 allowed:addMask("192.0.2.1/32")
d3ec24f9 822 addAction(NotRule(NetmaskGroupRule(allowed)), RCodeAction(DNSRCode.REFUSED))
36da3ecd
RG
823 newServer{address="127.0.0.1:%s"}
824 """
825
826 def testAdvancedNMGRule(self):
827 """
828 Advanced: NMGRule should refuse our queries
829
830 Send queries to "nmgrule.advanced.tests.powerdns.com.",
831 check that we are getting a REFUSED response.
832 """
833 name = 'nmgrule.advanced.tests.powerdns.com.'
834 query = dns.message.make_query(name, 'A', 'IN')
7af22479 835 query.flags &= ~dns.flags.RD
36da3ecd
RG
836 expectedResponse = dns.message.make_response(query)
837 expectedResponse.set_rcode(dns.rcode.REFUSED)
838
6ca2e796
RG
839 for method in ("sendUDPQuery", "sendTCPQuery"):
840 sender = getattr(self, method)
841 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 842 self.assertEqual(receivedResponse, expectedResponse)
55baa1f2 843
a8205923 844class TestDSTPortRule(DNSDistTest):
845
846 _config_params = ['_dnsDistPort', '_testServerPort']
847 _config_template = """
d3ec24f9 848 addAction(DSTPortRule(%d), RCodeAction(DNSRCode.REFUSED))
a8205923 849 newServer{address="127.0.0.1:%s"}
850 """
851
852 def testDSTPortRule(self):
853 """
854 Advanced: DSTPortRule should capture our queries
855
856 Send queries to "dstportrule.advanced.tests.powerdns.com.",
857 check that we are getting a REFUSED response.
858 """
859
860 name = 'dstportrule.advanced.tests.powerdns.com.'
861 query = dns.message.make_query(name, 'A', 'IN')
7af22479 862 query.flags &= ~dns.flags.RD
a8205923 863 expectedResponse = dns.message.make_response(query)
864 expectedResponse.set_rcode(dns.rcode.REFUSED)
865
6ca2e796
RG
866 for method in ("sendUDPQuery", "sendTCPQuery"):
867 sender = getattr(self, method)
868 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 869 self.assertEqual(receivedResponse, expectedResponse)
a8205923 870
57c61ce9
RG
871class TestAdvancedLabelsCountRule(DNSDistTest):
872
873 _config_template = """
d3ec24f9 874 addAction(QNameLabelsCountRule(5,6), RCodeAction(DNSRCode.REFUSED))
57c61ce9
RG
875 newServer{address="127.0.0.1:%s"}
876 """
877
878 def testAdvancedLabelsCountRule(self):
879 """
880 Advanced: QNameLabelsCountRule(5,6)
881 """
882 # 6 labels, we should be fine
883 name = 'ok.labelscount.advanced.tests.powerdns.com.'
884 query = dns.message.make_query(name, 'A', 'IN')
885 response = dns.message.make_response(query)
886 rrset = dns.rrset.from_text(name,
887 3600,
888 dns.rdataclass.IN,
889 dns.rdatatype.A,
890 '192.0.2.1')
891 response.answer.append(rrset)
892
6ca2e796
RG
893 for method in ("sendUDPQuery", "sendTCPQuery"):
894 sender = getattr(self, method)
895 (receivedQuery, receivedResponse) = sender(query, response)
896 self.assertTrue(receivedQuery)
897 self.assertTrue(receivedResponse)
898 receivedQuery.id = query.id
4bfebc93
CH
899 self.assertEqual(query, receivedQuery)
900 self.assertEqual(response, receivedResponse)
57c61ce9
RG
901
902 # more than 6 labels, the query should be refused
903 name = 'not.ok.labelscount.advanced.tests.powerdns.com.'
904 query = dns.message.make_query(name, 'A', 'IN')
7af22479 905 query.flags &= ~dns.flags.RD
57c61ce9
RG
906 expectedResponse = dns.message.make_response(query)
907 expectedResponse.set_rcode(dns.rcode.REFUSED)
908
6ca2e796
RG
909 for method in ("sendUDPQuery", "sendTCPQuery"):
910 sender = getattr(self, method)
911 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 912 self.assertEqual(receivedResponse, expectedResponse)
57c61ce9
RG
913
914 # less than 5 labels, the query should be refused
915 name = 'labelscountadvanced.tests.powerdns.com.'
916 query = dns.message.make_query(name, 'A', 'IN')
7af22479 917 query.flags &= ~dns.flags.RD
57c61ce9
RG
918 expectedResponse = dns.message.make_response(query)
919 expectedResponse.set_rcode(dns.rcode.REFUSED)
920
6ca2e796
RG
921 for method in ("sendUDPQuery", "sendTCPQuery"):
922 sender = getattr(self, method)
923 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 924 self.assertEqual(receivedResponse, expectedResponse)
57c61ce9
RG
925
926class TestAdvancedWireLengthRule(DNSDistTest):
927
928 _config_template = """
d3ec24f9 929 addAction(QNameWireLengthRule(54,56), RCodeAction(DNSRCode.REFUSED))
57c61ce9
RG
930 newServer{address="127.0.0.1:%s"}
931 """
932
933 def testAdvancedWireLengthRule(self):
934 """
935 Advanced: QNameWireLengthRule(54,56)
936 """
937 name = 'longenough.qnamewirelength.advanced.tests.powerdns.com.'
938 query = dns.message.make_query(name, 'A', 'IN')
939 response = dns.message.make_response(query)
940 rrset = dns.rrset.from_text(name,
941 3600,
942 dns.rdataclass.IN,
943 dns.rdatatype.A,
944 '192.0.2.1')
945 response.answer.append(rrset)
946
6ca2e796
RG
947 for method in ("sendUDPQuery", "sendTCPQuery"):
948 sender = getattr(self, method)
949 (receivedQuery, receivedResponse) = sender(query, response)
950 self.assertTrue(receivedQuery)
951 self.assertTrue(receivedResponse)
952 receivedQuery.id = query.id
4bfebc93
CH
953 self.assertEqual(query, receivedQuery)
954 self.assertEqual(response, receivedResponse)
57c61ce9
RG
955
956 # too short, the query should be refused
957 name = 'short.qnamewirelength.advanced.tests.powerdns.com.'
958 query = dns.message.make_query(name, 'A', 'IN')
7af22479 959 query.flags &= ~dns.flags.RD
57c61ce9
RG
960 expectedResponse = dns.message.make_response(query)
961 expectedResponse.set_rcode(dns.rcode.REFUSED)
962
6ca2e796
RG
963 for method in ("sendUDPQuery", "sendTCPQuery"):
964 sender = getattr(self, method)
965 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 966 self.assertEqual(receivedResponse, expectedResponse)
57c61ce9
RG
967
968 # too long, the query should be refused
969 name = 'toolongtobevalid.qnamewirelength.advanced.tests.powerdns.com.'
970 query = dns.message.make_query(name, 'A', 'IN')
7af22479 971 query.flags &= ~dns.flags.RD
57c61ce9
RG
972 expectedResponse = dns.message.make_response(query)
973 expectedResponse.set_rcode(dns.rcode.REFUSED)
974
6ca2e796
RG
975 for method in ("sendUDPQuery", "sendTCPQuery"):
976 sender = getattr(self, method)
977 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 978 self.assertEqual(receivedResponse, expectedResponse)
69389510 979
9fe42298 980@unittest.skipIf('SKIP_INCLUDEDIR_TESTS' in os.environ, 'IncludeDir tests are disabled')
69389510
RG
981class TestAdvancedIncludeDir(DNSDistTest):
982
983 _config_template = """
984 -- this directory contains a file allowing includedir.advanced.tests.powerdns.com.
985 includeDirectory('test-include-dir')
69389510
RG
986 newServer{address="127.0.0.1:%s"}
987 """
988
989 def testAdvancedIncludeDirAllowed(self):
990 """
991 Advanced: includeDirectory()
992 """
993 name = 'includedir.advanced.tests.powerdns.com.'
994 query = dns.message.make_query(name, 'A', 'IN')
995 response = dns.message.make_response(query)
996 rrset = dns.rrset.from_text(name,
997 3600,
998 dns.rdataclass.IN,
999 dns.rdatatype.A,
1000 '192.0.2.1')
1001 response.answer.append(rrset)
1002
6ca2e796
RG
1003 for method in ("sendUDPQuery", "sendTCPQuery"):
1004 sender = getattr(self, method)
1005 (receivedQuery, receivedResponse) = sender(query, response)
1006 self.assertTrue(receivedQuery)
1007 self.assertTrue(receivedResponse)
1008 receivedQuery.id = query.id
4bfebc93
CH
1009 self.assertEqual(query, receivedQuery)
1010 self.assertEqual(response, receivedResponse)
69389510
RG
1011
1012 # this one should be refused
1013 name = 'notincludedir.advanced.tests.powerdns.com.'
1014 query = dns.message.make_query(name, 'A', 'IN')
7af22479 1015 query.flags &= ~dns.flags.RD
69389510
RG
1016 expectedResponse = dns.message.make_response(query)
1017 expectedResponse.set_rcode(dns.rcode.REFUSED)
1018
6ca2e796
RG
1019 for method in ("sendUDPQuery", "sendTCPQuery"):
1020 sender = getattr(self, method)
1021 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1022 self.assertEqual(receivedResponse, expectedResponse)
b82f0bc2
RG
1023
1024class TestAdvancedLuaDO(DNSDistTest):
1025
1026 _config_template = """
1027 function nxDOLua(dq)
1028 if dq:getDO() then
1029 return DNSAction.Nxdomain, ""
1030 end
1031 return DNSAction.None, ""
1032 end
a2ff35e3 1033 addAction(AllRule(), LuaAction(nxDOLua))
b82f0bc2
RG
1034 newServer{address="127.0.0.1:%s"}
1035 """
1036
1037 def testNxDOViaLua(self):
1038 """
1039 Advanced: Nx DO queries via Lua
1040 """
1041 name = 'nxdo.advanced.tests.powerdns.com.'
1042 query = dns.message.make_query(name, 'A', 'IN')
1043 response = dns.message.make_response(query)
1044 rrset = dns.rrset.from_text(name,
1045 3600,
1046 dns.rdataclass.IN,
1047 dns.rdatatype.AAAA,
1048 '::1')
1049 response.answer.append(rrset)
1050 queryWithDO = dns.message.make_query(name, 'A', 'IN', want_dnssec=True)
1051 doResponse = dns.message.make_response(queryWithDO)
1052 doResponse.set_rcode(dns.rcode.NXDOMAIN)
1053
1054 # without DO
6ca2e796
RG
1055 for method in ("sendUDPQuery", "sendTCPQuery"):
1056 sender = getattr(self, method)
1057 (receivedQuery, receivedResponse) = sender(query, response)
1058 self.assertTrue(receivedQuery)
1059 self.assertTrue(receivedResponse)
1060 receivedQuery.id = query.id
4bfebc93
CH
1061 self.assertEqual(query, receivedQuery)
1062 self.assertEqual(receivedResponse, response)
b82f0bc2
RG
1063
1064 # with DO
6ca2e796
RG
1065 for method in ("sendUDPQuery", "sendTCPQuery"):
1066 sender = getattr(self, method)
1067 (_, receivedResponse) = sender(queryWithDO, response=None, useQueue=False)
1068 self.assertTrue(receivedResponse)
1069 doResponse.id = receivedResponse.id
4bfebc93 1070 self.assertEqual(receivedResponse, doResponse)
26b86deb 1071
c4f5aeff
RG
1072class TestAdvancedLuaRefused(DNSDistTest):
1073
1074 _config_template = """
1075 function refuse(dq)
1076 return DNSAction.Refused, ""
1077 end
a2ff35e3 1078 addAction(AllRule(), LuaAction(refuse))
c4f5aeff
RG
1079 newServer{address="127.0.0.1:%s"}
1080 """
1081
1082 def testRefusedViaLua(self):
1083 """
1084 Advanced: Refused via Lua
1085 """
1086 name = 'refused.advanced.tests.powerdns.com.'
1087 query = dns.message.make_query(name, 'A', 'IN')
1088 response = dns.message.make_response(query)
1089 rrset = dns.rrset.from_text(name,
1090 3600,
1091 dns.rdataclass.IN,
1092 dns.rdatatype.AAAA,
1093 '::1')
1094 response.answer.append(rrset)
1095 refusedResponse = dns.message.make_response(query)
1096 refusedResponse.set_rcode(dns.rcode.REFUSED)
1097
6ca2e796
RG
1098 for method in ("sendUDPQuery", "sendTCPQuery"):
1099 sender = getattr(self, method)
1100 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1101 self.assertTrue(receivedResponse)
1102 refusedResponse.id = receivedResponse.id
4bfebc93 1103 self.assertEqual(receivedResponse, refusedResponse)
63cdc73d
CHB
1104
1105class TestAdvancedLuaActionReturnSyntax(DNSDistTest):
1106
1107 _config_template = """
1108 function refuse(dq)
1109 return DNSAction.Refused
1110 end
1111 addAction(AllRule(), LuaAction(refuse))
1112 newServer{address="127.0.0.1:%s"}
1113 """
1114
1115 def testRefusedWithEmptyRule(self):
1116 """
1117 Advanced: Short syntax for LuaAction return values
1118 """
0b3789ef 1119 name = 'short.refused.advanced.tests.powerdns.com.'
63cdc73d
CHB
1120 query = dns.message.make_query(name, 'A', 'IN')
1121 response = dns.message.make_response(query)
1122 rrset = dns.rrset.from_text(name,
1123 3600,
1124 dns.rdataclass.IN,
1125 dns.rdatatype.AAAA,
1126 '::1')
1127 response.answer.append(rrset)
1128 refusedResponse = dns.message.make_response(query)
1129 refusedResponse.set_rcode(dns.rcode.REFUSED)
1130
6ca2e796
RG
1131 for method in ("sendUDPQuery", "sendTCPQuery"):
1132 sender = getattr(self, method)
1133 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1134 self.assertTrue(receivedResponse)
1135 refusedResponse.id = receivedResponse.id
4bfebc93 1136 self.assertEqual(receivedResponse, refusedResponse)
c4f5aeff
RG
1137
1138class TestAdvancedLuaTruncated(DNSDistTest):
1139
1140 _config_template = """
1141 function trunc(dq)
1142 if not dq.tcp then
1143 return DNSAction.Truncate, ""
1144 end
1145 return DNSAction.None, ""
1146 end
a2ff35e3 1147 addAction(AllRule(), LuaAction(trunc))
c4f5aeff
RG
1148 newServer{address="127.0.0.1:%s"}
1149 """
1150
1151 def testTCViaLua(self):
1152 """
1153 Advanced: TC via Lua
1154 """
1155 name = 'tc.advanced.tests.powerdns.com.'
1156 query = dns.message.make_query(name, 'A', 'IN')
955b9377
RG
1157 # dnsdist sets RA = RD for TC responses
1158 query.flags &= ~dns.flags.RD
c4f5aeff
RG
1159 response = dns.message.make_response(query)
1160 rrset = dns.rrset.from_text(name,
1161 3600,
1162 dns.rdataclass.IN,
1163 dns.rdatatype.AAAA,
1164 '::1')
1165 response.answer.append(rrset)
1166
1167 truncatedResponse = dns.message.make_response(query)
1168 truncatedResponse.flags |= dns.flags.TC
1169
1170 (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
1171 self.assertTrue(receivedResponse)
1172 truncatedResponse.id = receivedResponse.id
4bfebc93 1173 self.assertEqual(receivedResponse, truncatedResponse)
c4f5aeff
RG
1174
1175 # no truncation over TCP
1176 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
1177 self.assertTrue(receivedQuery)
1178 self.assertTrue(receivedResponse)
1179 receivedQuery.id = query.id
4bfebc93
CH
1180 self.assertEqual(query, receivedQuery)
1181 self.assertEqual(receivedResponse, response)
c4f5aeff 1182
26b86deb
RG
1183class TestStatNodeRespRingSince(DNSDistTest):
1184
1185 _consoleKey = DNSDistTest.generateConsoleKey()
b4f23783 1186 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
26b86deb
RG
1187 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
1188 _config_template = """
1189 setKey("%s")
1190 controlSocket("127.0.0.1:%s")
1191 s1 = newServer{address="127.0.0.1:%s"}
1192 s1:setUp()
1193 function visitor(node, self, childstat)
1194 table.insert(nodesSeen, node.fullname)
1195 end
1196 """
1197
1198 def testStatNodeRespRingSince(self):
1199 """
1200 Advanced: StatNodeRespRing with optional since parameter
1201
1202 """
1203 name = 'statnodesince.advanced.tests.powerdns.com.'
1204 query = dns.message.make_query(name, 'A', 'IN')
1205 response = dns.message.make_response(query)
1206 rrset = dns.rrset.from_text(name,
1207 1,
1208 dns.rdataclass.IN,
1209 dns.rdatatype.A,
1210 '127.0.0.1')
1211 response.answer.append(rrset)
1212
1213 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
1214 self.assertTrue(receivedQuery)
1215 self.assertTrue(receivedResponse)
1216 receivedQuery.id = query.id
4bfebc93
CH
1217 self.assertEqual(query, receivedQuery)
1218 self.assertEqual(response, receivedResponse)
26b86deb
RG
1219
1220 self.sendConsoleCommand("nodesSeen = {}")
1221 self.sendConsoleCommand("statNodeRespRing(visitor)")
1222 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1223 nodes = nodes.strip("\n")
4bfebc93 1224 self.assertEqual(nodes, """statnodesince.advanced.tests.powerdns.com.
26b86deb
RG
1225advanced.tests.powerdns.com.
1226tests.powerdns.com.
1227powerdns.com.
1228com.""")
1229
1230 self.sendConsoleCommand("nodesSeen = {}")
1231 self.sendConsoleCommand("statNodeRespRing(visitor, 0)")
1232 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1233 nodes = nodes.strip("\n")
4bfebc93 1234 self.assertEqual(nodes, """statnodesince.advanced.tests.powerdns.com.
26b86deb
RG
1235advanced.tests.powerdns.com.
1236tests.powerdns.com.
1237powerdns.com.
1238com.""")
1239
1240 time.sleep(5)
1241
1242 self.sendConsoleCommand("nodesSeen = {}")
1243 self.sendConsoleCommand("statNodeRespRing(visitor)")
1244 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1245 nodes = nodes.strip("\n")
4bfebc93 1246 self.assertEqual(nodes, """statnodesince.advanced.tests.powerdns.com.
26b86deb
RG
1247advanced.tests.powerdns.com.
1248tests.powerdns.com.
1249powerdns.com.
1250com.""")
1251
1252 self.sendConsoleCommand("nodesSeen = {}")
1253 self.sendConsoleCommand("statNodeRespRing(visitor, 5)")
1254 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1255 nodes = nodes.strip("\n")
4bfebc93 1256 self.assertEqual(nodes, """""")
26b86deb
RG
1257
1258 self.sendConsoleCommand("nodesSeen = {}")
1259 self.sendConsoleCommand("statNodeRespRing(visitor, 10)")
1260 nodes = self.sendConsoleCommand("str = '' for key,value in pairs(nodesSeen) do str = str..value..\"\\n\" end return str")
b4f23783 1261 nodes = nodes.strip("\n")
4bfebc93 1262 self.assertEqual(nodes, """statnodesince.advanced.tests.powerdns.com.
26b86deb
RG
1263advanced.tests.powerdns.com.
1264tests.powerdns.com.
1265powerdns.com.
1266com.""")
7caebbb2
RG
1267
1268class TestAdvancedRD(DNSDistTest):
1269
1270 _config_template = """
d3ec24f9 1271 addAction(RDRule(), RCodeAction(DNSRCode.REFUSED))
7caebbb2
RG
1272 newServer{address="127.0.0.1:%s"}
1273 """
1274
1275 def testAdvancedRDRefused(self):
1276 """
1277 Advanced: RD query is refused
1278 """
1279 name = 'rd.advanced.tests.powerdns.com.'
1280 query = dns.message.make_query(name, 'A', 'IN')
1281 expectedResponse = dns.message.make_response(query)
1282 expectedResponse.set_rcode(dns.rcode.REFUSED)
7af22479 1283 expectedResponse.flags |= dns.flags.RA
7caebbb2 1284
6ca2e796
RG
1285 for method in ("sendUDPQuery", "sendTCPQuery"):
1286 sender = getattr(self, method)
1287 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1288 self.assertEqual(receivedResponse, expectedResponse)
7caebbb2
RG
1289
1290 def testAdvancedNoRDAllowed(self):
1291 """
1292 Advanced: No-RD query is allowed
1293 """
1294 name = 'no-rd.advanced.tests.powerdns.com.'
1295 query = dns.message.make_query(name, 'A', 'IN')
1296 query.flags &= ~dns.flags.RD
1297 response = dns.message.make_response(query)
1298
6ca2e796
RG
1299 for method in ("sendUDPQuery", "sendTCPQuery"):
1300 sender = getattr(self, method)
1301 (receivedQuery, receivedResponse) = sender(query, response)
1302 receivedQuery.id = query.id
4bfebc93
CH
1303 self.assertEqual(receivedQuery, query)
1304 self.assertEqual(receivedResponse, response)
b052847c
RG
1305
1306class TestAdvancedGetLocalPort(DNSDistTest):
1307
1308 _config_template = """
1309 function answerBasedOnLocalPort(dq)
1310 local port = dq.localaddr:getPort()
1311 return DNSAction.Spoof, "port-was-"..port..".local-port.advanced.tests.powerdns.com."
1312 end
a2ff35e3 1313 addAction("local-port.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
b052847c
RG
1314 newServer{address="127.0.0.1:%s"}
1315 """
1316
1317 def testAdvancedGetLocalPort(self):
1318 """
1319 Advanced: Return CNAME containing the local port
1320 """
1321 name = 'local-port.advanced.tests.powerdns.com.'
1322 query = dns.message.make_query(name, 'A', 'IN')
1323 # dnsdist set RA = RD for spoofed responses
1324 query.flags &= ~dns.flags.RD
1325
1326 response = dns.message.make_response(query)
1327 rrset = dns.rrset.from_text(name,
1328 60,
1329 dns.rdataclass.IN,
1330 dns.rdatatype.CNAME,
1331 'port-was-{}.local-port.advanced.tests.powerdns.com.'.format(self._dnsDistPort))
1332 response.answer.append(rrset)
1333
6ca2e796
RG
1334 for method in ("sendUDPQuery", "sendTCPQuery"):
1335 sender = getattr(self, method)
1336 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1337 self.assertEqual(receivedResponse, response)
b052847c
RG
1338
1339class TestAdvancedGetLocalPortOnAnyBind(DNSDistTest):
1340
1341 _config_template = """
1342 function answerBasedOnLocalPort(dq)
1343 local port = dq.localaddr:getPort()
1344 return DNSAction.Spoof, "port-was-"..port..".local-port-any.advanced.tests.powerdns.com."
1345 end
a2ff35e3 1346 addAction("local-port-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalPort))
b052847c
RG
1347 newServer{address="127.0.0.1:%s"}
1348 """
1349 _dnsDistListeningAddr = "0.0.0.0"
1350
1351 def testAdvancedGetLocalPortOnAnyBind(self):
1352 """
1353 Advanced: Return CNAME containing the local port for an ANY bind
1354 """
1355 name = 'local-port-any.advanced.tests.powerdns.com.'
1356 query = dns.message.make_query(name, 'A', 'IN')
1357 # dnsdist set RA = RD for spoofed responses
1358 query.flags &= ~dns.flags.RD
1359
1360 response = dns.message.make_response(query)
1361 rrset = dns.rrset.from_text(name,
1362 60,
1363 dns.rdataclass.IN,
1364 dns.rdatatype.CNAME,
1365 'port-was-{}.local-port-any.advanced.tests.powerdns.com.'.format(self._dnsDistPort))
1366 response.answer.append(rrset)
1367
6ca2e796
RG
1368 for method in ("sendUDPQuery", "sendTCPQuery"):
1369 sender = getattr(self, method)
1370 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1371 self.assertEqual(receivedResponse, response)
29b6a412 1372
f93e2327
RG
1373class TestAdvancedGetLocalAddressOnAnyBind(DNSDistTest):
1374
1375 _config_template = """
1376 function answerBasedOnLocalAddress(dq)
207e77dd 1377 local dest = tostring(dq.localaddr)
f93e2327
RG
1378 local i, j = string.find(dest, "[0-9.]+")
1379 local addr = string.sub(dest, i, j)
1380 local dashAddr = string.gsub(addr, "[.]", "-")
1381 return DNSAction.Spoof, "address-was-"..dashAddr..".local-address-any.advanced.tests.powerdns.com."
1382 end
1383 addAction("local-address-any.advanced.tests.powerdns.com.", LuaAction(answerBasedOnLocalAddress))
1384 newServer{address="127.0.0.1:%s"}
1385 """
1386 _dnsDistListeningAddr = "0.0.0.0"
1387
1388 def testAdvancedGetLocalAddressOnAnyBind(self):
1389 """
1390 Advanced: Return CNAME containing the local address for an ANY bind
1391 """
1392 name = 'local-address-any.advanced.tests.powerdns.com.'
1393 query = dns.message.make_query(name, 'A', 'IN')
1394 # dnsdist set RA = RD for spoofed responses
1395 query.flags &= ~dns.flags.RD
1396
1397 response = dns.message.make_response(query)
1398 rrset = dns.rrset.from_text(name,
1399 60,
1400 dns.rdataclass.IN,
1401 dns.rdatatype.CNAME,
1402 'address-was-127-0-0-1.local-address-any.advanced.tests.powerdns.com.')
1403 response.answer.append(rrset)
1404
6ca2e796
RG
1405 for method in ("sendUDPQuery", "sendTCPQuery"):
1406 sender = getattr(self, method)
1407 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1408 self.assertEqual(receivedResponse, response)
f93e2327 1409
29b6a412
CH
1410class TestAdvancedLuaTempFailureTTL(DNSDistTest):
1411
1412 _config_template = """
1413 function testAction(dq)
1414 if dq.tempFailureTTL ~= nil then
1415 return DNSAction.Spoof, "initially.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1416 end
1417 dq.tempFailureTTL = 30
1418 if dq.tempFailureTTL ~= 30 then
1419 return DNSAction.Spoof, "after.set.not.expected.value.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1420 end
1421 dq.tempFailureTTL = nil
1422 if dq.tempFailureTTL ~= nil then
1423 return DNSAction.Spoof, "after.unset.not.nil.but." + dq.tempFailureTTL + ".tests.powerdns.com."
1424 end
1425 return DNSAction.None, ""
1426 end
1427 addAction(AllRule(), LuaAction(testAction))
1428 newServer{address="127.0.0.1:%s"}
1429 """
1430
1431 def testTempFailureTTLBinding(self):
1432 """
cdc2fb01 1433 Advanced: Exercise dq.tempFailureTTL Lua binding
29b6a412
CH
1434 """
1435 name = 'tempfailurettlbinding.advanced.tests.powerdns.com.'
1436 query = dns.message.make_query(name, 'A', 'IN')
1437 response = dns.message.make_response(query)
1438 rrset = dns.rrset.from_text(name,
1439 3600,
1440 dns.rdataclass.IN,
1441 dns.rdatatype.AAAA,
1442 '::1')
1443 response.answer.append(rrset)
1444
6ca2e796
RG
1445 for method in ("sendUDPQuery", "sendTCPQuery"):
1446 sender = getattr(self, method)
1447 (receivedQuery, receivedResponse) = sender(query, response)
1448 self.assertTrue(receivedQuery)
1449 self.assertTrue(receivedResponse)
1450 receivedQuery.id = query.id
4bfebc93
CH
1451 self.assertEqual(query, receivedQuery)
1452 self.assertEqual(receivedResponse, response)
4bfdbd34
PD
1453
1454class TestAdvancedEDNSOptionRule(DNSDistTest):
1455
1456 _config_template = """
1457 newServer{address="127.0.0.1:%s"}
6bb92a06 1458 addAction(EDNSOptionRule(EDNSOptionCode.ECS), DropAction())
4bfdbd34
PD
1459 """
1460
1461 def testDropped(self):
1462 """
cdc2fb01 1463 Advanced: A question with ECS is dropped
4bfdbd34
PD
1464 """
1465
1466 name = 'ednsoptionrule.advanced.tests.powerdns.com.'
1467
1468 ecso = clientsubnetoption.ClientSubnetOption('127.0.0.1', 24)
1469 query = dns.message.make_query(name, 'A', 'IN', use_edns=True, options=[ecso], payload=512)
1470
6ca2e796
RG
1471 for method in ("sendUDPQuery", "sendTCPQuery"):
1472 sender = getattr(self, method)
90186270 1473 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1474 self.assertEqual(receivedResponse, None)
4bfdbd34
PD
1475
1476 def testReplied(self):
1477 """
cdc2fb01 1478 Advanced: A question without ECS is answered
4bfdbd34
PD
1479 """
1480
1481 name = 'ednsoptionrule.advanced.tests.powerdns.com.'
1482
1483 # both with EDNS
1484 query = dns.message.make_query(name, 'A', 'IN', use_edns=True, options=[], payload=512)
1485 response = dns.message.make_response(query)
1486
6ca2e796
RG
1487 for method in ("sendUDPQuery", "sendTCPQuery"):
1488 sender = getattr(self, method)
1489 (receivedQuery, receivedResponse) = sender(query, response)
1490 self.assertTrue(receivedQuery)
1491 self.assertTrue(receivedResponse)
4bfdbd34 1492
6ca2e796 1493 receivedQuery.id = query.id
4bfebc93
CH
1494 self.assertEqual(query, receivedQuery)
1495 self.assertEqual(receivedResponse, response)
4bfdbd34
PD
1496
1497 # and with no EDNS at all
1498 query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
1499 response = dns.message.make_response(query)
1500
6ca2e796
RG
1501 for method in ("sendUDPQuery", "sendTCPQuery"):
1502 sender = getattr(self, method)
1503 (receivedQuery, receivedResponse) = sender(query, response)
1504 self.assertTrue(receivedQuery)
1505 self.assertTrue(receivedResponse)
4bfdbd34 1506
6ca2e796 1507 receivedQuery.id = query.id
4bfebc93
CH
1508 self.assertEqual(query, receivedQuery)
1509 self.assertEqual(receivedResponse, response)
bcc47804
RG
1510
1511class TestAdvancedAllowHeaderOnly(DNSDistTest):
1512
1513 _config_template = """
1514 newServer{address="127.0.0.1:%s"}
1515 setAllowEmptyResponse(true)
1516 """
1517
1518 def testHeaderOnlyRefused(self):
1519 """
1520 Advanced: Header-only refused response
1521 """
1522 name = 'header-only-refused-response.advanced.tests.powerdns.com.'
1523 query = dns.message.make_query(name, 'A', 'IN')
1524 response = dns.message.make_response(query)
1525 response.set_rcode(dns.rcode.REFUSED)
1526 response.question = []
1527
1528 for method in ("sendUDPQuery", "sendTCPQuery"):
1529 sender = getattr(self, method)
1530 (receivedQuery, receivedResponse) = sender(query, response)
1531 self.assertTrue(receivedQuery)
1532 receivedQuery.id = query.id
4bfebc93
CH
1533 self.assertEqual(query, receivedQuery)
1534 self.assertEqual(receivedResponse, response)
bcc47804
RG
1535
1536 def testHeaderOnlyNoErrorResponse(self):
1537 """
1538 Advanced: Header-only NoError response should be allowed
1539 """
1540 name = 'header-only-noerror-response.advanced.tests.powerdns.com.'
1541 query = dns.message.make_query(name, 'A', 'IN')
1542 response = dns.message.make_response(query)
1543 response.question = []
1544
1545 for method in ("sendUDPQuery", "sendTCPQuery"):
1546 sender = getattr(self, method)
1547 (receivedQuery, receivedResponse) = sender(query, response)
1548 self.assertTrue(receivedQuery)
1549 receivedQuery.id = query.id
4bfebc93
CH
1550 self.assertEqual(query, receivedQuery)
1551 self.assertEqual(receivedResponse, response)
bcc47804
RG
1552
1553 def testHeaderOnlyNXDResponse(self):
1554 """
1555 Advanced: Header-only NXD response should be allowed
1556 """
1557 name = 'header-only-nxd-response.advanced.tests.powerdns.com.'
1558 query = dns.message.make_query(name, 'A', 'IN')
1559 response = dns.message.make_response(query)
1560 response.set_rcode(dns.rcode.NXDOMAIN)
1561 response.question = []
1562
1563 for method in ("sendUDPQuery", "sendTCPQuery"):
1564 sender = getattr(self, method)
1565 (receivedQuery, receivedResponse) = sender(query, response)
1566 self.assertTrue(receivedQuery)
1567 receivedQuery.id = query.id
4bfebc93
CH
1568 self.assertEqual(query, receivedQuery)
1569 self.assertEqual(receivedResponse, response)
f61e6149 1570
6d83b8b1 1571class TestAdvancedEDNSVersionRule(DNSDistTest):
f61e6149
RG
1572
1573 _config_template = """
1574 newServer{address="127.0.0.1:%s"}
d3ec24f9 1575 addAction(EDNSVersionRule(0), ERCodeAction(DNSRCode.BADVERS))
f61e6149
RG
1576 """
1577
7af22479 1578 def testBadVers(self):
f61e6149 1579 """
7af22479 1580 Advanced: A question with ECS version larger than 0 yields BADVERS
f61e6149
RG
1581 """
1582
1583 name = 'ednsversionrule.advanced.tests.powerdns.com.'
1584
1585 query = dns.message.make_query(name, 'A', 'IN', use_edns=1)
7af22479 1586 query.flags &= ~dns.flags.RD
f61e6149
RG
1587 expectedResponse = dns.message.make_response(query)
1588 expectedResponse.set_rcode(dns.rcode.BADVERS)
1589
1590 for method in ("sendUDPQuery", "sendTCPQuery"):
1591 sender = getattr(self, method)
90186270 1592 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1593 self.assertEqual(receivedResponse, expectedResponse)
f61e6149
RG
1594
1595 def testNoEDNS0Pass(self):
1596 """
1597 Advanced: A question with ECS version 0 goes through
1598 """
1599
1600 name = 'ednsversionrule.advanced.tests.powerdns.com.'
1601
1602 query = dns.message.make_query(name, 'A', 'IN', use_edns=True)
1603 response = dns.message.make_response(query)
1604
1605 for method in ("sendUDPQuery", "sendTCPQuery"):
1606 sender = getattr(self, method)
1607 (receivedQuery, receivedResponse) = sender(query, response)
1608 receivedQuery.id = query.id
4bfebc93
CH
1609 self.assertEqual(query, receivedQuery)
1610 self.assertEqual(receivedResponse, response)
f61e6149
RG
1611
1612 def testReplied(self):
1613 """
1614 Advanced: A question without ECS goes through
1615 """
1616
1617 name = 'ednsoptionrule.advanced.tests.powerdns.com.'
1618
1619 query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
1620 response = dns.message.make_response(query)
1621
1622 for method in ("sendUDPQuery", "sendTCPQuery"):
1623 sender = getattr(self, method)
1624 (receivedQuery, receivedResponse) = sender(query, response)
1625 receivedQuery.id = query.id
4bfebc93
CH
1626 self.assertEqual(query, receivedQuery)
1627 self.assertEqual(receivedResponse, response)
488fd7c8
RG
1628
1629class TestSetRules(DNSDistTest):
1630
1631 _consoleKey = DNSDistTest.generateConsoleKey()
1632 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
1633 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort']
1634 _config_template = """
1635 setKey("%s")
1636 controlSocket("127.0.0.1:%s")
1637 newServer{address="127.0.0.1:%s"}
1638 addAction(AllRule(), SpoofAction("192.0.2.1"))
1639 """
1640
1641 def testClearThenSetRules(self):
1642 """
1643 Advanced: Clear rules, set rules
1644
1645 """
1646 name = 'clearthensetrules.advanced.tests.powerdns.com.'
1647 query = dns.message.make_query(name, 'A', 'IN')
1648 # dnsdist set RA = RD for spoofed responses
1649 query.flags &= ~dns.flags.RD
1650 expectedResponse = dns.message.make_response(query)
1651 rrset = dns.rrset.from_text(name,
1652 60,
1653 dns.rdataclass.IN,
1654 dns.rdatatype.A,
1655 '192.0.2.1')
1656 expectedResponse.answer.append(rrset)
1657
1658 for method in ("sendUDPQuery", "sendTCPQuery"):
1659 sender = getattr(self, method)
1660
1661 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1662 self.assertTrue(receivedResponse)
4bfebc93 1663 self.assertEqual(expectedResponse, receivedResponse)
488fd7c8
RG
1664
1665 # clear all the rules, we should not be spoofing and get a SERVFAIL from the responder instead
1666 self.sendConsoleCommand("clearRules()")
1667
1668 expectedResponse = dns.message.make_response(query)
1669 expectedResponse.set_rcode(dns.rcode.SERVFAIL)
1670
1671 for method in ("sendUDPQuery", "sendTCPQuery"):
1672 sender = getattr(self, method)
1673
1674 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1675 self.assertTrue(receivedResponse)
4bfebc93 1676 self.assertEqual(expectedResponse, receivedResponse)
488fd7c8
RG
1677
1678 # insert a new spoofing rule
1679 self.sendConsoleCommand("setRules({ newRuleAction(AllRule(), SpoofAction(\"192.0.2.2\")) })")
1680
1681 expectedResponse = dns.message.make_response(query)
1682 rrset = dns.rrset.from_text(name,
1683 60,
1684 dns.rdataclass.IN,
1685 dns.rdatatype.A,
1686 '192.0.2.2')
1687 expectedResponse.answer.append(rrset)
1688
1689 for method in ("sendUDPQuery", "sendTCPQuery"):
1690 sender = getattr(self, method)
1691
1692 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1693 self.assertTrue(receivedResponse)
4bfebc93 1694 self.assertEqual(expectedResponse, receivedResponse)
2a28db86
RG
1695
1696class TestAdvancedContinueAction(DNSDistTest):
1697
1698 _config_template = """
1699 newServer{address="127.0.0.1:%s", pool="mypool"}
1700 addAction("nocontinue.continue-action.advanced.tests.powerdns.com.", PoolAction("mypool"))
1701 addAction("continue.continue-action.advanced.tests.powerdns.com.", ContinueAction(PoolAction("mypool")))
198d8159 1702 addAction(AllRule(), SetDisableValidationAction())
2a28db86
RG
1703 """
1704
1705 def testNoContinue(self):
1706 """
1707 Advanced: Query routed to pool, PoolAction should be terminal
1708 """
1709
1710 name = 'nocontinue.continue-action.advanced.tests.powerdns.com.'
1711
1712 query = dns.message.make_query(name, 'A', 'IN')
1713 expectedQuery = dns.message.make_query(name, 'A', 'IN')
1714
1715 response = dns.message.make_response(query)
1716 expectedResponse = dns.message.make_response(query)
1717
1718 for method in ("sendUDPQuery", "sendTCPQuery"):
1719 sender = getattr(self, method)
1720 (receivedQuery, receivedResponse) = sender(query, response)
4bfebc93
CH
1721 self.assertEqual(receivedQuery, expectedQuery)
1722 self.assertEqual(receivedResponse, expectedResponse)
2a28db86
RG
1723
1724 def testNoContinue(self):
1725 """
1726 Advanced: Query routed to pool, ContinueAction() should not stop the processing
1727 """
1728
1729 name = 'continue.continue-action.advanced.tests.powerdns.com.'
1730
1731 query = dns.message.make_query(name, 'A', 'IN')
1732 expectedQuery = dns.message.make_query(name, 'A', 'IN')
1733 expectedQuery.flags |= dns.flags.CD
1734
1735 response = dns.message.make_response(query)
1736 expectedResponse = dns.message.make_response(query)
1737
1738 for method in ("sendUDPQuery", "sendTCPQuery"):
1739 sender = getattr(self, method)
1740 (receivedQuery, receivedResponse) = sender(query, response)
1741 expectedQuery.id = receivedQuery.id
4bfebc93
CH
1742 self.assertEqual(receivedQuery, expectedQuery)
1743 self.assertEqual(receivedResponse, expectedResponse)
af9f750c 1744
198d8159 1745class TestAdvancedNegativeAndSOA(DNSDistTest):
af9f750c 1746
6e1f856f 1747 _selfGeneratedPayloadSize = 1232
af9f750c 1748 _config_template = """
198d8159
RG
1749 addAction("nxd.negativeandsoa.advanced.tests.powerdns.com.", NegativeAndSOAAction(true, "auth.", 42, "mname", "rname", 5, 4, 3, 2, 1))
1750 addAction("nodata.negativeandsoa.advanced.tests.powerdns.com.", NegativeAndSOAAction(false, "another-auth.", 42, "mname", "rname", 1, 2, 3, 4, 5))
6e1f856f 1751 setPayloadSizeOnSelfGeneratedAnswers(%d)
af9f750c
RG
1752 newServer{address="127.0.0.1:%s"}
1753 """
6e1f856f
RG
1754 _config_params = ['_selfGeneratedPayloadSize', '_testServerPort']
1755
af9f750c
RG
1756
1757 def testAdvancedNegativeAndSOANXD(self):
1758 """
198d8159 1759 Advanced: NegativeAndSOAAction NXD
af9f750c 1760 """
198d8159 1761 name = 'nxd.negativeandsoa.advanced.tests.powerdns.com.'
6e1f856f
RG
1762 # no EDNS
1763 query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
ba572120 1764 query.flags &= ~dns.flags.RD
af9f750c
RG
1765 expectedResponse = dns.message.make_response(query)
1766 expectedResponse.set_rcode(dns.rcode.NXDOMAIN)
6e1f856f 1767 soa = dns.rrset.from_text("auth.",
af9f750c
RG
1768 42,
1769 dns.rdataclass.IN,
1770 dns.rdatatype.SOA,
1771 'mname. rname. 5 4 3 2 1')
1772 expectedResponse.additional.append(soa)
1773
1774 for method in ("sendUDPQuery", "sendTCPQuery"):
1775 sender = getattr(self, method)
1776 (_, receivedResponse) = sender(query, response=None, useQueue=False)
6e1f856f
RG
1777 self.checkMessageNoEDNS(expectedResponse, receivedResponse)
1778
1779 # withEDNS
1780 query = dns.message.make_query(name, 'A', 'IN', use_edns=True)
1781 query.flags &= ~dns.flags.RD
1782 expectedResponse = dns.message.make_response(query, our_payload=self._selfGeneratedPayloadSize)
1783 expectedResponse.set_rcode(dns.rcode.NXDOMAIN)
1784 soa = dns.rrset.from_text("auth.",
1785 42,
1786 dns.rdataclass.IN,
1787 dns.rdatatype.SOA,
1788 'mname. rname. 5 4 3 2 1')
1789 expectedResponse.additional.append(soa)
1790
1791 for method in ("sendUDPQuery", "sendTCPQuery"):
1792 sender = getattr(self, method)
1793 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1794 self.checkMessageEDNSWithoutOptions(expectedResponse, receivedResponse)
af9f750c
RG
1795
1796 def testAdvancedNegativeAndSOANoData(self):
1797 """
198d8159 1798 Advanced: NegativeAndSOAAction NoData
af9f750c 1799 """
198d8159 1800 name = 'nodata.negativeandsoa.advanced.tests.powerdns.com.'
6e1f856f
RG
1801 # no EDNS
1802 query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
ba572120 1803 query.flags &= ~dns.flags.RD
af9f750c
RG
1804 expectedResponse = dns.message.make_response(query)
1805 expectedResponse.set_rcode(dns.rcode.NOERROR)
6e1f856f 1806 soa = dns.rrset.from_text("another-auth.",
af9f750c
RG
1807 42,
1808 dns.rdataclass.IN,
1809 dns.rdatatype.SOA,
1810 'mname. rname. 1 2 3 4 5')
1811 expectedResponse.additional.append(soa)
1812
1813 for method in ("sendUDPQuery", "sendTCPQuery"):
1814 sender = getattr(self, method)
1815 (_, receivedResponse) = sender(query, response=None, useQueue=False)
6e1f856f
RG
1816 self.checkMessageNoEDNS(expectedResponse, receivedResponse)
1817
1818 # with EDNS
1819 query = dns.message.make_query(name, 'A', 'IN', use_edns=True)
1820 query.flags &= ~dns.flags.RD
1821 expectedResponse = dns.message.make_response(query, our_payload=self._selfGeneratedPayloadSize)
1822 expectedResponse.set_rcode(dns.rcode.NOERROR)
1823 soa = dns.rrset.from_text("another-auth.",
1824 42,
1825 dns.rdataclass.IN,
1826 dns.rdatatype.SOA,
1827 'mname. rname. 1 2 3 4 5')
1828 expectedResponse.additional.append(soa)
1829
1830 for method in ("sendUDPQuery", "sendTCPQuery"):
1831 sender = getattr(self, method)
1832 (_, receivedResponse) = sender(query, response=None, useQueue=False)
1833 self.checkMessageEDNSWithoutOptions(expectedResponse, receivedResponse)
b774d943 1834
8eb84a56
RG
1835class TestAdvancedLuaRule(DNSDistTest):
1836
1837 _config_template = """
1838
1839 function luarulefunction(dq)
acf16adc 1840 if dq:getTag('a-tag') ~= 'a-value' then
1841 print('invalid tag value')
1842 return false
8eb84a56 1843 end
acf16adc 1844
207e77dd 1845 if tostring(dq.qname) ~= 'lua-rule.advanced.tests.powerdns.com.' then
acf16adc 1846 print('invalid qname')
1847 return false
1848 end
1849
1850 return true
8eb84a56
RG
1851 end
1852
198d8159 1853 addAction(AllRule(), SetTagAction('a-tag', 'a-value'))
8eb84a56
RG
1854 addAction(LuaRule(luarulefunction), RCodeAction(DNSRCode.NOTIMP))
1855 addAction(AllRule(), RCodeAction(DNSRCode.REFUSED))
1856 -- newServer{address="127.0.0.1:%s"}
1857 """
1858
1859 def testAdvancedLuaRule(self):
1860 """
1861 Advanced: Test the LuaRule rule
1862 """
1863 name = 'lua-rule.advanced.tests.powerdns.com.'
1864 query = dns.message.make_query(name, 'A', 'IN')
1865 # dnsdist set RA = RD for spoofed responses
1866 query.flags &= ~dns.flags.RD
1867 notimplResponse = dns.message.make_response(query)
1868 notimplResponse.set_rcode(dns.rcode.NOTIMP)
1869
1870 for method in ("sendUDPQuery", "sendTCPQuery"):
1871 sender = getattr(self, method)
1872 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1873 self.assertEqual(receivedResponse, notimplResponse)
8eb84a56
RG
1874
1875 name = 'not-lua-rule.advanced.tests.powerdns.com.'
1876 query = dns.message.make_query(name, 'A', 'IN')
1877 # dnsdist set RA = RD for spoofed responses
1878 query.flags &= ~dns.flags.RD
1879 refusedResponse = dns.message.make_response(query)
1880 refusedResponse.set_rcode(dns.rcode.REFUSED)
1881
1882 for method in ("sendUDPQuery", "sendTCPQuery"):
1883 sender = getattr(self, method)
1884 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 1885 self.assertEqual(receivedResponse, refusedResponse)
8eb84a56 1886
b774d943
RG
1887class TestAdvancedLuaFFI(DNSDistTest):
1888
1889 _config_template = """
1890 local ffi = require("ffi")
1891
b774d943
RG
1892 local expectingUDP = true
1893
1894 function luaffirulefunction(dq)
1895 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
1896 if qtype ~= DNSQType.A and qtype ~= DNSQType.SOA then
1897 print('invalid qtype')
1898 return false
1899 end
1900
1901 local qclass = ffi.C.dnsdist_ffi_dnsquestion_get_qclass(dq)
1902 if qclass ~= DNSClass.IN then
1903 print('invalid qclass')
1904 return false
1905 end
1906
1907 local ret_ptr = ffi.new("char *[1]")
1908 local ret_ptr_param = ffi.cast("const char **", ret_ptr)
1909 local ret_size = ffi.new("size_t[1]")
1910 local ret_size_param = ffi.cast("size_t*", ret_size)
1911 ffi.C.dnsdist_ffi_dnsquestion_get_qname_raw(dq, ret_ptr_param, ret_size_param)
1912 if ret_size[0] ~= 36 then
1913 print('invalid length for the qname ')
1914 print(ret_size[0])
1915 return false
1916 end
1917
1918 local expectedQname = string.char(6)..'luaffi'..string.char(8)..'advanced'..string.char(5)..'tests'..string.char(8)..'powerdns'..string.char(3)..'com'
1919 if ffi.string(ret_ptr[0]) ~= expectedQname then
1920 print('invalid qname')
1921 print(ffi.string(ret_ptr[0]))
1922 return false
1923 end
1924
1925 local rcode = ffi.C.dnsdist_ffi_dnsquestion_get_rcode(dq)
1926 if rcode ~= 0 then
1927 print('invalid rcode')
1928 return false
1929 end
1930
1931 local opcode = ffi.C.dnsdist_ffi_dnsquestion_get_opcode(dq)
1932 if qtype == DNSQType.A and opcode ~= DNSOpcode.Query then
1933 print('invalid opcode')
1934 return false
1935 elseif qtype == DNSQType.SOA and opcode ~= DNSOpcode.Update then
1936 print('invalid opcode')
1937 return false
1938 end
1939
1940 local tcp = ffi.C.dnsdist_ffi_dnsquestion_get_tcp(dq)
1941 if expectingUDP == tcp then
1942 print('invalid tcp')
1943 return false
1944 end
1945 expectingUDP = expectingUDP == false
1946
1947 local dnssecok = ffi.C.dnsdist_ffi_dnsquestion_get_do(dq)
1948 if dnssecok ~= false then
1949 print('invalid DNSSEC OK')
1950 return false
1951 end
1952
1953 local len = ffi.C.dnsdist_ffi_dnsquestion_get_len(dq)
1954 if len ~= 52 then
1955 print('invalid length')
1956 print(len)
1957 return false
1958 end
1959
f7e6a5ce
RG
1960 local tag = ffi.C.dnsdist_ffi_dnsquestion_get_tag(dq, 'a-tag')
1961 if ffi.string(tag) ~= 'a-value' then
1962 print('invalid tag value')
1963 print(ffi.string(tag))
1964 return false
1965 end
b774d943
RG
1966 return true
1967 end
1968
1969 function luaffiactionfunction(dq)
1970 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
1971 if qtype == DNSQType.A then
1972 local str = "192.0.2.1"
1973 local buf = ffi.new("char[?]", #str + 1)
1974 ffi.copy(buf, str)
1975 ffi.C.dnsdist_ffi_dnsquestion_set_result(dq, buf, #str)
1976 return DNSAction.Spoof
1977 elseif qtype == DNSQType.SOA then
1978 ffi.C.dnsdist_ffi_dnsquestion_set_rcode(dq, DNSRCode.REFUSED)
1979 return DNSAction.Refused
1980 end
1981 end
1982
f7e6a5ce
RG
1983 function luaffiactionsettag(dq)
1984 ffi.C.dnsdist_ffi_dnsquestion_set_tag(dq, 'a-tag', 'a-value')
1985 return DNSAction.None
1986 end
1987
1988 addAction(AllRule(), LuaFFIAction(luaffiactionsettag))
b774d943
RG
1989 addAction(LuaFFIRule(luaffirulefunction), LuaFFIAction(luaffiactionfunction))
1990 -- newServer{address="127.0.0.1:%s"}
1991 """
1992
1993 def testAdvancedLuaFFI(self):
1994 """
1995 Advanced: Test the Lua FFI interface
1996 """
1997 name = 'luaffi.advanced.tests.powerdns.com.'
1998 query = dns.message.make_query(name, 'A', 'IN')
1999 # dnsdist set RA = RD for spoofed responses
2000 query.flags &= ~dns.flags.RD
2001
2002 response = dns.message.make_response(query)
2003 rrset = dns.rrset.from_text(name,
2004 60,
2005 dns.rdataclass.IN,
2006 dns.rdatatype.A,
2007 '192.0.2.1')
2008 response.answer.append(rrset)
2009
2010 for method in ("sendUDPQuery", "sendTCPQuery"):
2011 sender = getattr(self, method)
2012 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 2013 self.assertEqual(receivedResponse, response)
b774d943
RG
2014
2015 def testAdvancedLuaFFIUpdate(self):
2016 """
2017 Advanced: Test the Lua FFI interface via an update
2018 """
2019 name = 'luaffi.advanced.tests.powerdns.com.'
2020 query = dns.message.make_query(name, 'SOA', 'IN')
2021 query.set_opcode(dns.opcode.UPDATE)
2022 # dnsdist set RA = RD for spoofed responses
2023 query.flags &= ~dns.flags.RD
2024
2025 response = dns.message.make_response(query)
2026 response.set_rcode(dns.rcode.REFUSED)
2027
2028 for method in ("sendUDPQuery", "sendTCPQuery"):
2029 sender = getattr(self, method)
2030 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 2031 self.assertEqual(receivedResponse, response)
9a872eb7 2032
79ac0575
RG
2033class TestAdvancedLuaFFIPerThread(DNSDistTest):
2034
2035 _config_template = """
2036
2037 local rulefunction = [[
2038 local ffi = require("ffi")
2039
2040 return function(dq)
2041 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
2042 if qtype ~= DNSQType.A and qtype ~= DNSQType.SOA then
2043 print('invalid qtype')
2044 return false
2045 end
2046
2047 local qclass = ffi.C.dnsdist_ffi_dnsquestion_get_qclass(dq)
2048 if qclass ~= DNSClass.IN then
2049 print('invalid qclass')
2050 return false
2051 end
2052
2053 local ret_ptr = ffi.new("char *[1]")
2054 local ret_ptr_param = ffi.cast("const char **", ret_ptr)
2055 local ret_size = ffi.new("size_t[1]")
2056 local ret_size_param = ffi.cast("size_t*", ret_size)
2057 ffi.C.dnsdist_ffi_dnsquestion_get_qname_raw(dq, ret_ptr_param, ret_size_param)
2058 if ret_size[0] ~= 45 then
2059 print('invalid length for the qname ')
2060 print(ret_size[0])
2061 return false
2062 end
2063
2064 local expectedQname = string.char(15)..'luaffiperthread'..string.char(8)..'advanced'..string.char(5)..'tests'..string.char(8)..'powerdns'..string.char(3)..'com'
2065 if ffi.string(ret_ptr[0]) ~= expectedQname then
2066 print('invalid qname')
2067 print(ffi.string(ret_ptr[0]))
2068 return false
2069 end
2070
2071 local rcode = ffi.C.dnsdist_ffi_dnsquestion_get_rcode(dq)
2072 if rcode ~= 0 then
2073 print('invalid rcode')
2074 return false
2075 end
2076
2077 local opcode = ffi.C.dnsdist_ffi_dnsquestion_get_opcode(dq)
2078 if qtype == DNSQType.A and opcode ~= DNSOpcode.Query then
2079 print('invalid opcode')
2080 return false
2081 elseif qtype == DNSQType.SOA and opcode ~= DNSOpcode.Update then
2082 print('invalid opcode')
2083 return false
2084 end
2085
2086 local dnssecok = ffi.C.dnsdist_ffi_dnsquestion_get_do(dq)
2087 if dnssecok ~= false then
2088 print('invalid DNSSEC OK')
2089 return false
2090 end
2091
2092 local len = ffi.C.dnsdist_ffi_dnsquestion_get_len(dq)
2093 if len ~= 61 then
2094 print('invalid length')
2095 print(len)
2096 return false
2097 end
2098
2099 local tag = ffi.C.dnsdist_ffi_dnsquestion_get_tag(dq, 'a-tag')
2100 if ffi.string(tag) ~= 'a-value' then
2101 print('invalid tag value')
2102 print(ffi.string(tag))
2103 return false
2104 end
2105
2106 return true
2107 end
2108 ]]
2109
2110 local actionfunction = [[
2111 local ffi = require("ffi")
2112
2113 return function(dq)
2114 local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
2115 if qtype == DNSQType.A then
2116 local str = "192.0.2.1"
2117 local buf = ffi.new("char[?]", #str + 1)
2118 ffi.copy(buf, str)
2119 ffi.C.dnsdist_ffi_dnsquestion_set_result(dq, buf, #str)
2120 return DNSAction.Spoof
2121 elseif qtype == DNSQType.SOA then
2122 ffi.C.dnsdist_ffi_dnsquestion_set_rcode(dq, DNSRCode.REFUSED)
2123 return DNSAction.Refused
2124 end
2125 end
2126 ]]
2127
2128 local settagfunction = [[
2129 local ffi = require("ffi")
2130
2131 return function(dq)
2132 ffi.C.dnsdist_ffi_dnsquestion_set_tag(dq, 'a-tag', 'a-value')
2133 return DNSAction.None
2134 end
2135 ]]
2136
2137 addAction(AllRule(), LuaFFIPerThreadAction(settagfunction))
2138 addAction(LuaFFIPerThreadRule(rulefunction), LuaFFIPerThreadAction(actionfunction))
2139 -- newServer{address="127.0.0.1:%s"}
2140 """
2141
2142 def testAdvancedLuaPerthreadFFI(self):
2143 """
2144 Advanced: Test the Lua FFI per-thread interface
2145 """
2146 name = 'luaffiperthread.advanced.tests.powerdns.com.'
2147 query = dns.message.make_query(name, 'A', 'IN')
2148 # dnsdist set RA = RD for spoofed responses
2149 query.flags &= ~dns.flags.RD
2150
2151 response = dns.message.make_response(query)
2152 rrset = dns.rrset.from_text(name,
2153 60,
2154 dns.rdataclass.IN,
2155 dns.rdatatype.A,
2156 '192.0.2.1')
2157 response.answer.append(rrset)
2158
2159 for method in ("sendUDPQuery", "sendTCPQuery"):
2160 sender = getattr(self, method)
2161 (_, receivedResponse) = sender(query, response=None, useQueue=False)
2162 self.assertEqual(receivedResponse, response)
2163
2164 def testAdvancedLuaFFIPerThreadUpdate(self):
2165 """
2166 Advanced: Test the Lua FFI per-thread interface via an update
2167 """
2168 name = 'luaffiperthread.advanced.tests.powerdns.com.'
2169 query = dns.message.make_query(name, 'SOA', 'IN')
2170 query.set_opcode(dns.opcode.UPDATE)
b774d943
RG
2171 # dnsdist set RA = RD for spoofed responses
2172 query.flags &= ~dns.flags.RD
2173
2174 response = dns.message.make_response(query)
2175 response.set_rcode(dns.rcode.REFUSED)
2176
2177 for method in ("sendUDPQuery", "sendTCPQuery"):
2178 sender = getattr(self, method)
2179 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 2180 self.assertEqual(receivedResponse, response)
9a872eb7
RG
2181
2182class TestAdvancedDropEmptyQueries(DNSDistTest):
2183
2184 _config_template = """
2185 setDropEmptyQueries(true)
2186 newServer{address="127.0.0.1:%s"}
2187 """
2188
2189 def testAdvancedDropEmptyQueries(self):
2190 """
2191 Advanced: Drop empty queries
2192 """
2193 name = 'drop-empty-queries.advanced.tests.powerdns.com.'
2194 query = dns.message.Message()
2195
2196 for method in ("sendUDPQuery", "sendTCPQuery"):
2197 sender = getattr(self, method)
2198 (_, receivedResponse) = sender(query, response=None, useQueue=False)
4bfebc93 2199 self.assertEqual(receivedResponse, None)
7d808ff4
RG
2200
2201class TestProtocols(DNSDistTest):
2202 _config_template = """
2203 function checkUDP(dq)
2204 if dq:getProtocol() ~= "Do53 UDP" then
2205 return DNSAction.Spoof, '1.2.3.4'
2206 end
2207 return DNSAction.None
2208 end
2209
2210 function checkTCP(dq)
2211 if dq:getProtocol() ~= "Do53 TCP" then
2212 return DNSAction.Spoof, '1.2.3.4'
2213 end
2214 return DNSAction.None
2215 end
2216
2217 addAction("udp.protocols.advanced.tests.powerdns.com.", LuaAction(checkUDP))
2218 addAction("tcp.protocols.advanced.tests.powerdns.com.", LuaAction(checkTCP))
2219 newServer{address="127.0.0.1:%s"}
2220 """
2221
2222 def testProtocolUDP(self):
2223 """
2224 Advanced: Test DNSQuestion.Protocol over UDP
2225 """
2226 name = 'udp.protocols.advanced.tests.powerdns.com.'
2227 query = dns.message.make_query(name, 'A', 'IN')
2228 response = dns.message.make_response(query)
2229
2230 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
2231 receivedQuery.id = query.id
2232 self.assertEqual(receivedQuery, query)
2233 self.assertEqual(receivedResponse, response)
2234
2235 def testProtocolTCP(self):
2236 """
2237 Advanced: Test DNSQuestion.Protocol over TCP
2238 """
2239 name = 'tcp.protocols.advanced.tests.powerdns.com.'
2240 query = dns.message.make_query(name, 'A', 'IN')
2241 response = dns.message.make_response(query)
2242
2243 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
2244 receivedQuery.id = query.id
2245 self.assertEqual(receivedQuery, query)
2246 self.assertEqual(receivedResponse, response)
346410cd
CHB
2247
2248class TestAdvancedSetEDNSOptionAction(DNSDistTest):
2249
2250 _config_template = """
670e6761 2251 addAction(AllRule(), SetEDNSOptionAction(10, "deadbeefdeadc0de"))
346410cd
CHB
2252 newServer{address="127.0.0.1:%s"}
2253 """
2254
2255 def testAdvancedSetEDNSOption(self):
2256 """
2257 Advanced: Set EDNS Option
2258 """
2259 name = 'setednsoption.advanced.tests.powerdns.com.'
2260 query = dns.message.make_query(name, 'A', 'IN')
2261
2262 eco = cookiesoption.CookiesOption(b'deadbeef', b'deadc0de')
2263 expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=512, options=[eco])
2264
2265 response = dns.message.make_response(query)
2266 rrset = dns.rrset.from_text(name,
2267 3600,
2268 dns.rdataclass.IN,
2269 dns.rdatatype.A,
2270 '127.0.0.1')
2271 response.answer.append(rrset)
2272
2273 for method in ("sendUDPQuery", "sendTCPQuery"):
2274 sender = getattr(self, method)
2275 (receivedQuery, receivedResponse) = sender(query, response)
2276 self.assertTrue(receivedQuery)
2277 self.assertTrue(receivedResponse)
2278 receivedQuery.id = expectedQuery.id
2279 self.assertEqual(expectedQuery, receivedQuery)
ede92d2e 2280 self.checkResponseNoEDNS(response, receivedResponse)
346410cd 2281 self.checkQueryEDNS(expectedQuery, receivedQuery)
670e6761
RG
2282
2283 def testAdvancedSetEDNSOptionOverwrite(self):
2284 """
2285 Advanced: Set EDNS Option overwrites an existing option
2286 """
2287 name = 'setednsoption-overwrite.advanced.tests.powerdns.com.'
2288 initialECO = cookiesoption.CookiesOption(b'aaaaaaaa', b'bbbbbbbb')
2289 query = dns.message.make_query(name, 'A', 'IN')
2290
2291 overWrittenECO = cookiesoption.CookiesOption(b'deadbeef', b'deadc0de')
2292 expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=512, options=[overWrittenECO])
2293
2294 response = dns.message.make_response(query)
2295 rrset = dns.rrset.from_text(name,
2296 3600,
2297 dns.rdataclass.IN,
2298 dns.rdatatype.A,
2299 '127.0.0.1')
2300 response.answer.append(rrset)
2301
2302 for method in ("sendUDPQuery", "sendTCPQuery"):
2303 sender = getattr(self, method)
2304 (receivedQuery, receivedResponse) = sender(query, response)
2305 self.assertTrue(receivedQuery)
2306 self.assertTrue(receivedResponse)
2307 receivedQuery.id = expectedQuery.id
2308 self.assertEqual(expectedQuery, receivedQuery)
2309 self.checkResponseNoEDNS(response, receivedResponse)
2310 self.checkQueryEDNS(expectedQuery, receivedQuery)