async def get_response(query_data): query = parse(query_data) response_record = ResourceRecord( name=query.qd[0].name, qtype=TYPES.A, qclass=1, ttl=0, rdata=ipaddress.IPv4Address('123.100.123.1').packed, ) response = Message( qid=query.qid, qr=RESPONSE, opcode=0, aa=0, tc=0, rd=0, ra=1, z=0, rcode=0, qd=query.qd, an=(response_record, ), ns=(), ar=(), ) received_request.set() await continue_request.wait() return pack(response)
async def get_response(query_data): query = parse(query_data) response_records = tuple( ResourceRecord( name=query.qd[0].name, qtype=TYPES.A, qclass=1, ttl=0, rdata=ipaddress.IPv4Address('123.100.123.' + str(i)).packed, ) for i in range(0, num_records)) response = Message( qid=query.qid, qr=RESPONSE, opcode=0, aa=0, tc=0, rd=0, ra=1, z=0, rcode=0, qd=query.qd, an=response_records, ns=(), ar=(), ) return pack(response)
def error(query, rcode): return Message( qid=query.qid, qr=RESPONSE, opcode=0, aa=0, tc=0, rd=0, ra=1, z=0, rcode=rcode, qd=query.qd, an=(), ns=(), ar=(), )
async def get_response(query_data): query = parse(query_data) response = Message( qid=query.qid, qr=RESPONSE, opcode=0, aa=0, tc=0, rd=0, ra=1, z=0, rcode=rcode, qd=query.qd, an=(), ns=(), ar=(), ) return pack(response)
async def test_sending_lots_of_good_messages_not_affect_later_queries( self): resolve, clear_cache = get_resolver(53) self.add_async_cleanup(clear_cache) start = DnsProxy(rules=((r'(^.*$)', r'\1'), )) server_task = await start() self.add_async_cleanup(await_cancel, server_task) response = await resolve('www.google.com', TYPES.A) self.assertEqual(type(response[0]), IPv4AddressExpiresAt) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for i in range(0, 100000): name = b'doesnotexist' + str(i).encode('ascii') + b'.charemza.name' question_record = QuestionRecord(name, TYPES.A, qclass=1) question = Message( qid=i % 65535, qr=QUESTION, opcode=0, aa=0, tc=0, rd=0, ra=1, z=0, rcode=0, qd=(question_record, ), an=(), ns=(), ar=(), ) sock.sendto(pack(question), ('127.0.0.1', 53)) sock.close() response = await resolve('www.google.com', TYPES.A) self.assertEqual(type(response[0]), IPv4AddressExpiresAt)
async def proxy(request_logger, resolve, query): name_bytes = query.qd[0].name request_logger.info('Name: %s', name_bytes) name_str_lower = query.qd[0].name.lower().decode('idna') request_logger.info('Decoded: %s', name_str_lower) if query.qd[0].qtype != TYPES.A: request_logger.info('Unhandled query type: %s', query.qd[0].qtype) return error(query, ERRORS.REFUSED) for pattern, replace in rules: rewritten_name_str, num_matches = re.subn(pattern, replace, name_str_lower) if num_matches: request_logger.info('Matches rule (%s, %s)', pattern, replace) break else: # No break was triggered, i.e. no match request_logger.info('Does not match a rule') return error(query, ERRORS.REFUSED) try: ip_addresses = await resolve( rewritten_name_str, TYPES.A, get_logger_adapter=get_resolver_logger_adapter(request_logger)) except DnsRecordDoesNotExist: request_logger.info('Does not exist') return error(query, ERRORS.NXDOMAIN) except DnsResponseCode as dns_response_code_error: request_logger.info('Received error from upstream: %s', dns_response_code_error.args[0]) return error(query, dns_response_code_error.args[0]) request_logger.info('Resolved to %s', ip_addresses) now = loop.time() def ttl(ip_address): return int(max(0.0, ip_address.expires_at - now)) reponse_records = tuple( ResourceRecord(name=name_bytes, qtype=TYPES.A, qclass=1, ttl=ttl(ip_address), rdata=ip_address.packed) for ip_address in ip_addresses) return Message( qid=query.qid, qr=RESPONSE, opcode=0, aa=0, tc=0, rd=0, ra=1, z=0, rcode=0, qd=query.qd, an=reponse_records, ns=(), ar=(), )
async def test_sending_pointer_loop_not_affect_later_queries_c(self): resolve, clear_cache = get_resolver(53) self.add_async_cleanup(clear_cache) start = DnsProxy(rules=((r'(^.*$)', r'\1'), )) server_task = await start() self.add_async_cleanup(await_cancel, server_task) response = await resolve('www.google.com', TYPES.A) self.assertEqual(type(response[0]), IPv4AddressExpiresAt) name = b'mydomain.com' question_record = QuestionRecord(name, TYPES.A, qclass=1) record_1 = ResourceRecord( name=name, qtype=TYPES.A, qclass=1, ttl=0, rdata=ipaddress.IPv4Address('123.100.124.1').packed, ) response = Message( qid=1, qr=RESPONSE, opcode=0, aa=0, tc=0, rd=0, ra=1, z=0, rcode=0, qd=(question_record, ), an=(record_1, ), ns=(), ar=(), ) data = pack(response) packed_name = b''.join( component for label in name.split(b'.') for component in (bytes([len(label)]), label)) + b'\0' occurance_1 = data.index(packed_name) occurance_1_end = occurance_1 + len(packed_name) occurance_2 = occurance_1_end + data[occurance_1_end:].index( packed_name) occurance_2_end = occurance_2 + len(packed_name) data_compressed = \ data[:occurance_2] + \ struct.pack('!H', (192 * 256) + occurance_2 + 4) + \ struct.pack('!H', (192 * 256) + occurance_2) + \ struct.pack('!H', (192 * 256) + occurance_2 + 2) + \ data[occurance_2_end:] sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(data_compressed, ('127.0.0.1', 53)) sock.close() tasks = [ asyncio.create_task(resolve('www.google.com', TYPES.A)) for _ in range(0, 100000) ] responses = await asyncio.gather(*tasks) for response in responses: self.assertEqual(type(response[0]), IPv4AddressExpiresAt)