]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_AXFR.py
Meson: Separate test files from common files
[thirdparty/pdns.git] / regression-tests.dnsdist / test_AXFR.py
1 #!/usr/bin/env python
2 import threading
3 import time
4 import dns
5 from dnsdisttests import DNSDistTest, pickAvailablePort
6
7 class TestAXFR(DNSDistTest):
8
9 # this test suite uses a different responder port
10 # because, contrary to the other ones, its
11 # TCP responder allows multiple responses and we don't want
12 # to mix things up.
13 _testServerPort = pickAvailablePort()
14 _config_template = """
15 newServer{address="127.0.0.1:%s"}
16 """
17 _verboseMode = True
18
19 @classmethod
20 def startResponders(cls):
21 print("Launching responders..")
22
23 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
24 cls._UDPResponder.daemon = True
25 cls._UDPResponder.start()
26 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, True, None, None, True])
27 cls._TCPResponder.daemon = True
28 cls._TCPResponder.start()
29
30 def setUp(self):
31 # This function is called before every test
32 super(TestAXFR, self).setUp()
33 # make sure the TCP connection handlers from the previous test
34 # are not going to read our queue
35 time.sleep(1)
36
37 def testOneMessageAXFR(self):
38 """
39 AXFR: One message
40 """
41 name = 'one.axfr.tests.powerdns.com.'
42 query = dns.message.make_query(name, 'AXFR', 'IN')
43 response = dns.message.make_response(query)
44 soa = dns.rrset.from_text(name,
45 60,
46 dns.rdataclass.IN,
47 dns.rdatatype.SOA,
48 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
49 response.answer.append(soa)
50 response.answer.append(dns.rrset.from_text(name,
51 60,
52 dns.rdataclass.IN,
53 dns.rdatatype.A,
54 '192.0.2.1'))
55 response.answer.append(soa)
56
57 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
58 receivedQuery.id = query.id
59 self.assertEqual(query, receivedQuery)
60 self.assertEqual(response, receivedResponse)
61
62 def testOneNoSOAAXFR(self):
63 """
64 AXFR: One message, no SOA
65 """
66 name = 'onenosoa.axfr.tests.powerdns.com.'
67 query = dns.message.make_query(name, 'AXFR', 'IN')
68 response = dns.message.make_response(query)
69 response.answer.append(dns.rrset.from_text(name,
70 60,
71 dns.rdataclass.IN,
72 dns.rdatatype.A,
73 '192.0.2.1'))
74
75 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
76 receivedQuery.id = query.id
77 self.assertEqual(query, receivedQuery)
78 self.assertEqual(response, receivedResponse)
79
80 def testFourMessagesAXFR(self):
81 """
82 AXFR: Four messages
83 """
84 name = 'four.axfr.tests.powerdns.com.'
85 query = dns.message.make_query(name, 'AXFR', 'IN')
86 responses = []
87 soa = dns.rrset.from_text(name,
88 60,
89 dns.rdataclass.IN,
90 dns.rdatatype.SOA,
91 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
92 response = dns.message.make_response(query)
93 response.answer.append(soa)
94 responses.append(response)
95
96 response = dns.message.make_response(query)
97 response.answer.append(dns.rrset.from_text(name,
98 60,
99 dns.rdataclass.IN,
100 dns.rdatatype.A,
101 '192.0.2.1'))
102 responses.append(response)
103
104 response = dns.message.make_response(query)
105 rrset = dns.rrset.from_text(name,
106 60,
107 dns.rdataclass.IN,
108 dns.rdatatype.AAAA,
109 '2001:DB8::1')
110 response.answer.append(rrset)
111 responses.append(response)
112
113 response = dns.message.make_response(query)
114 rrset = dns.rrset.from_text(name,
115 60,
116 dns.rdataclass.IN,
117 dns.rdatatype.TXT,
118 'dummy')
119 response.answer.append(rrset)
120 responses.append(response)
121
122 response = dns.message.make_response(query)
123 response.answer.append(soa)
124 responses.append(response)
125
126 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
127 receivedQuery.id = query.id
128 self.assertEqual(query, receivedQuery)
129 self.assertEqual(len(receivedResponses), len(responses))
130
131 def testFourNoFinalSOAAXFR(self):
132 """
133 AXFR: Four messages, no final SOA
134 """
135 name = 'fournosoa.axfr.tests.powerdns.com.'
136 query = dns.message.make_query(name, 'AXFR', 'IN')
137 responses = []
138 soa = dns.rrset.from_text(name,
139 60,
140 dns.rdataclass.IN,
141 dns.rdatatype.SOA,
142 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
143 response = dns.message.make_response(query)
144 response.answer.append(soa)
145 responses.append(response)
146
147 response = dns.message.make_response(query)
148 response.answer.append(dns.rrset.from_text(name,
149 60,
150 dns.rdataclass.IN,
151 dns.rdatatype.A,
152 '192.0.2.1'))
153 responses.append(response)
154
155 response = dns.message.make_response(query)
156 rrset = dns.rrset.from_text(name,
157 60,
158 dns.rdataclass.IN,
159 dns.rdatatype.AAAA,
160 '2001:DB8::1')
161 response.answer.append(rrset)
162 responses.append(response)
163
164 response = dns.message.make_response(query)
165 rrset = dns.rrset.from_text(name,
166 60,
167 dns.rdataclass.IN,
168 dns.rdatatype.TXT,
169 'dummy')
170 response.answer.append(rrset)
171 responses.append(response)
172
173 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
174 receivedQuery.id = query.id
175 self.assertEqual(query, receivedQuery)
176 self.assertEqual(len(receivedResponses), len(responses))
177
178 def testThreePlusTrailingAXFR(self):
179 """
180 AXFR: Three messages including the final SOA, plus a trailing one
181 """
182 name = 'threeplustrailing.axfr.tests.powerdns.com.'
183 query = dns.message.make_query(name, 'AXFR', 'IN')
184 responses = []
185 soa = dns.rrset.from_text(name,
186 60,
187 dns.rdataclass.IN,
188 dns.rdatatype.SOA,
189 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
190
191 # the SOA starts the AXFR
192 response = dns.message.make_response(query)
193 response.answer.append(soa)
194 responses.append(response)
195
196 # one A
197 response = dns.message.make_response(query)
198 response.answer.append(dns.rrset.from_text(name,
199 60,
200 dns.rdataclass.IN,
201 dns.rdatatype.A,
202 '192.0.2.1'))
203 responses.append(response)
204
205 # one AAAA
206 response = dns.message.make_response(query)
207 rrset = dns.rrset.from_text(name,
208 60,
209 dns.rdataclass.IN,
210 dns.rdatatype.AAAA,
211 '2001:DB8::1')
212 response.answer.append(rrset)
213 responses.append(response)
214
215 # one TXT then the SOA that ends the AXFR
216 response = dns.message.make_response(query)
217 rrset = dns.rrset.from_text(name,
218 60,
219 dns.rdataclass.IN,
220 dns.rdatatype.TXT,
221 "Some text")
222 response.answer.append(rrset)
223 response.answer.append(soa)
224 responses.append(response)
225
226 # and we add a final, dummy TXT message that will
227 # be sent by the backend but that dnsdist should not
228 # pass along to the client
229 response = dns.message.make_response(query)
230 rrset = dns.rrset.from_text(name,
231 60,
232 dns.rdataclass.IN,
233 dns.rdatatype.TXT,
234 'dummy')
235 response.answer.append(rrset)
236 responses.append(response)
237
238 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
239 receivedQuery.id = query.id
240 self.assertEqual(query, receivedQuery)
241 self.assertEqual(len(receivedResponses), len(responses) - 1)
242
243 def testThreePlusTrailingIXFR(self):
244 """
245 IXFR: Three messages including the final SOA, plus a trailing one
246 """
247 name = 'threeplustrailing.ixfr.tests.powerdns.com.'
248 query = dns.message.make_query(name, 'AXFR', 'IN')
249 responses = []
250
251 finalSoa = dns.rrset.from_text(name,
252 60,
253 dns.rdataclass.IN,
254 dns.rdatatype.SOA,
255 'ns.' + name + ' hostmaster.' + name + ' 3 3600 3600 3600 60')
256
257 # the final SOA starts the IXFR, with first an update from 1 to 2 (one removal, two additions)
258 response = dns.message.make_response(query)
259 response.answer.append(finalSoa)
260 # update from 1 to 2
261 response.answer.append(dns.rrset.from_text(name,
262 60,
263 dns.rdataclass.IN,
264 dns.rdatatype.SOA,
265 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60'))
266 # one removal
267 response.answer.append(dns.rrset.from_text(name,
268 60,
269 dns.rdataclass.IN,
270 dns.rdatatype.A,
271 '192.0.2.1'))
272 # then additions
273 response.answer.append(dns.rrset.from_text(name,
274 60,
275 dns.rdataclass.IN,
276 dns.rdatatype.SOA,
277 'ns.' + name + ' hostmaster.' + name + ' 2 3600 3600 3600 60'))
278 # new message in the middle of the additions
279 responses.append(response)
280 response = dns.message.make_response(query)
281
282 response.answer.append(dns.rrset.from_text_list(name,
283 60,
284 dns.rdataclass.IN,
285 dns.rdatatype.A,
286 ['192.0.2.2', '192.0.2.3']))
287 # done with 1 -> 2
288 response.answer.append(dns.rrset.from_text(name,
289 60,
290 dns.rdataclass.IN,
291 dns.rdatatype.SOA,
292 'ns.' + name + ' hostmaster.' + name + ' 2 3600 3600 3600 60'))
293 # new message
294 responses.append(response)
295 response = dns.message.make_response(query)
296
297 # then upgrade to 3
298 # no removals
299 response.answer.append(finalSoa)
300
301 # and one addition
302 response.answer.append(dns.rrset.from_text(name,
303 60,
304 dns.rdataclass.IN,
305 dns.rdatatype.A,
306 '192.0.2.4'))
307 # and the final SOA
308 response.answer.append(finalSoa)
309 responses.append(response)
310
311 # and we add a final, dummy TXT message that will
312 # be sent by the backend but that dnsdist should not
313 # pass along to the client
314 response = dns.message.make_response(query)
315 rrset = dns.rrset.from_text(name,
316 60,
317 dns.rdataclass.IN,
318 dns.rdatatype.TXT,
319 'dummy')
320 response.answer.append(rrset)
321 responses.append(response)
322
323 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
324 receivedQuery.id = query.id
325 self.assertEqual(query, receivedQuery)
326 self.assertEqual(len(receivedResponses), len(responses) - 1)
327
328 # def testFourNoFirstSOAAXFR(self):
329 # """
330 # AXFR: Four messages, no SOA in the first one
331 # """
332 # name = 'fournosoainfirst.axfr.tests.powerdns.com.'
333 # query = dns.message.make_query(name, 'AXFR', 'IN')
334 # responses = []
335 # soa = dns.rrset.from_text(name,
336 # 60,
337 # dns.rdataclass.IN,
338 # dns.rdatatype.SOA,
339 # 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
340 # response = dns.message.make_response(query)
341 # response.answer.append(dns.rrset.from_text(name,
342 # 60,
343 # dns.rdataclass.IN,
344 # dns.rdatatype.A,
345 # '192.0.2.1'))
346 # responses.append(response)
347
348 # response = dns.message.make_response(query)
349 # rrset = dns.rrset.from_text(name,
350 # 60,
351 # dns.rdataclass.IN,
352 # dns.rdatatype.AAAA,
353 # '2001:DB8::1')
354 # response.answer.append(soa)
355 # response.answer.append(rrset)
356 # responses.append(response)
357
358 # response = dns.message.make_response(query)
359 # rrset = dns.rrset.from_text('dummy.' + name,
360 # 60,
361 # dns.rdataclass.IN,
362 # dns.rdatatype.AAAA,
363 # '2001:DB8::1')
364 # response.answer.append(rrset)
365 # responses.append(response)
366
367 # response = dns.message.make_response(query)
368 # rrset = dns.rrset.from_text(name,
369 # 60,
370 # dns.rdataclass.IN,
371 # dns.rdatatype.TXT,
372 # 'dummy')
373 # response.answer.append(rrset)
374 # response.answer.append(soa)
375 # responses.append(response)
376
377 # (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
378 # receivedQuery.id = query.id
379 # self.assertEqual(query, receivedQuery)
380 # self.assertEqual(len(receivedResponses), 1)
381
382 # def testFourLastSOAInSecondAXFR(self):
383 # """
384 # AXFR: Four messages, SOA in the first one and the second one
385 # """
386 # name = 'foursecondsoainsecond.axfr.tests.powerdns.com.'
387 # query = dns.message.make_query(name, 'AXFR', 'IN')
388 # responses = []
389 # soa = dns.rrset.from_text(name,
390 # 60,
391 # dns.rdataclass.IN,
392 # dns.rdatatype.SOA,
393 # 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
394
395 # response = dns.message.make_response(query)
396 # response.answer.append(soa)
397 # response.answer.append(dns.rrset.from_text(name,
398 # 60,
399 # dns.rdataclass.IN,
400 # dns.rdatatype.A,
401 # '192.0.2.1'))
402 # responses.append(response)
403
404 # response = dns.message.make_response(query)
405 # response.answer.append(soa)
406 # rrset = dns.rrset.from_text(name,
407 # 60,
408 # dns.rdataclass.IN,
409 # dns.rdatatype.AAAA,
410 # '2001:DB8::1')
411 # response.answer.append(rrset)
412 # responses.append(response)
413
414 # response = dns.message.make_response(query)
415 # rrset = dns.rrset.from_text('dummy.' + name,
416 # 60,
417 # dns.rdataclass.IN,
418 # dns.rdatatype.AAAA,
419 # '2001:DB8::1')
420 # response.answer.append(rrset)
421 # responses.append(response)
422
423 # response = dns.message.make_response(query)
424 # rrset = dns.rrset.from_text(name,
425 # 60,
426 # dns.rdataclass.IN,
427 # dns.rdatatype.TXT,
428 # 'dummy')
429 # response.answer.append(rrset)
430 # responses.append(response)
431
432 # (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
433 # receivedQuery.id = query.id
434 # self.assertEqual(query, receivedQuery)
435 # self.assertEqual(len(receivedResponses), 2)