]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.dnsdist/test_TeeAction.py
Merge pull request #13816 from jsoref/lua-records-rst
[thirdparty/pdns.git] / regression-tests.dnsdist / test_TeeAction.py
1 #!/usr/bin/env python
2 import base64
3 import threading
4 import clientsubnetoption
5 import dns
6 from dnsdisttests import DNSDistTest, Queue, pickAvailablePort
7 from proxyprotocolutils import ProxyProtocolUDPResponder, ProxyProtocolTCPResponder
8
9 class TestTeeAction(DNSDistTest):
10
11 _consoleKey = DNSDistTest.generateConsoleKey()
12 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
13 _teeServerPort = pickAvailablePort()
14 _teeProxyServerPort = pickAvailablePort()
15 _toTeeQueue = Queue()
16 _fromTeeQueue = Queue()
17 _toTeeProxyQueue = Queue()
18 _fromTeeProxyQueue = Queue()
19 _config_template = """
20 setKey("%s")
21 controlSocket("127.0.0.1:%s")
22 newServer{address="127.0.0.1:%d"}
23 addAction(QTypeRule(DNSQType.A), TeeAction("127.0.0.1:%d", true))
24 addAction(QTypeRule(DNSQType.AAAA), TeeAction("127.0.0.1:%d", false))
25 addAction(QTypeRule(DNSQType.ANY), TeeAction("127.0.0.1:%d", false, '127.0.0.1', true))
26 """
27 _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_teeServerPort', '_teeServerPort', '_teeProxyServerPort']
28 @classmethod
29 def startResponders(cls):
30 print("Launching responders..")
31
32 cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue])
33 cls._UDPResponder.daemon = True
34 cls._UDPResponder.start()
35
36 cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, True])
37 cls._TCPResponder.daemon = True
38 cls._TCPResponder.start()
39
40 cls._TeeResponder = threading.Thread(name='Tee Responder', target=cls.UDPResponder, args=[cls._teeServerPort, cls._toTeeQueue, cls._fromTeeQueue])
41 cls._TeeResponder.daemon = True
42 cls._TeeResponder.start()
43
44 cls._TeeProxyResponder = threading.Thread(name='Proxy Protocol Tee Responder', target=ProxyProtocolUDPResponder, args=[cls._teeProxyServerPort, cls._toTeeProxyQueue, cls._fromTeeProxyQueue])
45 cls._TeeProxyResponder.daemon = True
46 cls._TeeProxyResponder.start()
47
48 def testTeeWithECS(self):
49 """
50 TeeAction: ECS
51 """
52 name = 'ecs.tee.tests.powerdns.com.'
53 query = dns.message.make_query(name, 'A', 'IN')
54 response = dns.message.make_response(query)
55
56 rrset = dns.rrset.from_text(name,
57 3600,
58 dns.rdataclass.IN,
59 dns.rdatatype.A,
60 '192.0.2.1')
61 response.answer.append(rrset)
62
63 numberOfQueries = 10
64 for _ in range(numberOfQueries):
65 # push the response to the Tee server
66 self._toTeeQueue.put(response, True, 2.0)
67
68 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
69 self.assertTrue(receivedQuery)
70 self.assertTrue(receivedResponse)
71 receivedQuery.id = query.id
72 self.assertEqual(query, receivedQuery)
73 self.assertEqual(response, receivedResponse)
74
75 # retrieve the query from the Tee server
76 teedQuery = self._fromTeeQueue.get(True, 2.0)
77 ecso = clientsubnetoption.ClientSubnetOption('127.0.0.1', 24)
78 expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, options=[ecso], payload=512)
79 expectedQuery.id = query.id
80 self.checkQueryEDNSWithECS(expectedQuery, teedQuery)
81
82 # check the TeeAction stats
83 stats = self.sendConsoleCommand("getAction(0):printStats()")
84 self.assertEqual(stats, """noerrors\t%d
85 nxdomains\t0
86 other-rcode\t0
87 queries\t%d
88 recv-errors\t0
89 refuseds\t0
90 responses\t%d
91 send-errors\t0
92 servfails\t0
93 tcp-drops\t0
94 """ % (numberOfQueries, numberOfQueries, numberOfQueries))
95
96 def testTeeWithoutECS(self):
97 """
98 TeeAction: No ECS
99 """
100 name = 'noecs.tee.tests.powerdns.com.'
101 query = dns.message.make_query(name, 'AAAA', 'IN')
102 response = dns.message.make_response(query)
103
104 rrset = dns.rrset.from_text(name,
105 3600,
106 dns.rdataclass.IN,
107 dns.rdatatype.AAAA,
108 '2001:DB8::1')
109 response.answer.append(rrset)
110
111 numberOfQueries = 10
112 for _ in range(numberOfQueries):
113 # push the response to the Tee server
114 self._toTeeQueue.put(response, True, 2.0)
115
116 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
117 self.assertTrue(receivedQuery)
118 self.assertTrue(receivedResponse)
119 receivedQuery.id = query.id
120 self.assertEqual(query, receivedQuery)
121 self.assertEqual(response, receivedResponse)
122
123 # retrieve the query from the Tee server
124 teedQuery = self._fromTeeQueue.get(True, 2.0)
125 ecso = clientsubnetoption.ClientSubnetOption('127.0.0.1', 24)
126 expectedQuery = dns.message.make_query(name, 'AAAA', 'IN', use_edns=True, options=[ecso], payload=512)
127 expectedQuery.id = query.id
128 self.checkMessageNoEDNS(expectedQuery, teedQuery)
129
130 # check the TeeAction stats
131 stats = self.sendConsoleCommand("getAction(0):printStats()")
132 self.assertEqual(stats, """noerrors\t%d
133 nxdomains\t0
134 other-rcode\t0
135 queries\t%d
136 recv-errors\t0
137 refuseds\t0
138 responses\t%d
139 send-errors\t0
140 servfails\t0
141 tcp-drops\t0
142 """ % (numberOfQueries, numberOfQueries, numberOfQueries))
143
144 def testTeeWithProxy(self):
145 """
146 TeeAction: Proxy
147 """
148 name = 'proxy.tee.tests.powerdns.com.'
149 query = dns.message.make_query(name, 'ANY', 'IN')
150 response = dns.message.make_response(query)
151
152 rrset = dns.rrset.from_text(name,
153 3600,
154 dns.rdataclass.IN,
155 dns.rdatatype.A,
156 '192.0.2.1')
157 response.answer.append(rrset)
158
159 numberOfQueries = 10
160 for _ in range(numberOfQueries):
161 # push the response to the Tee Proxy server
162 self._toTeeProxyQueue.put(response, True, 2.0)
163
164 (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
165 self.assertTrue(receivedQuery)
166 self.assertTrue(receivedResponse)
167 receivedQuery.id = query.id
168 self.assertEqual(query, receivedQuery)
169 self.assertEqual(response, receivedResponse)
170
171 # retrieve the query from the Tee Proxy server
172 [payload, teedQuery] = self._fromTeeProxyQueue.get(True, 2.0)
173 self.checkMessageNoEDNS(query, dns.message.from_wire(teedQuery))
174 self.checkMessageProxyProtocol(payload, '127.0.0.1', '127.0.0.1', False)
175
176 # check the TeeAction stats
177 stats = self.sendConsoleCommand("getAction(0):printStats()")
178 self.assertEqual(stats, """noerrors\t%d
179 nxdomains\t0
180 other-rcode\t0
181 queries\t%d
182 recv-errors\t0
183 refuseds\t0
184 responses\t%d
185 send-errors\t0
186 servfails\t0
187 tcp-drops\t0
188 """ % (numberOfQueries, numberOfQueries, numberOfQueries))