Exemple #1
0
        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)
Exemple #2
0
        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=(),
    )
Exemple #4
0
 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)
Exemple #5
0
    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=(),
        )
Exemple #7
0
    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)