]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_AXFR.py
Merge pull request #14078 from rgacogne/ddist-harvest-quic
[thirdparty/pdns.git] / regression-tests.dnsdist / test_AXFR.py
CommitLineData
548c8b66
RG
1#!/usr/bin/env python
2import threading
936dd73c 3import time
548c8b66 4import dns
630eb526 5from dnsdisttests import DNSDistTest, pickAvailablePort
548c8b66
RG
6
7class 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.
630eb526 13 _testServerPort = pickAvailablePort()
548c8b66
RG
14 _config_template = """
15 newServer{address="127.0.0.1:%s"}
16 """
645a1ca4 17
548c8b66
RG
18 @classmethod
19 def startResponders(cls):
20 print("Launching responders..")
21
5df86a8a 22 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
630eb526 23 cls._UDPResponder.daemon = True
548c8b66 24 cls._UDPResponder.start()
645a1ca4 25 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, True, None, None, True])
630eb526 26 cls._TCPResponder.daemon = True
548c8b66
RG
27 cls._TCPResponder.start()
28
936dd73c
RG
29 def setUp(self):
30 # This function is called before every test
31 super(TestAXFR, self).setUp()
32 # make sure the TCP connection handlers from the previous test
33 # are not going to read our queue
34 time.sleep(1)
35
548c8b66
RG
36 def testOneMessageAXFR(self):
37 """
38 AXFR: One message
39 """
40 name = 'one.axfr.tests.powerdns.com.'
41 query = dns.message.make_query(name, 'AXFR', 'IN')
42 response = dns.message.make_response(query)
43 soa = dns.rrset.from_text(name,
44 60,
45 dns.rdataclass.IN,
46 dns.rdatatype.SOA,
47 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
48 response.answer.append(soa)
49 response.answer.append(dns.rrset.from_text(name,
50 60,
51 dns.rdataclass.IN,
52 dns.rdatatype.A,
53 '192.0.2.1'))
54 response.answer.append(soa)
55
56 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
57 receivedQuery.id = query.id
58 self.assertEqual(query, receivedQuery)
59 self.assertEqual(response, receivedResponse)
60
61 def testOneNoSOAAXFR(self):
62 """
63 AXFR: One message, no SOA
64 """
65 name = 'onenosoa.axfr.tests.powerdns.com.'
66 query = dns.message.make_query(name, 'AXFR', 'IN')
67 response = dns.message.make_response(query)
68 response.answer.append(dns.rrset.from_text(name,
69 60,
70 dns.rdataclass.IN,
71 dns.rdatatype.A,
72 '192.0.2.1'))
73
74 (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
75 receivedQuery.id = query.id
76 self.assertEqual(query, receivedQuery)
77 self.assertEqual(response, receivedResponse)
78
79 def testFourMessagesAXFR(self):
80 """
81 AXFR: Four messages
82 """
83 name = 'four.axfr.tests.powerdns.com.'
84 query = dns.message.make_query(name, 'AXFR', 'IN')
85 responses = []
86 soa = dns.rrset.from_text(name,
87 60,
88 dns.rdataclass.IN,
89 dns.rdatatype.SOA,
90 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
91 response = dns.message.make_response(query)
92 response.answer.append(soa)
93 responses.append(response)
94
95 response = dns.message.make_response(query)
96 response.answer.append(dns.rrset.from_text(name,
97 60,
98 dns.rdataclass.IN,
99 dns.rdatatype.A,
100 '192.0.2.1'))
101 responses.append(response)
102
103 response = dns.message.make_response(query)
104 rrset = dns.rrset.from_text(name,
105 60,
106 dns.rdataclass.IN,
107 dns.rdatatype.AAAA,
108 '2001:DB8::1')
109 response.answer.append(rrset)
110 responses.append(response)
111
112 response = dns.message.make_response(query)
113 rrset = dns.rrset.from_text(name,
114 60,
115 dns.rdataclass.IN,
116 dns.rdatatype.TXT,
117 'dummy')
118 response.answer.append(rrset)
119 responses.append(response)
120
121 response = dns.message.make_response(query)
122 response.answer.append(soa)
123 responses.append(response)
124
125 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
126 receivedQuery.id = query.id
127 self.assertEqual(query, receivedQuery)
128 self.assertEqual(len(receivedResponses), len(responses))
129
130 def testFourNoFinalSOAAXFR(self):
131 """
132 AXFR: Four messages, no final SOA
133 """
134 name = 'fournosoa.axfr.tests.powerdns.com.'
135 query = dns.message.make_query(name, 'AXFR', 'IN')
136 responses = []
137 soa = dns.rrset.from_text(name,
138 60,
139 dns.rdataclass.IN,
140 dns.rdatatype.SOA,
141 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
142 response = dns.message.make_response(query)
143 response.answer.append(soa)
144 responses.append(response)
145
146 response = dns.message.make_response(query)
147 response.answer.append(dns.rrset.from_text(name,
148 60,
149 dns.rdataclass.IN,
150 dns.rdatatype.A,
151 '192.0.2.1'))
152 responses.append(response)
153
154 response = dns.message.make_response(query)
155 rrset = dns.rrset.from_text(name,
156 60,
157 dns.rdataclass.IN,
158 dns.rdatatype.AAAA,
159 '2001:DB8::1')
160 response.answer.append(rrset)
161 responses.append(response)
162
163 response = dns.message.make_response(query)
164 rrset = dns.rrset.from_text(name,
165 60,
166 dns.rdataclass.IN,
167 dns.rdatatype.TXT,
168 'dummy')
169 response.answer.append(rrset)
170 responses.append(response)
171
172 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
173 receivedQuery.id = query.id
174 self.assertEqual(query, receivedQuery)
175 self.assertEqual(len(receivedResponses), len(responses))
176
4639c3f5
RG
177 def testThreePlusTrailingAXFR(self):
178 """
179 AXFR: Three messages including the final SOA, plus a trailing one
180 """
181 name = 'threeplustrailing.axfr.tests.powerdns.com.'
182 query = dns.message.make_query(name, 'AXFR', 'IN')
183 responses = []
184 soa = dns.rrset.from_text(name,
185 60,
186 dns.rdataclass.IN,
187 dns.rdatatype.SOA,
188 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60')
189
190 # the SOA starts the AXFR
191 response = dns.message.make_response(query)
192 response.answer.append(soa)
193 responses.append(response)
194
195 # one A
196 response = dns.message.make_response(query)
197 response.answer.append(dns.rrset.from_text(name,
198 60,
199 dns.rdataclass.IN,
200 dns.rdatatype.A,
201 '192.0.2.1'))
202 responses.append(response)
203
204 # one AAAA
205 response = dns.message.make_response(query)
206 rrset = dns.rrset.from_text(name,
207 60,
208 dns.rdataclass.IN,
209 dns.rdatatype.AAAA,
210 '2001:DB8::1')
211 response.answer.append(rrset)
212 responses.append(response)
213
214 # one TXT then the SOA that ends the AXFR
215 response = dns.message.make_response(query)
216 rrset = dns.rrset.from_text(name,
217 60,
218 dns.rdataclass.IN,
219 dns.rdatatype.TXT,
220 "Some text")
221 response.answer.append(rrset)
222 response.answer.append(soa)
223 responses.append(response)
224
225 # and we add a final, dummy TXT message that will
226 # be sent by the backend but that dnsdist should not
227 # pass along to the client
228 response = dns.message.make_response(query)
229 rrset = dns.rrset.from_text(name,
230 60,
231 dns.rdataclass.IN,
232 dns.rdatatype.TXT,
233 'dummy')
234 response.answer.append(rrset)
235 responses.append(response)
236
237 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
238 receivedQuery.id = query.id
239 self.assertEqual(query, receivedQuery)
240 self.assertEqual(len(receivedResponses), len(responses) - 1)
241
242 def testThreePlusTrailingIXFR(self):
243 """
244 IXFR: Three messages including the final SOA, plus a trailing one
245 """
246 name = 'threeplustrailing.ixfr.tests.powerdns.com.'
247 query = dns.message.make_query(name, 'AXFR', 'IN')
248 responses = []
249
250 finalSoa = dns.rrset.from_text(name,
251 60,
252 dns.rdataclass.IN,
253 dns.rdatatype.SOA,
254 'ns.' + name + ' hostmaster.' + name + ' 3 3600 3600 3600 60')
255
936dd73c 256 # the final SOA starts the IXFR, with first an update from 1 to 2 (one removal, two additions)
4639c3f5
RG
257 response = dns.message.make_response(query)
258 response.answer.append(finalSoa)
259 # update from 1 to 2
260 response.answer.append(dns.rrset.from_text(name,
261 60,
262 dns.rdataclass.IN,
263 dns.rdatatype.SOA,
264 'ns.' + name + ' hostmaster.' + name + ' 1 3600 3600 3600 60'))
265 # one removal
266 response.answer.append(dns.rrset.from_text(name,
267 60,
268 dns.rdataclass.IN,
269 dns.rdatatype.A,
270 '192.0.2.1'))
271 # then additions
272 response.answer.append(dns.rrset.from_text(name,
273 60,
274 dns.rdataclass.IN,
275 dns.rdatatype.SOA,
276 'ns.' + name + ' hostmaster.' + name + ' 2 3600 3600 3600 60'))
277 # new message in the middle of the additions
278 responses.append(response)
279 response = dns.message.make_response(query)
280
281 response.answer.append(dns.rrset.from_text_list(name,
282 60,
283 dns.rdataclass.IN,
284 dns.rdatatype.A,
285 ['192.0.2.2', '192.0.2.3']))
286 # done with 1 -> 2
287 response.answer.append(dns.rrset.from_text(name,
288 60,
289 dns.rdataclass.IN,
290 dns.rdatatype.SOA,
291 'ns.' + name + ' hostmaster.' + name + ' 2 3600 3600 3600 60'))
292 # new message
293 responses.append(response)
294 response = dns.message.make_response(query)
295
296 # then upgrade to 3
297 # no removals
298 response.answer.append(finalSoa)
299
300 # and one addition
301 response.answer.append(dns.rrset.from_text(name,
302 60,
303 dns.rdataclass.IN,
304 dns.rdatatype.A,
305 '192.0.2.4'))
306 # and the final SOA
307 response.answer.append(finalSoa)
308 responses.append(response)
309
310 # and we add a final, dummy TXT message that will
311 # be sent by the backend but that dnsdist should not
312 # pass along to the client
313 response = dns.message.make_response(query)
314 rrset = dns.rrset.from_text(name,
315 60,
316 dns.rdataclass.IN,
317 dns.rdatatype.TXT,
318 'dummy')
319 response.answer.append(rrset)
320 responses.append(response)
321
322 (receivedQuery, receivedResponses) = self.sendTCPQueryWithMultipleResponses(query, responses)
323 receivedQuery.id = query.id
324 self.assertEqual(query, receivedQuery)
325 self.assertEqual(len(receivedResponses), len(responses) - 1)