예제 #1
0
 def test_lookupChecksClass(self):
     """
     If a response includes a record with a class different from the one
     in the query, it is ignored and lookup continues until a record with
     the right class is found.
     """
     badClass = Record_A('10.0.0.1')
     badClass.CLASS = HS
     servers = {
         ('1.1.2.3', 53): {
             ('foo.example.com', A): {
                 'answers': [('foo.example.com', badClass)],
                 'authority': [('foo.example.com', Record_NS('ns1.example.com'))],
                 'additional': [('ns1.example.com', Record_A('10.0.0.2'))],
             },
         },
         ('10.0.0.2', 53): {
             ('foo.example.com', A): {
                 'answers': [('foo.example.com', Record_A('10.0.0.3'))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress('foo.example.com')
     d.addCallback(lambda (ans, auth, add): ans[0].payload)
     d.addCallback(self.assertEquals, Record_A('10.0.0.3'))
     return d
 def test_missingGlue(self):
     """
     If an intermediate response includes no glue records for the
     authorities, separate queries are made to find those addresses.
     """
     servers = {
         ("1.1.2.3", 53): {
             (b"foo.example.com", A): {
                 "authority":
                 [(b"foo.example.com", Record_NS(b"ns1.example.org"))],
                 # Conspicuous lack of an additional section naming ns1.example.com
             },
             (b"ns1.example.org", A): {
                 "answers": [(b"ns1.example.org", Record_A("10.0.0.1"))],
             },
         },
         ("10.0.0.1", 53): {
             (b"foo.example.com", A): {
                 "answers": [(b"foo.example.com", Record_A("10.0.0.2"))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress(b"foo.example.com")
     d.addCallback(getOneAddress)
     d.addCallback(self.assertEqual, "10.0.0.2")
     return d
 def test_lookupAddress(self):
     """
     L{root.Resolver.lookupAddress} looks up the I{A} records for the
     specified hostname by first querying one of the root servers the
     resolver was created with and then following the authority delegations
     until a result is received.
     """
     servers = {
         ("1.1.2.3", 53): {
             (b"foo.example.com", A): {
                 "authority":
                 [(b"foo.example.com", Record_NS(b"ns1.example.com"))],
                 "additional":
                 [(b"ns1.example.com", Record_A("34.55.89.144"))],
             },
         },
         ("34.55.89.144", 53): {
             (b"foo.example.com", A): {
                 "answers": [(b"foo.example.com", Record_A("10.0.0.1"))],
             }
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress(b"foo.example.com")
     d.addCallback(getOneAddress)
     d.addCallback(self.assertEqual, "10.0.0.1")
     return d
예제 #4
0
 def test_missingGlue(self):
     """
     If an intermediate response includes no glue records for the
     authorities, separate queries are made to find those addresses.
     """
     servers = {
         ('1.1.2.3', 53): {
             (b'foo.example.com', A): {
                 'authority':
                 [(b'foo.example.com', Record_NS(b'ns1.example.org'))],
                 # Conspicuous lack of an additional section naming ns1.example.com
             },
             (b'ns1.example.org', A): {
                 'answers': [(b'ns1.example.org', Record_A('10.0.0.1'))],
             },
         },
         ('10.0.0.1', 53): {
             (b'foo.example.com', A): {
                 'answers': [(b'foo.example.com', Record_A('10.0.0.2'))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress(b'foo.example.com')
     d.addCallback(getOneAddress)
     d.addCallback(self.assertEqual, '10.0.0.2')
     return d
예제 #5
0
 def test_lookupAddress(self):
     """
     L{root.Resolver.lookupAddress} looks up the I{A} records for the
     specified hostname by first querying one of the root servers the
     resolver was created with and then following the authority delegations
     until a result is received.
     """
     servers = {
         ('1.1.2.3', 53): {
             (b'foo.example.com', A): {
                 'authority':
                 [(b'foo.example.com', Record_NS(b'ns1.example.com'))],
                 'additional':
                 [(b'ns1.example.com', Record_A('34.55.89.144'))],
             },
         },
         ('34.55.89.144', 53): {
             (b'foo.example.com', A): {
                 'answers': [(b'foo.example.com', Record_A('10.0.0.1'))],
             }
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress(b'foo.example.com')
     d.addCallback(getOneAddress)
     d.addCallback(self.assertEqual, '10.0.0.1')
     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): {
             ('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_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
 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
예제 #9
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)
예제 #10
0
 def test_lookupAddress(self):
     """
     L{hosts.Resolver.lookupAddress} returns a L{Deferred} which fires with A
     records from the hosts file.
     """
     d = self.resolver.lookupAddress(b'multiple')
     answers, authority, additional = self.successResultOf(d)
     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)
    def test_boundedQueries(self):
        """
        L{Resolver.lookupAddress} won't issue more queries following
        delegations than the limit passed to its initializer.
        """
        servers = {
            ("1.1.2.3", 53): {
                # First query - force it to start over with a name lookup of
                # ns1.example.com
                (b"example.com", A): {
                    "authority":
                    [(b"example.com", Record_NS(b"ns1.example.com"))],
                },
                # Second query - let it resume the original lookup with the
                # address of the nameserver handling the delegation.
                (b"ns1.example.com", A): {
                    "answers": [(b"ns1.example.com", Record_A("10.0.0.2"))],
                },
            },
            ("10.0.0.2", 53): {
                # Third query - let it jump straight to asking the
                # delegation server by including its address here (different
                # case from the first query).
                (b"example.com", A): {
                    "authority":
                    [(b"example.com", Record_NS(b"ns2.example.com"))],
                    "additional": [(b"ns2.example.com", Record_A("10.0.0.3"))],
                },
            },
            ("10.0.0.3", 53): {
                # Fourth query - give it the answer, we're done.
                (b"example.com", A): {
                    "answers": [(b"example.com", Record_A("10.0.0.4"))],
                },
            },
        }

        # Make two resolvers.  One which is allowed to make 3 queries
        # maximum, and so will fail, and on which may make 4, and so should
        # succeed.
        failer = self._getResolver(servers, 3)
        failD = self.assertFailure(failer.lookupAddress(b"example.com"),
                                   ResolverError)

        succeeder = self._getResolver(servers, 4)
        succeedD = succeeder.lookupAddress(b"example.com")
        succeedD.addCallback(getOnePayload)
        succeedD.addCallback(self.assertEqual, Record_A("10.0.0.4"))

        return gatherResults([failD, succeedD])
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)
예제 #13
0
def addSubdomains(host, zone, subs):
    """
    Add the given subdomain mapping to the given zone list.
    """
    for (ip, hosts) in subs.items():
        for sub in hosts:
            zone.append((sub + host, Record_A(ip, ttl="5M")))
예제 #14
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,
     )
예제 #15
0
 def test_lookupChecksClass(self):
     """
     If a response includes a record with a class different from the one
     in the query, it is ignored and lookup continues until a record with
     the right class is found.
     """
     badClass = Record_A('10.0.0.1')
     badClass.CLASS = HS
     servers = {
         ('1.1.2.3', 53): {
             ('foo.example.com', A): {
                 'answers': [('foo.example.com', badClass)],
                 'authority':
                 [('foo.example.com', Record_NS('ns1.example.com'))],
                 'additional': [('ns1.example.com', Record_A('10.0.0.2'))],
             },
         },
         ('10.0.0.2', 53): {
             ('foo.example.com', A): {
                 'answers': [('foo.example.com', Record_A('10.0.0.3'))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress('foo.example.com')
     d.addCallback(getOnePayload)
     d.addCallback(self.assertEqual, Record_A('10.0.0.3'))
     return d
 def test_lookupChecksClass(self):
     """
     If a response includes a record with a class different from the one
     in the query, it is ignored and lookup continues until a record with
     the right class is found.
     """
     badClass = Record_A("10.0.0.1")
     badClass.CLASS = HS
     servers = {
         ("1.1.2.3", 53): {
             (b"foo.example.com", A): {
                 "answers": [(b"foo.example.com", badClass)],
                 "authority":
                 [(b"foo.example.com", Record_NS(b"ns1.example.com"))],
                 "additional": [(b"ns1.example.com", Record_A("10.0.0.2"))],
             },
         },
         ("10.0.0.2", 53): {
             (b"foo.example.com", A): {
                 "answers": [(b"foo.example.com", Record_A("10.0.0.3"))],
             },
         },
     }
     resolver = self._getResolver(servers)
     d = resolver.lookupAddress(b"foo.example.com")
     d.addCallback(getOnePayload)
     d.addCallback(self.assertEqual, Record_A("10.0.0.3"))
     return d
예제 #17
0
def nameservers(host, *addresses):
    """
    Return NS records and A record glue for the given host.
    """
    if not addresses:
        addresses = [dornkirk, ns2]
    records = []
    for i, addr in enumerate(addresses):
        records.extend([
            (host, Record_NS('ns%d.twistedmatrix.com' % (i + 1, ), ttl='1H')),
            ('ns%d.twistedmatrix.com' % (i + 1, ), Record_A(addr, ttl='1H'))
        ])
    return records
 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
예제 #20
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, [])
예제 #21
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)
예제 #22
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]
예제 #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("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)
예제 #25
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)