]>
git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_Trailing.py
4 from dnsdisttests
import DNSDistTest
6 class TestTrailingDataToBackend(DNSDistTest
):
8 # this test suite uses a different responder port
9 # because, contrary to the other ones, its
10 # responders allow trailing data and we don't want
12 _testServerPort
= 5360
14 _config_template
= """
15 newServer{address="127.0.0.1:%s"}
17 function replaceTrailingData(dq)
18 local success = dq:setTrailingData("ABC")
20 return DNSAction.ServFail, ""
22 return DNSAction.None, ""
24 addAction("added.trailing.tests.powerdns.com.", LuaAction(replaceTrailingData))
26 function fillBuffer(dq)
27 local available = 4096 - dq.len
29 available = 65535 - dq.len
31 local tail = string.rep("A", available)
32 local success = dq:setTrailingData(tail)
34 return DNSAction.ServFail, ""
36 return DNSAction.None, ""
38 addAction("max.trailing.tests.powerdns.com.", LuaAction(fillBuffer))
40 function exceedBuffer(dq)
41 local available = 4096 - dq.len
43 available = 65535 - dq.len
45 local tail = string.rep("A", available + 1)
46 local success = dq:setTrailingData(tail)
48 return DNSAction.ServFail, ""
50 return DNSAction.None, ""
52 addAction("limited.trailing.tests.powerdns.com.", LuaAction(exceedBuffer))
55 def startResponders(cls
):
56 print("Launching responders..")
58 # Respond REFUSED to queries with trailing data.
59 cls
._UDPResponder
= threading
.Thread(name
='UDP Responder', target
=cls
.UDPResponder
, args
=[cls
._testServerPort
, cls
._toResponderQueue
, cls
._fromResponderQueue
, dns
.rcode
.REFUSED
])
60 cls
._UDPResponder
.setDaemon(True)
61 cls
._UDPResponder
.start()
63 # Respond REFUSED to queries with trailing data.
64 cls
._TCPResponder
= threading
.Thread(name
='TCP Responder', target
=cls
.TCPResponder
, args
=[cls
._testServerPort
, cls
._toResponderQueue
, cls
._fromResponderQueue
, dns
.rcode
.REFUSED
])
65 cls
._TCPResponder
.setDaemon(True)
66 cls
._TCPResponder
.start()
68 def testTrailingPassthrough(self
):
70 Trailing data: Pass through
73 name
= 'passthrough.trailing.tests.powerdns.com.'
74 query
= dns
.message
.make_query(name
, 'A', 'IN')
75 response
= dns
.message
.make_response(query
)
76 rrset
= dns
.rrset
.from_text(name
,
81 response
.answer
.append(rrset
)
82 expectedResponse
= dns
.message
.make_response(query
)
83 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
88 for method
in ("sendUDPQuery", "sendTCPQuery"):
89 sender
= getattr(self
, method
)
90 (receivedQuery
, receivedResponse
) = sender(raw
, response
, rawQuery
=True)
91 self
.assertTrue(receivedQuery
)
92 self
.assertTrue(receivedResponse
)
93 receivedQuery
.id = query
.id
94 self
.assertEquals(receivedQuery
, query
)
95 self
.assertEquals(receivedResponse
, expectedResponse
)
97 def testTrailingCapacity(self
):
99 Trailing data: Fill buffer
102 name
= 'max.trailing.tests.powerdns.com.'
103 query
= dns
.message
.make_query(name
, 'A', 'IN')
104 response
= dns
.message
.make_response(query
)
105 rrset
= dns
.rrset
.from_text(name
,
110 response
.answer
.append(rrset
)
111 expectedResponse
= dns
.message
.make_response(query
)
112 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
114 for method
in ("sendUDPQuery", "sendTCPQuery"):
115 sender
= getattr(self
, method
)
116 (receivedQuery
, receivedResponse
) = sender(query
, response
)
117 self
.assertTrue(receivedQuery
)
118 self
.assertTrue(receivedResponse
)
119 receivedQuery
.id = query
.id
120 self
.assertEquals(receivedQuery
, query
)
121 self
.assertEquals(receivedResponse
, expectedResponse
)
123 def testTrailingLimited(self
):
125 Trailing data: Reject buffer overflows
128 name
= 'limited.trailing.tests.powerdns.com.'
129 query
= dns
.message
.make_query(name
, 'A', 'IN')
130 response
= dns
.message
.make_response(query
)
131 rrset
= dns
.rrset
.from_text(name
,
136 response
.answer
.append(rrset
)
137 expectedResponse
= dns
.message
.make_response(query
)
138 expectedResponse
.set_rcode(dns
.rcode
.SERVFAIL
)
140 for method
in ("sendUDPQuery", "sendTCPQuery"):
141 sender
= getattr(self
, method
)
142 (_
, receivedResponse
) = sender(query
, response
, useQueue
=False)
143 self
.assertTrue(receivedResponse
)
144 self
.assertEquals(receivedResponse
, expectedResponse
)
146 def testTrailingAdded(self
):
151 name
= 'added.trailing.tests.powerdns.com.'
152 query
= dns
.message
.make_query(name
, 'A', 'IN')
153 response
= dns
.message
.make_response(query
)
154 rrset
= dns
.rrset
.from_text(name
,
159 response
.answer
.append(rrset
)
160 expectedResponse
= dns
.message
.make_response(query
)
161 expectedResponse
.set_rcode(dns
.rcode
.REFUSED
)
163 for method
in ("sendUDPQuery", "sendTCPQuery"):
164 sender
= getattr(self
, method
)
165 (receivedQuery
, receivedResponse
) = sender(query
, response
)
166 self
.assertTrue(receivedQuery
)
167 self
.assertTrue(receivedResponse
)
168 receivedQuery
.id = query
.id
169 self
.assertEquals(receivedQuery
, query
)
170 self
.assertEquals(receivedResponse
, expectedResponse
)
172 class TestTrailingDataToDnsdist(DNSDistTest
):
174 _config_template
= """
175 newServer{address="127.0.0.1:%s"}
177 addAction(AndRule({QNameRule("dropped.trailing.tests.powerdns.com."), TrailingDataRule()}), DropAction())
179 function removeTrailingData(dq)
180 local success = dq:setTrailingData("")
182 print("Trailing removal failed")
183 return DNSAction.ServFail, ""
185 return DNSAction.None, ""
187 addAction("removed.trailing.tests.powerdns.com.", LuaAction(removeTrailingData))
189 function reportTrailingData(dq)
190 local tail = dq:getTrailingData()
191 return DNSAction.Spoof, "-" .. tail .. ".echoed.trailing.tests.powerdns.com."
193 addAction("echoed.trailing.tests.powerdns.com.", LuaAction(reportTrailingData))
195 function replaceTrailingData(dq)
196 local success = dq:setTrailingData("ABC")
198 return DNSAction.ServFail, ""
200 return DNSAction.None, ""
202 addAction("replaced.trailing.tests.powerdns.com.", LuaAction(replaceTrailingData))
203 addAction("replaced.trailing.tests.powerdns.com.", LuaAction(reportTrailingData))
205 function reportTrailingHex(dq)
206 local tail = dq:getTrailingData()
207 local hex = string.gsub(tail, ".", function(ch)
208 return string.sub(string.format("\\x2502X", string.byte(ch)), -2)
210 return DNSAction.Spoof, "-0x" .. hex .. ".echoed-hex.trailing.tests.powerdns.com."
212 addAction("echoed-hex.trailing.tests.powerdns.com.", LuaAction(reportTrailingHex))
214 function replaceTrailingData_unsafe(dq)
215 local success = dq:setTrailingData("\\xB0\\x00\\xDE\\xADB\\xF0\\x9F\\x91\\xBB\\xC3\\xBE")
217 return DNSAction.ServFail, ""
219 return DNSAction.None, ""
221 addAction("replaced-unsafe.trailing.tests.powerdns.com.", LuaAction(replaceTrailingData_unsafe))
222 addAction("replaced-unsafe.trailing.tests.powerdns.com.", LuaAction(reportTrailingHex))
225 def testTrailingDropped(self
):
227 Trailing data: Drop query
230 name
= 'dropped.trailing.tests.powerdns.com.'
231 query
= dns
.message
.make_query(name
, 'A', 'IN')
232 response
= dns
.message
.make_response(query
)
233 rrset
= dns
.rrset
.from_text(name
,
238 response
.answer
.append(rrset
)
240 raw
= query
.to_wire()
243 for method
in ("sendUDPQuery", "sendTCPQuery"):
244 sender
= getattr(self
, method
)
246 # Verify that queries with no trailing data make it through.
247 (receivedQuery
, receivedResponse
) = sender(query
, response
)
248 self
.assertTrue(receivedQuery
)
249 self
.assertTrue(receivedResponse
)
250 receivedQuery
.id = query
.id
251 self
.assertEquals(query
, receivedQuery
)
252 self
.assertEquals(response
, receivedResponse
)
254 # Verify that queries with trailing data don't make it through.
255 (_
, receivedResponse
) = sender(raw
, response
, rawQuery
=True, useQueue
=False)
256 self
.assertEquals(receivedResponse
, None)
258 def testTrailingRemoved(self
):
260 Trailing data: Remove
263 name
= 'removed.trailing.tests.powerdns.com.'
264 query
= dns
.message
.make_query(name
, 'A', 'IN')
265 response
= dns
.message
.make_response(query
)
266 rrset
= dns
.rrset
.from_text(name
,
271 response
.answer
.append(rrset
)
273 raw
= query
.to_wire()
276 for method
in ("sendUDPQuery", "sendTCPQuery"):
277 sender
= getattr(self
, method
)
278 (receivedQuery
, receivedResponse
) = sender(raw
, response
, rawQuery
=True)
279 self
.assertTrue(receivedQuery
)
280 self
.assertTrue(receivedResponse
)
281 receivedQuery
.id = query
.id
282 self
.assertEquals(receivedQuery
, query
)
283 self
.assertEquals(receivedResponse
, response
)
285 def testTrailingRead(self
):
290 name
= 'echoed.trailing.tests.powerdns.com.'
291 query
= dns
.message
.make_query(name
, 'A', 'IN')
292 response
= dns
.message
.make_response(query
)
293 response
.set_rcode(dns
.rcode
.SERVFAIL
)
294 expectedResponse
= dns
.message
.make_response(query
)
295 rrset
= dns
.rrset
.from_text(name
,
299 '-TrailingData.echoed.trailing.tests.powerdns.com.')
300 expectedResponse
.answer
.append(rrset
)
302 raw
= query
.to_wire()
303 raw
= raw
+ b
'TrailingData'
305 for method
in ("sendUDPQuery", "sendTCPQuery"):
306 sender
= getattr(self
, method
)
307 (_
, receivedResponse
) = sender(raw
, response
=None, rawQuery
=True, useQueue
=False)
308 self
.assertTrue(receivedResponse
)
309 expectedResponse
.flags
= receivedResponse
.flags
310 self
.assertEquals(receivedResponse
, expectedResponse
)
312 def testTrailingReplaced(self
):
314 Trailing data: Replace
317 name
= 'replaced.trailing.tests.powerdns.com.'
318 query
= dns
.message
.make_query(name
, 'A', 'IN')
319 response
= dns
.message
.make_response(query
)
320 response
.set_rcode(dns
.rcode
.SERVFAIL
)
321 expectedResponse
= dns
.message
.make_response(query
)
322 rrset
= dns
.rrset
.from_text(name
,
326 '-ABC.echoed.trailing.tests.powerdns.com.')
327 expectedResponse
.answer
.append(rrset
)
329 raw
= query
.to_wire()
330 raw
= raw
+ b
'TrailingData'
332 for method
in ("sendUDPQuery", "sendTCPQuery"):
333 sender
= getattr(self
, method
)
334 (_
, receivedResponse
) = sender(raw
, response
=None, rawQuery
=True, useQueue
=False)
335 self
.assertTrue(receivedResponse
)
336 expectedResponse
.flags
= receivedResponse
.flags
337 self
.assertEquals(receivedResponse
, expectedResponse
)
339 def testTrailingReadUnsafe(self
):
341 Trailing data: Echo as hex
344 name
= 'echoed-hex.trailing.tests.powerdns.com.'
345 query
= dns
.message
.make_query(name
, 'A', 'IN')
346 response
= dns
.message
.make_response(query
)
347 response
.set_rcode(dns
.rcode
.SERVFAIL
)
348 expectedResponse
= dns
.message
.make_response(query
)
349 rrset
= dns
.rrset
.from_text(name
,
353 '-0x0000DEAD.echoed-hex.trailing.tests.powerdns.com.')
354 expectedResponse
.answer
.append(rrset
)
356 raw
= query
.to_wire()
357 raw
= raw
+ b
'\x00\x00\xDE\xAD'
359 for method
in ("sendUDPQuery", "sendTCPQuery"):
360 sender
= getattr(self
, method
)
361 (_
, receivedResponse
) = sender(raw
, response
=None, rawQuery
=True, useQueue
=False)
362 self
.assertTrue(receivedResponse
)
363 expectedResponse
.flags
= receivedResponse
.flags
364 self
.assertEquals(receivedResponse
, expectedResponse
)
366 def testTrailingReplacedUnsafe(self
):
368 Trailing data: Replace with null and/or non-ASCII bytes
371 name
= 'replaced-unsafe.trailing.tests.powerdns.com.'
372 query
= dns
.message
.make_query(name
, 'A', 'IN')
373 response
= dns
.message
.make_response(query
)
374 response
.set_rcode(dns
.rcode
.SERVFAIL
)
375 expectedResponse
= dns
.message
.make_response(query
)
376 rrset
= dns
.rrset
.from_text(name
,
380 '-0xB000DEAD42F09F91BBC3BE.echoed-hex.trailing.tests.powerdns.com.')
381 expectedResponse
.answer
.append(rrset
)
383 raw
= query
.to_wire()
384 raw
= raw
+ b
'TrailingData'
386 for method
in ("sendUDPQuery", "sendTCPQuery"):
387 sender
= getattr(self
, method
)
388 (_
, receivedResponse
) = sender(raw
, response
=None, rawQuery
=True, useQueue
=False)
389 self
.assertTrue(receivedResponse
)
390 expectedResponse
.flags
= receivedResponse
.flags
391 self
.assertEquals(receivedResponse
, expectedResponse
)