def lookupNameservers(self, name, timeout=None): """ Answer NS record requests """ name_is_self = name in [self.wildcard_domain, self.ns_domain] if name.endswith('.' + self.wildcard_domain) or name_is_self: # If we're responsible for this domain, return NS records payload = dns.Record_NS(name=self.ns_domain) answer = dns.RRHeader(name=name, type=dns.NS, payload=payload, auth=True, ttl=TTL) # Additional section: NS ip address additional_payload = dns.Record_A(address=self.my_ip) additional_answer = dns.RRHeader(name=name, payload=additional_payload, ttl=TTL) answers = [answer] authority = [] additional = [additional_answer] return defer.succeed((answers, authority, additional)) # fail for domains that are not handled by our server return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name)))
def _lookup(self, name, cls, type, timeout): segs = name.split('.') print name, segs for i in reversed(xrange(len(segs))): seg = segs[i] try: nh = util.name_to_name_hash(seg) except ValueError: continue name2 = '.'.join(segs[i:]) break else: raise dns.DomainError(name) print(nh, name2) result = yield self.dht.iterativeFindValue(nh) if isinstance(result, list): print result print 5 raise dns.AuthoritativeDomainError(name) assert isinstance(result, dict), result print result pkt = packet.DomainPacket.from_binary(result[nh]) if pkt.get_name_hash() != nh: print 6 raise dns.AuthoritativeDomainError(name) record = pkt.get_record() if not self.dht.get_my_time() < record.get_end_time(): print 7 raise dns.AuthoritativeDomainError(name) if not pkt.verify_signature(): print 8 raise dns.AuthoritativeDomainError(name) zone = record.get_zone(name2) defer.returnValue((yield zone._lookup(name, cls, type, timeout)))
def _lookup(self, name, cls, type, timeout=None): if self._debug_level > 2: print('address %s (%s)' % (name, type), file=sys.stderr) answers = [] additional = [] authority = [] if type == dns.NS: return self.lookupNameservers(name) elif type == dns.SOA: answer = [self._get_authority_record(name)] return defer.succeed(([answer], authority, additional)) elif type == dns.A: result = self._localLookup(name) if result: # TTL = 1 hour payload = dns.Record_A(address=bytes(result)) answer = dns.RRHeader(name=name, payload=payload, auth=True, ttl=TTL) answers = [answer] return defer.succeed((answers, authority, additional)) else: if self._debug_level > 2: print('Unknown %s' % name, file=sys.stderr) return defer.fail( failure.Failure(dns.AuthoritativeDomainError(name))) else: # Types not handled by our server - respond with SOA authority = [self._get_authority_record(name)] return defer.succeed((answers, authority, additional))
def _lookup(self, name, cls, type, timeout=None): """ Determine a response to a particular DNS query. @param name: The name which is being queried and for which to lookup a response. @type name: L{bytes} @param cls: The class which is being queried. Only I{IN} is implemented here and this value is presently disregarded. @type cls: L{int} @param type: The type of records being queried. See the types defined in L{twisted.names.dns}. @type type: L{int} @param timeout: All processing is done locally and a result is available immediately, so the timeout value is ignored. @return: A L{Deferred} that fires with a L{tuple} of three sets of response records (to comprise the I{answer}, I{authority}, and I{additional} sections of a DNS response) or with a L{Failure} if there is a problem processing the query. """ 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 # Sort of https://tools.ietf.org/html/rfc1034#section-4.3.2 . # See https://twistedmatrix.com/trac/ticket/6732 additionalInformation = self._additionalRecords( results, authority, default_ttl) if cnames: results.extend(additionalInformation) else: additional.extend(additionalInformation) 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 dns._isSubdomainOf(name, self.soa[0]): # We may be the authority and we didn't find it. # XXX: The QNAME may also be in a delegated child zone. See # #6581 and #6580 return defer.fail( failure.Failure(dns.AuthoritativeDomainError(name)) ) else: # The QNAME is not a descendant of this zone. Fail with # DomainError so that the next chained authority or # resolver will be queried. return defer.fail(failure.Failure(error.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): 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 _lookup(self, name, cls, type, timeout = None): """ Determine a response to a particular DNS query. @param name: The name which is being queried and for which to lookup a response. @type name: L{bytes} @param cls: The class which is being queried. Only I{IN} is implemented here and this value is presently disregarded. @type cls: L{int} @param type: The type of records being queried. See the types defined in L{twisted.names.dns}. @type type: L{int} @param timeout: All processing is done locally and a result is available immediately, so the timeout value is ignored. @return: A L{Deferred} that fires with a L{tuple} of three sets of response records (to comprise the I{answer}, I{authority}, and I{additional} sections of a DNS response) or with a L{Failure} if there is a problem processing the query. """ cnames = [] results = [] authority = [] additional = [] print '%s %s' % (name, dns.QUERY_TYPES[type]) domain_zone, zone_name = self._lookup_records(name.lower()) if not domain_zone: return defer.fail(failure.Failure(error.DomainError(name))) domain_records = domain_zone.get(name.lower()) if not domain_records: return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name))) for record in domain_records: ttl = record.ttl if record.TYPE == dns.NS and name.lower() != zone_name.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 record.TYPE == dns.SOA: soa = record if not results: results = cnames # https://tools.ietf.org/html/rfc1034#section-4.3.2 - sort of. # See https://twistedmatrix.com/trac/ticket/6732 additionalInformation = self._additionalRecords(results, authority) if cnames: results.extend(additionalInformation) else: additional.extend(additionalInformation) 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(zone_name, dns.SOA, dns.IN, ttl, soa, auth=True) ) return defer.succeed((results, authority, additional))
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 dns._isSubdomainOf(name, self.soa[0]): # We may be the authority and we didn't find it. # XXX: The QNAME may also be a in a delegated child zone. See # #6581 and #6580 return defer.fail(failure.Failure(dns.AuthoritativeDomainError(name))) else: # The QNAME is not a descendant of this zone. Fail with # DomainError so that the next chained authority or # resolver will be queried. return defer.fail(failure.Failure(error.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) 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)))