Example #1
0
    def _resolve_address(self, address, family, cb):
        """
        Use Pants' DNS client to asynchronously resolve the given
        address.

        ========= ===================================================
        Argument  Description
        ========= ===================================================
        address   The address to resolve.
        family    The address family.
        cb        A callable taking two mandatory arguments and one
                  optional argument. The arguments are: the resolved
                  address, the socket family and error information,
                  respectively.
        ========= ===================================================
        """
        # This is here to prevent an import-loop. pants.util.dns depends
        # on pants._channel. Unfortunate, but necessary.
        global dns
        if dns is None:
            from pants.util import dns

        # UNIX addresses and INADDR_ANY don't need to be resolved.
        if isinstance(address, basestring) or address[0] == '':
            cb(address, family)
            return

        def dns_callback(status, cname, ttl, rdata):
            if status == dns.DNS_NAMEERROR:
                cb(None, None, NAME_ERROR)
                return

            if status != dns.DNS_OK or not rdata:
                cb(address, family)
                return

            for i in rdata:
                if ':' in i:
                    if not HAS_IPV6:
                        continue
                    cb((i,) + address[1:], socket.AF_INET6)
                    return
                else:
                    cb((i,) + address[1:], socket.AF_INET)
                    return
            else:
                cb(None, None, FAMILY_ERROR)

        if HAS_IPV6 and family == socket.AF_INET6:
            qtype = dns.AAAA
        else:
            qtype = (dns.AAAA, dns.A)

        dns.query(address[0], qtype, callback=dns_callback)
Example #2
0
    def _resolve_address(self, address, callback):
        """
        Use Pants' DNS client to asynchronously resolve the given
        address.

        ========= ===================================================
        Argument  Description
        ========= ===================================================
        address   The address to resolve.
        callback  A callable taking two mandatory arguments and one
                  optional argument. The arguments are: the resolved
                  address, the socket family and error information,
                  respectively.
        ========= ===================================================
        """
        raise NotImplementedError("pants.util.dns is currently disabled")

        # This is here to prevent an import-loop. pants.util.dns depends
        # on pants._channel. Unfortunate, but necessary.
        global dns
        if dns is None:
            from pants.util import dns

        def dns_callback(status, cname, ttl, rdata):
            if status != dns.DNS_OK:
                # DNS errored. Assume it's a bad hostname.
                callback(None, None, NAME_ERROR)
                return

            for addr in rdata:
                family = socket.AF_INET6 if ':' in addr else 0
                try:
                    result = socket.getaddrinfo(addr, address[1], family, 0, 0,
                                                socket.AI_NUMERICHOST)
                except socket.error:
                    continue

                # It's a valid host.
                result = result[0]
                callback(result[-1], result[0])
                return

            # We didn't get any valid address.
            callback(None, None, NAME_ERROR)

        # Only query records that we can use.
        if not HAS_IPV6:
            qtype = dns.A
        elif len(address) == 4:
            qtype = dns.AAAA
        else:
            qtype = (dns.AAAA, dns.A)

        dns.query(address[0], qtype, callback=dns_callback)
Example #3
0
    def _resolve_address(self, address, callback):
        """
        Use Pants' DNS client to asynchronously resolve the given
        address.

        ========= ===================================================
        Argument  Description
        ========= ===================================================
        address   The address to resolve.
        callback  A callable taking two mandatory arguments and one
                  optional argument. The arguments are: the resolved
                  address, the socket family and error information,
                  respectively.
        ========= ===================================================
        """
        raise NotImplementedError("pants.util.dns is currently disabled")

        # This is here to prevent an import-loop. pants.util.dns depends
        # on pants._channel. Unfortunate, but necessary.
        global dns
        if dns is None:
            from pants.util import dns

        def dns_callback(status, cname, ttl, rdata):
            if status != dns.DNS_OK:
                # DNS errored. Assume it's a bad hostname.
                callback(None, None, NAME_ERROR)
                return

            for addr in rdata:
                family = socket.AF_INET6 if ':' in addr else 0
                try:
                    result = socket.getaddrinfo(addr, address[1], family, 0, 0, socket.AI_NUMERICHOST)
                except socket.error:
                    continue

                # It's a valid host.
                result = result[0]
                callback(result[-1], result[0])
                return

            # We didn't get any valid address.
            callback(None, None, NAME_ERROR)

        # Only query records that we can use.
        if not HAS_IPV6:
            qtype = dns.A
        elif len(address) == 4:
            qtype = dns.AAAA
        else:
            qtype = (dns.AAAA, dns.A)

        dns.query(address[0], qtype, callback=dns_callback)