Example #1
0
    def test_name_error(self):
        dns_client_mock = Mock()

        dns_client_mock.lookupService.return_value = defer.fail(error.DNSNameError())

        service_name = b"test_service.example.com"

        cache = {}
        resolver = SrvResolver(dns_client=dns_client_mock, cache=cache)

        servers = yield defer.ensureDeferred(resolver.resolve_service(service_name))

        self.assertEqual(len(servers), 0)
        self.assertEqual(len(cache), 0)
Example #2
0
File: client.py Project: uda/ddns
 def return_record(record):
     if isinstance(record, six.string_types):
         record = record.strip()
         if '\x1e' in record:
             record = random.choice(record.split('\x1e'))
     if record:
         return defer.succeed([
             (dns.RRHeader(name=name,
                           ttl=self.ttl,
                           payload=dns.Record_A(record, self.ttl),
                           auth=True), ), (), ()
         ])
     else:
         return defer.fail(error.DNSNameError(name))
Example #3
0
    def test_name_error(self):
        dns_client_mock = Mock()

        dns_client_mock.lookupService.return_value = defer.fail(error.DNSNameError())

        service_name = "test_service.examle.com"

        cache = {}

        servers = yield resolve_service(
            service_name, dns_client=dns_client_mock, cache=cache
        )

        self.assertEquals(len(servers), 0)
        self.assertEquals(len(cache), 0)
Example #4
0
    def _cbMX(self, answers, domain, cnamesLeft):
        """
        Try to find the mail exchange host for a domain from the given DNS
        records.

        This will attempt to resolve canonical name record results.  It can
        recognize loops and will give up on non-cyclic chains after a specified
        number of lookups.

        @type answers: L{dict} mapping L{bytes} to L{list} of L{IRecord
            <twisted.names.dns.IRecord>} provider
        @param answers: A mapping of record name to record payload.

        @type domain: L{bytes}
        @param domain: A domain name.

        @type cnamesLeft: L{int}
        @param cnamesLeft: The number of unique canonical name records
            left to follow while looking up the mail exchange host.

        @rtype: L{Record_MX <twisted.names.dns.Record_MX>} or L{Failure}
        @return: An MX record for the mail exchange host or a failure if one
            cannot be found.
        """
        # Do this import here so that relaymanager.py doesn't depend on
        # twisted.names, only MXCalculator will.
        from twisted.names import dns, error

        seenAliases = set()
        exchanges = []
        # Examine the answers for the domain we asked about
        pertinentRecords = answers.get(domain, [])
        while pertinentRecords:
            record = pertinentRecords.pop()

            # If it's a CNAME, we'll need to do some more processing
            if record.TYPE == dns.CNAME:

                # Remember that this name was an alias.
                seenAliases.add(domain)

                canonicalName = str(record.name)
                # See if we have some local records which might be relevant.
                if canonicalName in answers:

                    # Make sure it isn't a loop contained entirely within the
                    # results we have here.
                    if canonicalName in seenAliases:
                        return Failure(CanonicalNameLoop(record))

                    pertinentRecords = answers[canonicalName]
                    exchanges = []
                else:
                    if cnamesLeft:
                        # Request more information from the server.
                        return self.getMX(canonicalName, cnamesLeft - 1)
                    else:
                        # Give up.
                        return Failure(CanonicalNameChainTooLong(record))

            # If it's an MX, collect it.
            if record.TYPE == dns.MX:
                exchanges.append((record.preference, record))

        if exchanges:
            exchanges.sort()
            for (preference, record) in exchanges:
                host = str(record.name)
                if host not in self.badMXs:
                    return record
                t = self.clock.seconds() - self.badMXs[host]
                if t >= 0:
                    del self.badMXs[host]
                    return record
            return exchanges[0][1]
        else:
            # Treat no answers the same as an error - jump to the errback to
            # try to look up an A record.  This provides behavior described as
            # a special case in RFC 974 in the section headed I{Interpreting
            # the List of MX RRs}.
            return Failure(error.DNSNameError(f"No MX records for {domain!r}"))
Example #5
0
 def _lookup(self, name, cls, qtype, timeout):
     return defer.fail(error.DNSNameError([]))
Example #6
0
    def _cbMX(self, answers, domain, cnamesLeft):
        """
        Try to find the MX host from the given DNS information.

        This will attempt to resolve CNAME results.  It can recognize loops
        and will give up on non-cyclic chains after a specified number of
        lookups.
        """
        # Do this import here so that relaymanager.py doesn't depend on
        # twisted.names, only MXCalculator will.
        from twisted.names import dns, error

        seenAliases = set()
        exchanges = []
        # Examine the answers for the domain we asked about
        pertinentRecords = answers.get(domain, [])
        while pertinentRecords:
            record = pertinentRecords.pop()

            # If it's a CNAME, we'll need to do some more processing
            if record.TYPE == dns.CNAME:

                # Remember that this name was an alias.
                seenAliases.add(domain)

                canonicalName = str(record.name)
                # See if we have some local records which might be relevant.
                if canonicalName in answers:

                    # Make sure it isn't a loop contained entirely within the
                    # results we have here.
                    if canonicalName in seenAliases:
                        return Failure(CanonicalNameLoop(record))

                    pertinentRecords = answers[canonicalName]
                    exchanges = []
                else:
                    if cnamesLeft:
                        # Request more information from the server.
                        return self.getMX(canonicalName, cnamesLeft - 1)
                    else:
                        # Give up.
                        return Failure(CanonicalNameChainTooLong(record))

            # If it's an MX, collect it.
            if record.TYPE == dns.MX:
                exchanges.append((record.preference, record))

        if exchanges:
            exchanges.sort()
            for (preference, record) in exchanges:
                host = str(record.name)
                if host not in self.badMXs:
                    return record
                t = self.clock.seconds() - self.badMXs[host]
                if t >= 0:
                    del self.badMXs[host]
                    return record
            return exchanges[0][1]
        else:
            # Treat no answers the same as an error - jump to the errback to try
            # to look up an A record.  This provides behavior described as a
            # special case in RFC 974 in the section headed I{Interpreting the
            # List of MX RRs}.
            return Failure(
                error.DNSNameError("No MX records for %r" % (domain,)))