def _respond(self, name, records): if records: return defer.succeed((records, (), ())) return defer.fail(failure.Failure(dns.DomainError(name)))
def _lookup(self, name, cls, type, timeout=None): if not self.soa or not self.records: return defer.fail(failure.Failure(dns.DomainError(name))) return FileAuthority.__dict__['_lookup'](self, name, cls, type, timeout)
def lookupAllRecords(self, name, timeout = None): return defer.fail(failure.Failure(dns.DomainError(name)))
def _lookup(self, name, cls, type, timeout=None): cnames = [] results = [] authority = [] additional = [] default_ttl = max(self.soa[1].minimum, self.soa[1].expire) domain_records = self.records.get(name.lower()) if domain_records: for record in domain_records: if record.ttl is not None: ttl = record.ttl else: ttl = default_ttl if record.TYPE == dns.NS and name.lower() != self.soa[0].lower( ): # NS record belong to a child zone: this is a referral. As # NS records are authoritative in the child zone, ours here # are not. RFC 2181, section 6.1. authority.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=False)) elif record.TYPE == type or type == dns.ALL_RECORDS: results.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)) if record.TYPE == dns.CNAME: cnames.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)) if not results: results = cnames for record in results + authority: section = { dns.NS: additional, dns.CNAME: results, dns.MX: additional }.get(record.type) if section is not None: n = str(record.payload.name) for rec in self.records.get(n.lower(), ()): if rec.TYPE == dns.A: section.append( dns.RRHeader(n, dns.A, dns.IN, rec.ttl or default_ttl, rec, auth=True)) if not results and not authority: # Empty response. Include SOA record to allow clients to cache # this response. RFC 1034, sections 3.7 and 4.3.4, and RFC 2181 # section 7.1. authority.append( dns.RRHeader(self.soa[0], dns.SOA, dns.IN, ttl, self.soa[1], auth=True)) return defer.succeed((results, authority, additional)) else: if name.lower().endswith(self.soa[0].lower()): # We are the authority and we didn't find it. Goodbye. return defer.fail( failure.Failure(dns.AuthoritativeDomainError(name))) return defer.fail(failure.Failure(dns.DomainError(name)))
def _lookup(self, name, cls, type, timeout=None): if not self.soa or not self.records: # No transfer has occurred yet. Fail non-authoritatively so that # the caller can try elsewhere. return defer.fail(failure.Failure(dns.DomainError(name))) return FileAuthority._lookup(self, name, cls, type, timeout)
def _lookup(self, name, cls, type, timeout, addr=None, edns=None): q = dns.Query(name, type, cls) d = defer.fail(failure.Failure(dns.DomainError(name))) for r in self.resolvers: d = d.addErrback(FailureHandler(r.query, q, timeout, addr, edns)) return d
def _lookup(self, name, cls, type, timeout=None): cnames = [] results = [] authority = [] additional = [] default_ttl = max(self.soa[1].minimum, self.soa[1].expire) domain_records = self.records.get(name.lower()) if domain_records: for record in domain_records: if record.ttl is not None: ttl = record.ttl else: ttl = default_ttl if record.TYPE == type or type == dns.ALL_RECORDS: results.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)) elif record.TYPE == dns.NS and type != dns.ALL_RECORDS: authority.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)) if record.TYPE == dns.CNAME: cnames.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)) if not results: results = cnames for record in results + authority: section = { dns.NS: additional, dns.CNAME: results, dns.MX: additional }.get(record.type) if section is not None: n = str(record.payload.name) for rec in self.records.get(n.lower(), ()): if rec.TYPE == dns.A: section.append( dns.RRHeader(n, dns.A, dns.IN, rec.ttl or default_ttl, rec, auth=True)) return defer.succeed((results, authority, additional)) else: if name.lower().endswith(self.soa[0].lower()): # We are the authority and we didn't find it. Goodbye. return defer.fail( failure.Failure(dns.AuthoritativeDomainError(name))) return defer.fail(failure.Failure(dns.DomainError(name)))
def query(self, query, timeout=None): """ :param query: :param timeout: :return: """ qname = query.name.name qtype = query.type if not self._backend.supports(qname): self._logger.d('unsupported query name [%s], just forward it.', qname) return defer.fail(dns.DomainError()) if qtype not in (dns.A, dns.AAAA): self._logger.d('unsupported query type [%d], just forward it.', qtype) return defer.fail(dns.DomainError()) def _lookup_backend(backend, logger, qn, qt): """ :param backend: :param qn: :param qt: :return: three-tuple(answers, authorities, additional) of lists of twisted.names.dns.RRHeader instances. """ import random try: name_detail = backend.lookup(qn) except: logger.ex( 'lookup name %s occurs error, just ignore and forward it.', qn) return EMPTY_ANSWERS if not name_detail.items: return EMPTY_ANSWERS if qt == dns.A: answers = name_detail.items \ | select(lambda it: it.host_ipv4) \ | collect(lambda it: it.host_ipv4) \ | as_set \ | collect(lambda it: dns.Record_A(address=it)) \ | collect(lambda record_a: dns.RRHeader(name=qn, payload=record_a)) \ | as_list random.shuffle(answers) return answers, [], [] else: answers = name_detail.items \ | select(lambda it: it.host_ipv6) \ | collect(lambda it: it.host_ipv6) \ | as_set \ | collect(lambda it: dns.Record_AAAA(address=it)) \ | collect(lambda record_aaaa: dns.RRHeader(name=qn, payload=record_aaaa)) \ | as_list random.shuffle(answers) return answers, [], [] return threads.deferToThread(_lookup_backend, self._backend, self._logger, qname, qtype)
def _lookup(self, name, cls, type, timeout=None): cnames = [] results = [] authority = [] additional = [] default_ttl = max(self.soa[1].minimum, self.soa[1].expire) client_address = self.address[0] domain_records = self.records.get(name.lower()) if not domain_records: domain_records = list() # search database only for CLOUDLET_DOMAIN if name.lower() == MemoryResolver.CLOUDLET_DOMAIN.lower(): db_domain_records = list() + domain_records machine_list = self.db.search_nearby_cloudlet(client_address, max_count=10) appended_ips = dict() for each_machine in machine_list: # avoid duplicated record if appended_ips.get(each_machine.ip_address, False) == True: continue if each_machine.ip_address.startswith( MemoryResolver.IP_FILTER): new_record = dns.Record_A(address=each_machine.ip_address, ttl=default_ttl) db_domain_records.append(new_record) appended_ips[each_machine.ip_address] = True else: db_domain_records = domain_records if db_domain_records: for record in db_domain_records: if record.ttl is not None: ttl = record.ttl else: ttl = default_ttl if record.TYPE == dns.NS and name.lower() != self.soa[0].lower( ): # NS record belong to a child zone: this is a referral. As # NS records are authoritative in the child zone, ours here # are not. RFC 2181, section 6.1. authority.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=False)) elif record.TYPE == type or type == dns.ALL_RECORDS: results.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)) if record.TYPE == dns.CNAME: cnames.append( dns.RRHeader(name, record.TYPE, dns.IN, ttl, record, auth=True)) if not results: results = cnames for record in results + authority: section = { dns.NS: additional, dns.CNAME: results, dns.MX: additional }.get(record.type) if section is not None: n = str(record.payload.name) for rec in self.records.get(n.lower(), ()): if rec.TYPE == dns.A: section.append( dns.RRHeader(n, dns.A, dns.IN, rec.ttl or default_ttl, rec, auth=True)) if not results and not authority: # Empty response. Include SOA record to allow clients to cache # this response. RFC 1034, sections 3.7 and 4.3.4, and RFC 2181 # section 7.1. authority.append( dns.RRHeader(self.soa[0], dns.SOA, dns.IN, ttl, self.soa[1], auth=True)) return defer.succeed((results, authority, additional)) else: if name.lower().endswith(self.soa[0].lower()): # We are the authority and we didn't find it. Goodbye. return defer.fail( failure.Failure(dns.AuthoritativeDomainError(name))) return defer.fail(failure.Failure(dns.DomainError(name)))