]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.recursor-dnssec/test_LargeAnswer.py
rec: Disable only our own TCP listening socket when reuseport is enabled
[thirdparty/pdns.git] / regression-tests.recursor-dnssec / test_LargeAnswer.py
CommitLineData
d328c3f0
RG
1import dns
2import os
3import socket
4import struct
5import threading
6import time
7
8from recursortests import RecursorTest
9from twisted.internet.protocol import DatagramProtocol
10from twisted.internet import reactor
11
12largeReactorRunning = False
13
14class LargeAnswerTest(RecursorTest):
15 """
16 This test makes sure that we correctly process an answer matching our exact
17 udp-truncation-threshold buffer size.
18 """
19 _confdir = 'LargeAnswer'
20 _udpTruncationThreshold = 1680
21
22 _config_template = """
23forward-zones=large-answer.example=%s.22
24udp-truncation-threshold=%d
25 """ % (os.environ['PREFIX'], _udpTruncationThreshold)
26
27 @classmethod
28 def startResponders(cls):
29 global largeReactorRunning
30 print("Launching responders..")
31
32 address = cls._PREFIX + '.22'
33 port = 53
34
35 if not largeReactorRunning:
36 reactor.listenUDP(port, UDPLargeResponder(), interface=address)
37 largeReactorRunning = True
38
39 if not reactor.running:
d023146c 40 cls._UDPResponder = threading.Thread(name='UDP Responder', target=reactor.run, args=(False,))
d328c3f0
RG
41 cls._UDPResponder.setDaemon(True)
42 cls._UDPResponder.start()
43
d328c3f0
RG
44 def checkResponseContent(self, rawResponse, value):
45 self.assertEquals(len(rawResponse), self._udpTruncationThreshold)
46 response = dns.message.from_wire(rawResponse)
47
48 self.assertRcodeEqual(response, dns.rcode.NOERROR)
49 self.assertFalse(response.flags & dns.flags.TC)
50
51 for record in response.answer:
52 self.assertEquals(record.rdtype, dns.rdatatype.TXT)
53 for part in record:
54 for string in part.strings:
55 self.assertTrue(len(string) == 255 or len(string) == 16)
56 for c in string:
57 self.assertEquals(c, value)
58
59 def testLargeAnswer(self):
60 # why the same query 10 times, do you ask? because if we are reading from
61 # unintialized buffer memory, there is small risk that we find exactly the
62 # value we expected by chance so let's massage our buffer a bit
63 query = dns.message.make_query('AAAA.large-answer.example.', 'TXT', 'IN', use_edns=True, payload=4096)
64 for _ in range(10):
65 raw = self.sendUDPQuery(query, decode=False)
66 self.checkResponseContent(raw, 'A')
67
68 query = dns.message.make_query('ZZZZ.large-answer.example.', 'TXT', 'IN', use_edns=True, payload=4096)
69 for _ in range(10):
70 raw = self.sendUDPQuery(query, decode=False)
71 self.checkResponseContent(raw, 'Z')
72
73class UDPLargeResponder(DatagramProtocol):
74
75 def datagramReceived(self, datagram, address):
76 request = dns.message.from_wire(datagram)
77
78 response = dns.message.make_response(request)
79 response.use_edns(edns=False)
80 response.flags |= dns.flags.AA
81
82 if request.question[0].name == dns.name.from_text('AAAA.large-answer.example.'):
83 value = 'A'
84 else:
85 value = 'Z'
86
87 answer = dns.rrset.from_text(request.question[0].name, 0, dns.rdataclass.IN, 'TXT', value*255)
88 for _ in range(6):
89 response.answer.append(answer)
90 answer = dns.rrset.from_text(request.question[0].name, 0, dns.rdataclass.IN, 'TXT', value*16)
91 response.answer.append(answer)
92 self.transport.write(response.to_wire(max_size=65535), address)