def test_followCanonicalName(self):
     """
     If no record of the requested type is included in a response, but a
     I{CNAME} record for the query name is included, queries are made to
     resolve the value of the I{CNAME}.
     """
     servers = {
         ('1.1.2.3', 53): {
             ('example.com', A): {
                 'answers': [('example.com', Record_CNAME('example.net'))],
             },
             ('example.net', A): {
                 'answers': [('example.net', Record_A('10.0.0.5'))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress('example.com')
     d.addCallback(lambda (ans, auth, add): ans)
     d.addCallback(self.assertEquals, [
         RRHeader('example.com', CNAME,
                  payload=Record_CNAME('example.net')),
         RRHeader('example.net', A, payload=Record_A('10.0.0.5'))
     ])
     return d
 def test_returnCanonicalName(self):
     """
     If a I{CNAME} record is encountered as the answer to a query for
     another record type, that record is returned as the answer.
     """
     servers = {
         ("1.1.2.3", 53): {
             (b"example.com", A): {
                 "answers": [
                     (b"example.com", Record_CNAME(b"example.net")),
                     (b"example.net", Record_A("10.0.0.7")),
                 ],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress(b"example.com")
     d.addCallback(lambda results: results[0])  # Get the answer section
     d.addCallback(
         self.assertEqual,
         [
             RRHeader(b"example.com",
                      CNAME,
                      payload=Record_CNAME(b"example.net")),
             RRHeader(b"example.net", A, payload=Record_A("10.0.0.7")),
         ],
     )
     return d
 def test_followCanonicalName(self):
     """
     If no record of the requested type is included in a response, but a
     I{CNAME} record for the query name is included, queries are made to
     resolve the value of the I{CNAME}.
     """
     servers = {
         ("1.1.2.3", 53): {
             (b"example.com", A): {
                 "answers":
                 [(b"example.com", Record_CNAME(b"example.net"))],
             },
             (b"example.net", A): {
                 "answers": [(b"example.net", Record_A("10.0.0.5"))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress(b"example.com")
     d.addCallback(lambda results: results[0])  # Get the answer section
     d.addCallback(
         self.assertEqual,
         [
             RRHeader(b"example.com",
                      CNAME,
                      payload=Record_CNAME(b"example.net")),
             RRHeader(b"example.net", A, payload=Record_A("10.0.0.5")),
         ],
     )
     return d
예제 #4
0
 def resolved(results):
     answers, authority, additional = results
     self.assertEqual((RRHeader(b"multiple", A, IN, self.ttl,
                                Record_A("1.1.1.3", self.ttl)),
                       RRHeader(b"multiple", A, IN, self.ttl,
                                Record_A("1.1.1.4", self.ttl))),
                      answers)
예제 #5
0
 def resolved(results):
     answers, authority, additional = results
     self.assertEqual(
         (RRHeader(b"ip6-multiple", AAAA, IN, self.ttl,
                   Record_AAAA("::3", self.ttl)),
          RRHeader(b"ip6-multiple", AAAA, IN, self.ttl,
                   Record_AAAA("::4", self.ttl))),
         answers)
예제 #6
0
 def test_lookupIPV6Address(self):
     """
     L{hosts.Resolver.lookupIPV6Address} returns a L{Deferred} which fires
     with AAAA records from the hosts file.
     """
     d = self.resolver.lookupIPV6Address(b'ip6-multiple')
     answers, authority, additional = self.successResultOf(d)
     self.assertEqual((RRHeader(b"ip6-multiple", AAAA, IN, self.ttl,
                                Record_AAAA("::3", self.ttl)),
                       RRHeader(b"ip6-multiple", AAAA, IN, self.ttl,
                                Record_AAAA("::4", self.ttl))), answers)
def test_infer_search_domains(resolver):
    """
    ``LocalResolver`` uses a number of DNS queries sent to it as probes to
    infer the search domains configured for the client.
    """
    probe = u"hellotelepresence"
    counter = count(0)
    for search in [u".foo", u".foo.bar", u".alternate"]:
        for i in range(3):
            name = u"{}{}{}".format(
                probe,
                next(counter),
                search,
            ).encode("ascii")
            rrheader = RRHeader(
                name=name,
                payload=Record_A(address=b"127.0.0.1"),
            )
            expected = ([rrheader], [], [])
            result = resolver.query(Query(name))
            assert expected == result

    for search in [u".foo", u".foo.bar", u".alternate"]:
        mangled = (u"example.com" + search).encode("ascii").split(b".")
        assert [b"example", b"com"] == resolver._strip_search_suffix(mangled)
    def _respond(self, answers=[], authority=[], additional=[], rCode=OK):
        """
        Create a L{Message} suitable for use as a response to a query.

        @param answers: A C{list} of two-tuples giving data for the answers
            section of the message.  The first element of each tuple is a name
            for the L{RRHeader}.  The second element is the payload.
        @param authority: A C{list} like C{answers}, but for the authority
            section of the response.
        @param additional: A C{list} like C{answers}, but for the
            additional section of the response.
        @param rCode: The response code the message will be created with.

        @return: A new L{Message} initialized with the given values.
        """
        response = Message(rCode=rCode)
        for (section, data) in [
            (response.answers, answers),
            (response.authority, authority),
            (response.additional, additional),
        ]:
            section.extend([
                RRHeader(name,
                         record.TYPE,
                         getattr(record, "CLASS", IN),
                         payload=record) for (name, record) in data
            ])
        return response
예제 #9
0
    def test_lookupAddress(self):
        """
        L{SecondaryAuthority.lookupAddress} returns a L{Deferred} that fires
        with the I{A} records the authority has cached from the primary.
        """
        secondary = SecondaryAuthority.fromServerAddressAndDomain(
            ("192.168.1.2", 1234), b"example.com")
        secondary._reactor = reactor = MemoryReactorClock()

        secondary.transfer()

        host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0)

        proto = factory.buildProtocol((host, port))
        transport = StringTransport()
        proto.makeConnection(transport)

        query = Message(answer=1, auth=1)
        query.decode(BytesIO(transport.value()[2:]))

        # Generate a response with some data we can check.
        soa = Record_SOA(
            mname=b"ns1.example.com",
            rname="admin.example.com",
            serial=123456,
            refresh=3600,
            minimum=4800,
            expire=7200,
            retry=9600,
            ttl=12000,
        )
        a = Record_A(b"192.168.1.2", ttl=0)
        answer = Message(id=query.id, answer=1, auth=1)
        answer.answers.extend([
            RRHeader(b"example.com", type=SOA, payload=soa),
            RRHeader(b"example.com", payload=a),
            RRHeader(b"example.com", type=SOA, payload=soa),
        ])

        data = answer.toStr()
        proto.dataReceived(pack("!H", len(data)) + data)

        result = self.successResultOf(secondary.lookupAddress("example.com"))
        self.assertEqual(
            ([RRHeader(b"example.com", payload=a, auth=True)], [], []), result)
예제 #10
0
 def test_lookupAllRecords(self):
     """
     L{hosts.Resolver.lookupAllRecords} returns a L{Deferred} which fires
     with A records from the hosts file.
     """
     d = self.resolver.lookupAllRecords(b'mixed')
     answers, authority, additional = self.successResultOf(d)
     self.assertEqual((RRHeader(b"mixed", A, IN, self.ttl,
                                Record_A("1.1.1.2", self.ttl)), ), answers)
예제 #11
0
파일: mx.py 프로젝트: CXM-JV/cloud-mailing
 def getMX(self, domain):
     return defer.succeed([
         RRHeader(name=domain,
                  type=Record_MX.TYPE,
                  payload=Record_MX(
                      1,
                      'localhost',
                  ))
     ])
예제 #12
0
 def test_lookupIPV6Malformed(self):
     """
     Like L{test_lookupAddressMalformed}, but for
     L{hosts.Resolver.lookupIPV6Address}.
     """
     d = self.resolver.lookupIPV6Address(b"malformed")
     [answer], authority, additional = self.successResultOf(d)
     self.assertEqual(
         RRHeader(b"malformed", AAAA, IN, self.ttl, Record_AAAA("::5", self.ttl)),
         answer,
     )
예제 #13
0
 def test_lookupMalformed(self):
     """
     L{hosts.Resolver.lookupAddress} returns a L{Deferred} which fires with
     the valid addresses from the hosts file, ignoring any entries that
     aren't valid IP addresses.
     """
     d = self.resolver.lookupAddress(b"malformed")
     [answer], authority, additional = self.successResultOf(d)
     self.assertEqual(
         RRHeader(b"malformed", A, IN, self.ttl, Record_A("1.1.1.5", self.ttl)),
         answer,
     )
 def test_filteredQuery(self):
     """
     L{Resolver._query} accepts a L{Query} instance and an address, issues
     the query, and returns a L{Deferred} which fires with the response to
     the query.  If a true value is passed for the C{filter} parameter, the
     result is a three-tuple of lists of records.
     """
     answer, authority, additional = self._queryTest(True)
     self.assertEqual(answer, [
         RRHeader(b"foo.example.com", payload=Record_A("5.8.13.21", ttl=0))
     ])
     self.assertEqual(authority, [])
     self.assertEqual(additional, [])
 def test_returnCanonicalName(self):
     """
     If a I{CNAME} record is encountered as the answer to a query for
     another record type, that record is returned as the answer.
     """
     servers = {
         ('1.1.2.3', 53): {
             ('example.com', A): {
                 'answers': [('example.com', Record_CNAME('example.net')),
                             ('example.net', Record_A('10.0.0.7'))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress('example.com')
     d.addCallback(lambda (ans, auth, add): ans)
     d.addCallback(self.assertEquals, [
         RRHeader('example.com', CNAME,
                  payload=Record_CNAME('example.net')),
         RRHeader('example.net', A, payload=Record_A('10.0.0.7'))
     ])
     return d
예제 #16
0
 def test_unfilteredQuery(self):
     """
     Similar to L{test_filteredQuery}, but for the case where a false value
     is passed for the C{filter} parameter.  In this case, the result is a
     L{Message} instance.
     """
     message = self._queryTest(False)
     self.assertIsInstance(message, Message)
     self.assertEqual(message.queries, [])
     self.assertEqual(message.answers, [
         RRHeader(b'foo.example.com', payload=Record_A('5.8.13.21', ttl=0))
     ])
     self.assertEqual(message.authority, [])
     self.assertEqual(message.additional, [])
예제 #17
0
    def _queryTest(self, filter):
        """
        Invoke L{Resolver._query} and verify that it sends the correct DNS
        query.  Deliver a canned response to the query and return whatever the
        L{Deferred} returned by L{Resolver._query} fires with.

        @param filter: The value to pass for the C{filter} parameter to
            L{Resolver._query}.
        """
        reactor = MemoryReactor()
        resolver = Resolver([], reactor=reactor)
        d = resolver._query(
            Query(b'foo.example.com', A, IN), [('1.1.2.3', 1053)], (30,),
            filter)

        # A UDP port should have been started.
        portNumber, transport = reactor.udpPorts.popitem()

        # And a DNS packet sent.
        [(packet, address)] = transport._sentPackets

        message = Message()
        message.fromStr(packet)

        # It should be a query with the parameters used above.
        self.assertEqual(message.queries, [Query(b'foo.example.com', A, IN)])
        self.assertEqual(message.answers, [])
        self.assertEqual(message.authority, [])
        self.assertEqual(message.additional, [])

        response = []
        d.addCallback(response.append)
        self.assertEqual(response, [])

        # Once a reply is received, the Deferred should fire.
        del message.queries[:]
        message.answer = 1
        message.answers.append(RRHeader(
            b'foo.example.com', payload=Record_A('5.8.13.21')))
        transport._protocol.datagramReceived(
            message.toStr(), ('1.1.2.3', 1053))
        return response[0]
예제 #18
0
파일: dns.py 프로젝트: excitedleigh/lo0dns
async def get_response(query: Query):
    name = query.name.name
    if name.endswith(b'.'): name = name[:-1]
    if not name.endswith(b'.lo0.wtf'): raise DomainError()
    results = []
    if query.type in (AAAA, ALL_RECORDS):
        name = name[:-8]
        vhost, username = name.rsplit(b'.', 1)
        vhost_hash = CityHash32(vhost)
        username_hash = CityHash32(username)
        ip = NETWORK[(username_hash << 32) + vhost_hash]
        results.append(
            RRHeader(
                name=query.name.name,
                type=AAAA,
                ttl=60,
                payload=Record_AAAA(address=str(ip).encode('ascii')),
            ))
    if query.type in (SOA, ALL_RECORDS) and name == b'':
        results.append(SOA_OBJ)
    return results
예제 #19
0
파일: dns.py 프로젝트: excitedleigh/lo0dns
            return [], [], []
        return answers, [], []

    @ensure_returns_deferred
    async def lookupAllRecords(self, name, timeout=None):
        query = Query(name, type=ALL_RECORDS)
        answers = await self.callback(query)
        return answers, [], []


SOA_OBJ = RRHeader(name='lo0.wtf',
                   type=SOA,
                   ttl=60,
                   payload=Record_SOA(
                       mname='lo0-ns1.leigh.party',
                       rname='l.leigh.net.au',
                       serial=int(time() / 10),
                       refresh=60,
                       retry=60,
                       expire=60,
                       minimum=60,
                   ))


async def get_response(query: Query):
    name = query.name.name
    if name.endswith(b'.'): name = name[:-1]
    if not name.endswith(b'.lo0.wtf'): raise DomainError()
    results = []
    if query.type in (AAAA, ALL_RECORDS):
        name = name[:-8]
        vhost, username = name.rsplit(b'.', 1)
예제 #20
0
 def make_soa_result(self, serial):
     return RRHeader(type=SOA,
                     cls=A,
                     ttl=30,
                     payload=Record_SOA(serial=serial))
예제 #21
0
 def resolved(results):
     answers, authority, additional = results
     self.assertEqual(
         (RRHeader(b"mixed", A, IN, self.ttl,
                   Record_A("1.1.1.2", self.ttl)),),
         answers)
예제 #22
0
 def resolved((results, authority, additional)):
     self.assertEqual((RRHeader("multiple", A, IN, self.ttl,
                                Record_A("1.1.1.3", self.ttl)),
                       RRHeader("multiple", A, IN, self.ttl,
                                Record_A("1.1.1.4", self.ttl))),
                      results)
예제 #23
0
 def resolved((results, authority, additional)):
     self.assertEqual((RRHeader("mixed", A, IN, self.ttl,
                                Record_A("1.1.1.2", self.ttl)), ),
                      results)
예제 #24
0
 def resolved((results, authority, additional)):
     self.assertEqual((RRHeader("ip6-multiple", AAAA, IN, self.ttl,
                                Record_AAAA("::3", self.ttl)),
                       RRHeader("ip6-multiple", AAAA, IN, self.ttl,
                                Record_AAAA("::4", self.ttl))), results)