]>
Commit | Line | Data |
---|---|---|
1d0bd88a | 1 | #!/usr/bin/env python |
1d0bd88a RG |
2 | import threading |
3 | import socket | |
4 | import struct | |
5 | import sys | |
6 | import time | |
b4f23783 | 7 | from dnsdisttests import DNSDistTest, Queue |
1d0bd88a RG |
8 | |
9 | import dns | |
10 | import dnsmessage_pb2 | |
11 | ||
f29fabd9 | 12 | class DNSDistProtobufTest(DNSDistTest): |
1d0bd88a | 13 | _protobufServerPort = 4242 |
b4f23783 | 14 | _protobufQueue = Queue() |
312a09a6 | 15 | _protobufServerID = 'dnsdist-server-1' |
1d0bd88a | 16 | _protobufCounter = 0 |
1d0bd88a RG |
17 | |
18 | @classmethod | |
19 | def ProtobufListener(cls, port): | |
20 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
21 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) | |
22 | try: | |
23 | sock.bind(("127.0.0.1", port)) | |
24 | except socket.error as e: | |
25 | print("Error binding in the protbuf listener: %s" % str(e)) | |
26 | sys.exit(1) | |
27 | ||
28 | sock.listen(100) | |
29 | while True: | |
30 | (conn, _) = sock.accept() | |
31 | data = None | |
32 | while True: | |
33 | data = conn.recv(2) | |
34 | if not data: | |
35 | break | |
36 | (datalen,) = struct.unpack("!H", data) | |
37 | data = conn.recv(datalen) | |
38 | if not data: | |
39 | break | |
40 | ||
41 | cls._protobufQueue.put(data, True, timeout=2.0) | |
42 | ||
43 | conn.close() | |
44 | sock.close() | |
45 | ||
46 | @classmethod | |
47 | def startResponders(cls): | |
5df86a8a | 48 | cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) |
1d0bd88a RG |
49 | cls._UDPResponder.setDaemon(True) |
50 | cls._UDPResponder.start() | |
741ebe08 | 51 | |
5df86a8a | 52 | cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) |
1d0bd88a RG |
53 | cls._TCPResponder.setDaemon(True) |
54 | cls._TCPResponder.start() | |
55 | ||
56 | cls._protobufListener = threading.Thread(name='Protobuf Listener', target=cls.ProtobufListener, args=[cls._protobufServerPort]) | |
57 | cls._protobufListener.setDaemon(True) | |
58 | cls._protobufListener.start() | |
59 | ||
60 | def getFirstProtobufMessage(self): | |
61 | self.assertFalse(self._protobufQueue.empty()) | |
62 | data = self._protobufQueue.get(False) | |
63 | self.assertTrue(data) | |
64 | msg = dnsmessage_pb2.PBDNSMessage() | |
65 | msg.ParseFromString(data) | |
66 | return msg | |
67 | ||
29cd61cc | 68 | def checkProtobufBase(self, msg, protocol, query, initiator, normalQueryResponse=True): |
1d0bd88a RG |
69 | self.assertTrue(msg) |
70 | self.assertTrue(msg.HasField('timeSec')) | |
71 | self.assertTrue(msg.HasField('socketFamily')) | |
72 | self.assertEquals(msg.socketFamily, dnsmessage_pb2.PBDNSMessage.INET) | |
73 | self.assertTrue(msg.HasField('from')) | |
74 | fromvalue = getattr(msg, 'from') | |
29cd61cc | 75 | self.assertEquals(socket.inet_ntop(socket.AF_INET, fromvalue), initiator) |
1d0bd88a RG |
76 | self.assertTrue(msg.HasField('socketProtocol')) |
77 | self.assertEquals(msg.socketProtocol, protocol) | |
78 | self.assertTrue(msg.HasField('messageId')) | |
79 | self.assertTrue(msg.HasField('id')) | |
29cd61cc | 80 | self.assertEquals(msg.id, query.id) |
1d0bd88a | 81 | self.assertTrue(msg.HasField('inBytes')) |
312a09a6 | 82 | self.assertTrue(msg.HasField('serverIdentity')) |
06b0e003 | 83 | self.assertEquals(msg.serverIdentity, self._protobufServerID.encode('utf-8')) |
312a09a6 | 84 | |
0096ada6 RG |
85 | if normalQueryResponse: |
86 | # compare inBytes with length of query/response | |
87 | self.assertEquals(msg.inBytes, len(query.to_wire())) | |
1d0bd88a RG |
88 | # dnsdist doesn't set the existing EDNS Subnet for now, |
89 | # although it might be set from Lua | |
90 | # self.assertTrue(msg.HasField('originalRequestorSubnet')) | |
91 | # self.assertEquals(len(msg.originalRequestorSubnet), 4) | |
92 | # self.assertEquals(socket.inet_ntop(socket.AF_INET, msg.originalRequestorSubnet), '127.0.0.1') | |
93 | ||
8667904b | 94 | def checkProtobufQuery(self, msg, protocol, query, qclass, qtype, qname, initiator='127.0.0.1'): |
0096ada6 | 95 | self.assertEquals(msg.type, dnsmessage_pb2.PBDNSMessage.DNSQueryType) |
8667904b | 96 | self.checkProtobufBase(msg, protocol, query, initiator) |
1d0bd88a RG |
97 | # dnsdist doesn't fill the responder field for responses |
98 | # because it doesn't keep the information around. | |
99 | self.assertTrue(msg.HasField('to')) | |
100 | self.assertEquals(socket.inet_ntop(socket.AF_INET, msg.to), '127.0.0.1') | |
101 | self.assertTrue(msg.HasField('question')) | |
102 | self.assertTrue(msg.question.HasField('qClass')) | |
103 | self.assertEquals(msg.question.qClass, qclass) | |
104 | self.assertTrue(msg.question.HasField('qType')) | |
105 | self.assertEquals(msg.question.qClass, qtype) | |
106 | self.assertTrue(msg.question.HasField('qName')) | |
107 | self.assertEquals(msg.question.qName, qname) | |
108 | ||
0096ada6 RG |
109 | def checkProtobufTags(self, tags, expectedTags): |
110 | # only differences will be in new list | |
111 | listx = set(tags) ^ set(expectedTags) | |
112 | # exclusive or of lists should be empty | |
113 | self.assertEqual(len(listx), 0, "Protobuf tags don't match") | |
741ebe08 | 114 | |
29cd61cc SO |
115 | def checkProtobufQueryConvertedToResponse(self, msg, protocol, response, initiator='127.0.0.0'): |
116 | self.assertEquals(msg.type, dnsmessage_pb2.PBDNSMessage.DNSResponseType) | |
0096ada6 RG |
117 | # skip comparing inBytes (size of the query) with the length of the generated response |
118 | self.checkProtobufBase(msg, protocol, response, initiator, False) | |
29cd61cc SO |
119 | self.assertTrue(msg.HasField('response')) |
120 | self.assertTrue(msg.response.HasField('queryTimeSec')) | |
121 | ||
8667904b | 122 | def checkProtobufResponse(self, msg, protocol, response, initiator='127.0.0.1'): |
29cd61cc | 123 | self.assertEquals(msg.type, dnsmessage_pb2.PBDNSMessage.DNSResponseType) |
8667904b | 124 | self.checkProtobufBase(msg, protocol, response, initiator) |
29cd61cc SO |
125 | self.assertTrue(msg.HasField('response')) |
126 | self.assertTrue(msg.response.HasField('queryTimeSec')) | |
741ebe08 | 127 | |
8667904b RG |
128 | def checkProtobufResponseRecord(self, record, rclass, rtype, rname, rttl): |
129 | self.assertTrue(record.HasField('class')) | |
130 | self.assertEquals(getattr(record, 'class'), rclass) | |
131 | self.assertTrue(record.HasField('type')) | |
132 | self.assertEquals(record.type, rtype) | |
133 | self.assertTrue(record.HasField('name')) | |
134 | self.assertEquals(record.name, rname) | |
135 | self.assertTrue(record.HasField('ttl')) | |
136 | self.assertEquals(record.ttl, rttl) | |
137 | self.assertTrue(record.HasField('rdata')) | |
138 | ||
f29fabd9 RG |
139 | class TestProtobuf(DNSDistProtobufTest): |
140 | _config_params = ['_testServerPort', '_protobufServerPort', '_protobufServerID', '_protobufServerID'] | |
141 | _config_template = """ | |
142 | luasmn = newSuffixMatchNode() | |
143 | luasmn:add(newDNSName('lua.protobuf.tests.powerdns.com.')) | |
144 | ||
145 | function alterProtobufResponse(dq, protobuf) | |
146 | if luasmn:check(dq.qname) then | |
147 | requestor = newCA(dq.remoteaddr:toString()) -- called by testLuaProtobuf() | |
148 | if requestor:isIPv4() then | |
149 | requestor:truncate(24) | |
150 | else | |
151 | requestor:truncate(56) | |
152 | end | |
153 | protobuf:setRequestor(requestor) | |
154 | ||
155 | local tableTags = {} | |
156 | table.insert(tableTags, "TestLabel1,TestData1") | |
157 | table.insert(tableTags, "TestLabel2,TestData2") | |
158 | ||
159 | protobuf:setTagArray(tableTags) | |
160 | ||
161 | protobuf:setTag('TestLabel3,TestData3') | |
162 | ||
163 | protobuf:setTag("Response,456") | |
164 | ||
165 | else | |
166 | ||
167 | local tableTags = {} -- called by testProtobuf() | |
168 | table.insert(tableTags, "TestLabel1,TestData1") | |
169 | table.insert(tableTags, "TestLabel2,TestData2") | |
170 | protobuf:setTagArray(tableTags) | |
171 | ||
172 | protobuf:setTag('TestLabel3,TestData3') | |
173 | ||
174 | protobuf:setTag("Response,456") | |
175 | ||
176 | end | |
177 | end | |
178 | ||
179 | function alterProtobufQuery(dq, protobuf) | |
180 | ||
181 | if luasmn:check(dq.qname) then | |
182 | requestor = newCA(dq.remoteaddr:toString()) -- called by testLuaProtobuf() | |
183 | if requestor:isIPv4() then | |
184 | requestor:truncate(24) | |
185 | else | |
186 | requestor:truncate(56) | |
187 | end | |
188 | protobuf:setRequestor(requestor) | |
189 | ||
190 | local tableTags = {} | |
191 | tableTags = dq:getTagArray() -- get table from DNSQuery | |
192 | ||
193 | local tablePB = {} | |
194 | for k, v in pairs( tableTags) do | |
195 | table.insert(tablePB, k .. "," .. v) | |
196 | end | |
197 | ||
198 | protobuf:setTagArray(tablePB) -- store table in protobuf | |
199 | protobuf:setTag("Query,123") -- add another tag entry in protobuf | |
200 | ||
d3ec24f9 | 201 | protobuf:setResponseCode(DNSRCode.NXDOMAIN) -- set protobuf response code to be NXDOMAIN |
f29fabd9 RG |
202 | |
203 | local strReqName = dq.qname:toString() -- get request dns name | |
204 | ||
205 | protobuf:setProtobufResponseType() -- set protobuf to look like a response and not a query, with 0 default time | |
206 | ||
207 | blobData = '\127' .. '\000' .. '\000' .. '\001' -- 127.0.0.1, note: lua 5.1 can only embed decimal not hex | |
208 | ||
209 | protobuf:addResponseRR(strReqName, 1, 1, 123, blobData) -- add a RR to the protobuf | |
210 | ||
211 | protobuf:setBytes(65) -- set the size of the query to confirm in checkProtobufBase | |
212 | ||
213 | else | |
214 | ||
215 | local tableTags = {} -- called by testProtobuf() | |
216 | table.insert(tableTags, "TestLabel1,TestData1") | |
217 | table.insert(tableTags, "TestLabel2,TestData2") | |
218 | ||
219 | protobuf:setTagArray(tableTags) | |
220 | protobuf:setTag('TestLabel3,TestData3') | |
221 | protobuf:setTag("Query,123") | |
222 | ||
223 | end | |
224 | end | |
225 | ||
226 | function alterLuaFirst(dq) -- called when dnsdist receives new request | |
227 | local tt = {} | |
228 | tt["TestLabel1"] = "TestData1" | |
229 | tt["TestLabel2"] = "TestData2" | |
230 | ||
231 | dq:setTagArray(tt) | |
232 | ||
233 | dq:setTag("TestLabel3","TestData3") | |
234 | return DNSAction.None, "" -- continue to the next rule | |
235 | end | |
236 | ||
237 | newServer{address="127.0.0.1:%s", useClientSubnet=true} | |
238 | rl = newRemoteLogger('127.0.0.1:%s') | |
239 | ||
240 | addAction(AllRule(), LuaAction(alterLuaFirst)) -- Add tags to DNSQuery first | |
241 | ||
242 | addAction(AllRule(), RemoteLogAction(rl, alterProtobufQuery, {serverID='%s'})) -- Send protobuf message before lookup | |
243 | ||
244 | addResponseAction(AllRule(), RemoteLogResponseAction(rl, alterProtobufResponse, true, {serverID='%s'})) -- Send protobuf message after lookup | |
245 | ||
246 | """ | |
247 | ||
1d0bd88a RG |
248 | def testProtobuf(self): |
249 | """ | |
250 | Protobuf: Send data to a protobuf server | |
251 | """ | |
29cd61cc | 252 | name = 'query.protobuf.tests.powerdns.com.' |
741ebe08 | 253 | |
165c9030 | 254 | target = 'target.protobuf.tests.powerdns.com.' |
1d0bd88a RG |
255 | query = dns.message.make_query(name, 'A', 'IN') |
256 | response = dns.message.make_response(query) | |
741ebe08 | 257 | |
1d0bd88a | 258 | rrset = dns.rrset.from_text(name, |
165c9030 RG |
259 | 3600, |
260 | dns.rdataclass.IN, | |
261 | dns.rdatatype.CNAME, | |
262 | target) | |
263 | response.answer.append(rrset) | |
741ebe08 | 264 | |
165c9030 | 265 | rrset = dns.rrset.from_text(target, |
1d0bd88a RG |
266 | 3600, |
267 | dns.rdataclass.IN, | |
268 | dns.rdatatype.A, | |
269 | '127.0.0.1') | |
270 | response.answer.append(rrset) | |
271 | ||
272 | (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) | |
273 | self.assertTrue(receivedQuery) | |
274 | self.assertTrue(receivedResponse) | |
275 | receivedQuery.id = query.id | |
276 | self.assertEquals(query, receivedQuery) | |
277 | self.assertEquals(response, receivedResponse) | |
278 | ||
279 | # let the protobuf messages the time to get there | |
280 | time.sleep(1) | |
281 | ||
282 | # check the protobuf message corresponding to the UDP query | |
283 | msg = self.getFirstProtobufMessage() | |
741ebe08 | 284 | |
29cd61cc | 285 | self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.UDP, query, dns.rdataclass.IN, dns.rdatatype.A, name) |
0096ada6 | 286 | self.checkProtobufTags(msg.response.tags, [u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Query,123"]) |
1d0bd88a RG |
287 | |
288 | # check the protobuf message corresponding to the UDP response | |
289 | msg = self.getFirstProtobufMessage() | |
0096ada6 RG |
290 | self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, response) |
291 | self.checkProtobufTags(msg.response.tags, [ u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Response,456"]) | |
29cd61cc | 292 | self.assertEquals(len(msg.response.rrs), 2) |
165c9030 RG |
293 | rr = msg.response.rrs[0] |
294 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 3600) | |
06b0e003 | 295 | self.assertEquals(rr.rdata.decode('utf-8'), target) |
165c9030 RG |
296 | rr = msg.response.rrs[1] |
297 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, target, 3600) | |
298 | self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '127.0.0.1') | |
1d0bd88a RG |
299 | |
300 | (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) | |
301 | self.assertTrue(receivedQuery) | |
302 | self.assertTrue(receivedResponse) | |
303 | receivedQuery.id = query.id | |
304 | self.assertEquals(query, receivedQuery) | |
305 | self.assertEquals(response, receivedResponse) | |
306 | ||
307 | # let the protobuf messages the time to get there | |
308 | time.sleep(1) | |
309 | ||
310 | # check the protobuf message corresponding to the TCP query | |
311 | msg = self.getFirstProtobufMessage() | |
29cd61cc | 312 | |
1d0bd88a | 313 | self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.TCP, query, dns.rdataclass.IN, dns.rdatatype.A, name) |
0096ada6 | 314 | self.checkProtobufTags(msg.response.tags, [u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Query,123"]) |
1d0bd88a RG |
315 | |
316 | # check the protobuf message corresponding to the TCP response | |
317 | msg = self.getFirstProtobufMessage() | |
0096ada6 RG |
318 | self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.TCP, response) |
319 | self.checkProtobufTags(msg.response.tags, [ u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Response,456"]) | |
165c9030 RG |
320 | self.assertEquals(len(msg.response.rrs), 2) |
321 | rr = msg.response.rrs[0] | |
322 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 3600) | |
06b0e003 | 323 | self.assertEquals(rr.rdata.decode('utf-8'), target) |
165c9030 RG |
324 | rr = msg.response.rrs[1] |
325 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, target, 3600) | |
326 | self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '127.0.0.1') | |
8667904b RG |
327 | |
328 | def testLuaProtobuf(self): | |
741ebe08 | 329 | |
8667904b RG |
330 | """ |
331 | Protobuf: Check that the Lua callback rewrote the initiator | |
332 | """ | |
333 | name = 'lua.protobuf.tests.powerdns.com.' | |
334 | query = dns.message.make_query(name, 'A', 'IN') | |
335 | response = dns.message.make_response(query) | |
336 | rrset = dns.rrset.from_text(name, | |
337 | 3600, | |
338 | dns.rdataclass.IN, | |
339 | dns.rdatatype.A, | |
340 | '127.0.0.1') | |
341 | response.answer.append(rrset) | |
342 | ||
741ebe08 | 343 | |
8667904b | 344 | (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) |
741ebe08 | 345 | |
29cd61cc SO |
346 | self.assertTrue(receivedQuery) |
347 | self.assertTrue(receivedResponse) | |
8667904b RG |
348 | receivedQuery.id = query.id |
349 | self.assertEquals(query, receivedQuery) | |
350 | self.assertEquals(response, receivedResponse) | |
351 | ||
741ebe08 | 352 | |
8667904b RG |
353 | # let the protobuf messages the time to get there |
354 | time.sleep(1) | |
355 | ||
356 | # check the protobuf message corresponding to the UDP query | |
357 | msg = self.getFirstProtobufMessage() | |
29cd61cc | 358 | |
0096ada6 RG |
359 | self.checkProtobufQueryConvertedToResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, response, '127.0.0.0') |
360 | self.checkProtobufTags(msg.response.tags, [ u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Query,123"]) | |
8667904b RG |
361 | |
362 | # check the protobuf message corresponding to the UDP response | |
363 | msg = self.getFirstProtobufMessage() | |
0096ada6 RG |
364 | self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, response, '127.0.0.0') |
365 | self.checkProtobufTags(msg.response.tags, [ u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Response,456"]) | |
8667904b RG |
366 | self.assertEquals(len(msg.response.rrs), 1) |
367 | for rr in msg.response.rrs: | |
368 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 3600) | |
369 | self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '127.0.0.1') | |
370 | ||
371 | (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) | |
372 | self.assertTrue(receivedQuery) | |
373 | self.assertTrue(receivedResponse) | |
374 | receivedQuery.id = query.id | |
375 | self.assertEquals(query, receivedQuery) | |
376 | self.assertEquals(response, receivedResponse) | |
377 | ||
378 | # let the protobuf messages the time to get there | |
379 | time.sleep(1) | |
380 | ||
381 | # check the protobuf message corresponding to the TCP query | |
382 | msg = self.getFirstProtobufMessage() | |
0096ada6 RG |
383 | self.checkProtobufQueryConvertedToResponse(msg, dnsmessage_pb2.PBDNSMessage.TCP, response, '127.0.0.0') |
384 | self.checkProtobufTags(msg.response.tags, [ u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Query,123"]) | |
8667904b RG |
385 | |
386 | # check the protobuf message corresponding to the TCP response | |
387 | msg = self.getFirstProtobufMessage() | |
0096ada6 RG |
388 | self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.TCP, response, '127.0.0.0') |
389 | self.checkProtobufTags(msg.response.tags, [ u"TestLabel1,TestData1", u"TestLabel2,TestData2", u"TestLabel3,TestData3", u"Response,456"]) | |
8667904b RG |
390 | self.assertEquals(len(msg.response.rrs), 1) |
391 | for rr in msg.response.rrs: | |
392 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 3600) | |
1d0bd88a | 393 | self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '127.0.0.1') |
f29fabd9 RG |
394 | |
395 | class TestProtobufIPCipher(DNSDistProtobufTest): | |
396 | _config_params = ['_testServerPort', '_protobufServerPort', '_protobufServerID', '_protobufServerID'] | |
397 | _config_template = """ | |
398 | newServer{address="127.0.0.1:%s", useClientSubnet=true} | |
399 | key = makeIPCipherKey("some 16-byte key") | |
400 | rl = newRemoteLogger('127.0.0.1:%s') | |
401 | addAction(AllRule(), RemoteLogAction(rl, nil, {serverID='%s', ipEncryptKey=key})) -- Send protobuf message before lookup | |
402 | addResponseAction(AllRule(), RemoteLogResponseAction(rl, nil, true, {serverID='%s', ipEncryptKey=key})) -- Send protobuf message after lookup | |
403 | ||
404 | """ | |
405 | ||
406 | def testProtobuf(self): | |
407 | """ | |
408 | Protobuf: Send data to a protobuf server | |
409 | """ | |
410 | name = 'query.protobuf-ipcipher.tests.powerdns.com.' | |
411 | ||
78603024 | 412 | target = 'target.protobuf-ipcipher.tests.powerdns.com.' |
f29fabd9 RG |
413 | query = dns.message.make_query(name, 'A', 'IN') |
414 | response = dns.message.make_response(query) | |
415 | ||
416 | rrset = dns.rrset.from_text(name, | |
417 | 3600, | |
418 | dns.rdataclass.IN, | |
419 | dns.rdatatype.CNAME, | |
420 | target) | |
421 | response.answer.append(rrset) | |
422 | ||
423 | rrset = dns.rrset.from_text(target, | |
424 | 3600, | |
425 | dns.rdataclass.IN, | |
426 | dns.rdatatype.A, | |
427 | '127.0.0.1') | |
428 | response.answer.append(rrset) | |
429 | ||
430 | (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) | |
431 | self.assertTrue(receivedQuery) | |
432 | self.assertTrue(receivedResponse) | |
433 | receivedQuery.id = query.id | |
434 | self.assertEquals(query, receivedQuery) | |
435 | self.assertEquals(response, receivedResponse) | |
436 | ||
437 | # let the protobuf messages the time to get there | |
438 | time.sleep(1) | |
439 | ||
440 | # check the protobuf message corresponding to the UDP query | |
441 | msg = self.getFirstProtobufMessage() | |
442 | ||
443 | # 108.41.239.98 is 127.0.0.1 pseudonymized with ipcipher and the current key | |
444 | self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.UDP, query, dns.rdataclass.IN, dns.rdatatype.A, name, '108.41.239.98') | |
445 | ||
446 | # check the protobuf message corresponding to the UDP response | |
447 | msg = self.getFirstProtobufMessage() | |
448 | self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, response, '108.41.239.98') | |
449 | ||
450 | self.assertEquals(len(msg.response.rrs), 2) | |
451 | rr = msg.response.rrs[0] | |
452 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 3600) | |
78603024 | 453 | self.assertEquals(rr.rdata.decode('ascii'), target) |
f29fabd9 RG |
454 | rr = msg.response.rrs[1] |
455 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, target, 3600) | |
456 | self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '127.0.0.1') | |
457 | ||
458 | (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) | |
459 | self.assertTrue(receivedQuery) | |
460 | self.assertTrue(receivedResponse) | |
461 | receivedQuery.id = query.id | |
462 | self.assertEquals(query, receivedQuery) | |
463 | self.assertEquals(response, receivedResponse) | |
464 | ||
465 | # let the protobuf messages the time to get there | |
466 | time.sleep(1) | |
467 | ||
468 | # check the protobuf message corresponding to the TCP query | |
469 | msg = self.getFirstProtobufMessage() | |
470 | # 108.41.239.98 is 127.0.0.1 pseudonymized with ipcipher and the current key | |
471 | self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.TCP, query, dns.rdataclass.IN, dns.rdatatype.A, name, '108.41.239.98') | |
472 | ||
473 | # check the protobuf message corresponding to the TCP response | |
474 | msg = self.getFirstProtobufMessage() | |
475 | self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.TCP, response, '108.41.239.98') | |
476 | self.assertEquals(len(msg.response.rrs), 2) | |
477 | rr = msg.response.rrs[0] | |
478 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.CNAME, name, 3600) | |
78603024 | 479 | self.assertEquals(rr.rdata.decode('ascii'), target) |
f29fabd9 RG |
480 | rr = msg.response.rrs[1] |
481 | self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, target, 3600) | |
482 | self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '127.0.0.1') |