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)
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)