def _lookup(self, name, cls, type, timeout): log.msg("Looking up type %s records for hostname: %s" % (type, name)) all_types = self.names.lookup(name, type) results = [] authority = [] additional = [] if len(all_types) > 0: log.msg("Got results.") else: log.msg("No results.") for type, records in all_types.items(): for data, metadata in records.items(): if type == A: payload = dns.Record_A(data) elif type == CNAME: # TODO: Add proper CNAME support that sends corresponding "A" records. payload = dns.Record_CNAME(data) elif type == MX: payload = dns.Record_MX(metadata["preference"], data) elif type == NS: payload = dns.Record_NS(data) header = dns.RRHeader(name, type=type, payload=payload, ttl=metadata["ttl"], auth=True) results.append(header) return defer.succeed((results, authority, additional))
def testCNAMEAdditional(self): """Test additional processing for CNAME records""" return self.namesTest( self.resolver.lookupAddress('cname.test-domain.com'), [ dns.Record_CNAME('test-domain.com', ttl=19283784), dns.Record_A('127.0.0.1', ttl=19283784) ])
def __parseLine(self, line): tokens = line.split(None, 2) # reject if incorrectly formatted. if len(tokens) != 3: raise RuntimeError( "line '%s': wrong # of tokens %d." %(line, len(tokens))) rname, rtype, rvalue = tokens # # if rvalue is a list, make sure to store it as one! if rvalue.startswith("["): rvalue = json.loads(rvalue) # create correct payload payload = None if rtype == "A": payload = dns.Record_A(address=rvalue) elif rtype == "CNAME": payload = dns.Record_CNAME(name=rvalue) elif rtype == "MX": payload = dns.Record_MX(name=rvalue[0], preference=int(rvalue[1])) elif rtype == "NS": payload = dns.Record_NS(name=rvalue) elif rtype == "SOA": payload = dns.Record_SOA(mname=rvalue[0], rname=rvalue[1]) elif rtype == "TXT": payload = dns.Record_TXT(data=[rvalue]) else: raise "cannot parse line!" return dns.RRHeader(name=rname, type=self.__query_types[rtype], payload=payload, ttl=0) # set TTL to 0 for now so that we can
def test_cname(self): """ The repr of a L{dns.Record_CNAME} instance includes the name of the mail forwarder and the TTL of the record. """ self.assertEqual(repr(dns.Record_CNAME('example.com', 4321)), "<CNAME name=example.com ttl=4321>")
def _answerCNAMETest(self, addresses): """ Verify that a response to a CNAME query has certain records in the I{answer} section. @param addresses: See C{_additionalTest} """ target = b"www." + soa_record.mname.name d = self._lookupSomeRecords("lookupCanonicalName", soa_record, dns.Record_CNAME, target, addresses) answer, authority, additional = self.successResultOf(d) alias = dns.RRHeader( soa_record.mname.name, dns.CNAME, ttl=soa_record.expire, payload=dns.Record_CNAME(target), auth=True, ) self.assertRecordsMatch( [ dns.RRHeader( target, address.TYPE, ttl=soa_record.expire, payload=address, auth=True, ) for address in addresses ] + [alias], answer, )
def to_record(self): if self.type == dns.A: return dns.Record_A(self.payload) elif self.type == dns.AAAA: return dns.Record_AAAA(self.payload) elif self.type == dns.CNAME: return dns.Record_CNAME(self.payload) else: raise Exception('Bad type')
def processAnswer(readBack): count,i=readBack[0],readBack[1] if i >= len(result[0]): if len(answers) < 1 : # in case couldn't build any answer use the org one logger.warn("can not build reply use the orginal answer ") return result[0],result[1],[] return answers, authority, additional answer = result[0][i] slowDown = False if count and count > DNSResolver.maxSiteCharsRate: logger.debug("execeed the max site characters rate") return defer.fail(error.DomainError()) else: if count and count > DNSResolver.slowSiteAtByteRate: slowDown = True if answer.type == dns.CNAME and cRecords[0] < DNSResolver.totalCnameRecords: siteName = b"%s"%answer.name siteCName = getattr(answer.payload, "name", "") siteCName = b"%s"%siteCName if len(siteCName) > DNSResolver.maxRespNameLen: return defer.fail(error.DomainError()) siteRe = DNSResolver.siteRegx.match(siteName) if siteRe: DNSResolver.updateSite(siteRe.groups()[0] + siteRe.groups()[1],len(siteCName)) if answer.ttl < DNSResolver.minTTL: answer.ttl = DNSResolver.minTTL siteCName = siteCName if not DNSResolver.upperName else siteCName.upper() answers.append(dns.RRHeader(siteName, answer.type, dns.IN, answer.ttl, dns.Record_CNAME(b"%s"%siteCName), auth=False)) cRecords[0] += 1 elif answer.type == dns.A and aRecords[0] < DNSResolver.totalARecords: siteName = b"%s"%answer.name siteName = siteName if not DNSResolver.upperName else siteName.upper() addrDot = answer.payload.dottedQuad() if answer.ttl < DNSResolver.minTTL: answer.ttl = DNSResolver.minTTL answers.append( dns.RRHeader(name=siteName, payload=dns.Record_A(address=addrDot), ttl=answer.ttl)) aRecords[0] += 1 if slowDown == True: return task.deferLater(reactor, DNSResolver.respDelayBy , slowDownResponse, None) else: return processAnswer([count,i+1])
def resolve(result): answers, authority, additional = result cname = dns.RRHeader( type=CNAME, name=alias.encode(), payload=dns.Record_CNAME(name=target.encode())) answers = [cname] + answers return answers, authority, additional
def lookupAddress(self, name, timeout=None): name = name.decode().lower() log.debug('address {}'.format(name)) result = self._localLookup(name) # If doesn't look like an IP address, try and look it up again # locally. Do this as many times as need to. Note there is no # protection against loops here. while result and not is_ip(result): mapped = self._localLookup(result) if mapped is not None: result = mapped else: break if not result: log.debug('fallback {}'.format(name)) return super().lookupAddress(name, timeout) # Check if looks like IP address. If still not treat it like # a CNAME and lookup name using normal DNS lookup. if not is_ip(result): log.debug('cname {}'.format(result)) return defer.succeed(( [ dns.RRHeader( name=name, type=dns.CNAME, payload=dns.Record_CNAME(name=result, ttl=3600), ) ], [], [], )) try: payload = dns.Record_A(address=result) except OSError as e: log.warn(str(e)) return defer.succeed(([], [], [])) answer = dns.RRHeader(name=name, payload=payload) answers = [answer] authority = [] additional = [] return defer.succeed((answers, authority, additional))
def test_cnameRecords(self): """ CNAME records are loaded. """ [answers, [], []] = self.successResultOf( self.auth.lookupIPV6Address(b"www.example.com")) rr = answers[0] self.assertEqual( dns.Record_CNAME(name="example.com", ), rr.payload, )
def lookupCanonicalName(self, name, timeout=None): if name[-len(DOMAIN):] != DOMAIN: return [(), (), ()] transmission = bromine.from_address(name) chid = bromine.get_channel_id(transmission) socket = self.ensure_channel_open(chid) host = socket.pump(name) reply = [ dns.RRHeader(name, dns.CNAME, dns.IN, 0, dns.Record_CNAME(host, 0)) ] if not socket.empty(): # more bangs in that packet, same bucks # + client understands it needs to pull some more host = socket.pump(None) reply.append( dns.RRHeader(name, dns.CNAME, dns.IN, 0, dns.Record_CNAME(host, 0))) return [reply, (), ()]
def test_cnameRecords(self): """ CNAME records are loaded. """ rr = self.successResultOf( self.auth.lookupIPV6Address(b"www.example.com"))[0][0] self.assertEqual( dns.Record_CNAME( name="example.com", ttl=604800, ), rr.payload, )
def makeResult(value): print "dht: %s -> %s" % (dhtQueryString(name, type), value) response = dns.RRHeader(name=name, type=type, ttl=10) if type == dns.A: payload = dns.Record_A(address=value, ttl=10) elif type == dns.AAAA: payload = dns.Record_AAAA(address=value, ttl=10) elif type == dns.CNAME: payload = dns.Record_CNAME(name=value, ttl=10) elif type == dns.MX: payload = dns.Record_MX(name=value, ttl=10) elif type == dns.PTR: payload = dns.Record_PTR(name=value, ttl=10) response.payload = payload return ([response], [], [])
def _doDynamicResponse(self, query): """ Calculate the response to a query. """ name = query.name.name answers = [ dns.RRHeader( name=name, type=dns.CNAME, payload=dns.Record_CNAME( name=self.cname, ), ), dns.RRHeader( name=name, type=dns.SOA, payload=dns.Record_SOA( serial=2018101700, refresh=10800, minimum=86400, expire=604800, retry=2000, ), ), dns.RRHeader( name=name, type=dns.NS, payload=dns.Record_NS( name=self.nameserver1, ), ), dns.RRHeader( name=name, type=dns.NS, payload=dns.Record_NS( name=self.nameserver2, ), ), ] authority = [] additional = [] return answers, authority, additional
def __build_answer(self, query, db_zone, db_record, is_conditional_response=False): record = None # Calculate the query type (in case it's a request for A but a CNAME is returned). query_type = REV_TYPES[db_record.type] if query_type == dns.A: record = dns.Record_A(address=db_record.property( 'address', conditional=is_conditional_response), ttl=db_record.ttl) elif query_type == dns.AAAA: record = dns.Record_AAAA(address=db_record.property( 'address', conditional=is_conditional_response), ttl=db_record.ttl) elif query_type == dns.AFSDB: record = dns.Record_AFSDB(subtype=int( db_record.property('subtype', conditional=is_conditional_response)), hostname=db_record.property( 'hostname', conditional=is_conditional_response)) elif query_type == dns.CNAME: record = dns.Record_CNAME(name=db_record.property( 'name', conditional=is_conditional_response), ttl=db_record.ttl) elif query_type == dns.DNAME: record = dns.Record_DNAME(name=db_record.property( 'name', conditional=is_conditional_response), ttl=db_record.ttl) elif query_type == dns.HINFO: record = dns.Record_HINFO( cpu=db_record.property( 'cpu', conditional=is_conditional_response).encode(), os=db_record.property( 'os', conditional=is_conditional_response).encode()) elif query_type == dns.MX: record = dns.Record_MX(preference=int( db_record.property('preference', conditional=is_conditional_response)), name=db_record.property( 'name', conditional=is_conditional_response)) elif query_type == dns.NAPTR: record = dns.Record_NAPTR( order=int( db_record.property('order', conditional=is_conditional_response)), preference=int( db_record.property('preference', conditional=is_conditional_response)), flags=db_record.property( 'flags', conditional=is_conditional_response).encode(), service=db_record.property( 'service', conditional=is_conditional_response).encode(), regexp=db_record.property( 'regexp', conditional=is_conditional_response).encode(), replacement=db_record.property( 'replacement', conditional=is_conditional_response)) elif query_type == dns.NS: record = dns.Record_NS(name=db_record.property( 'name', conditional=is_conditional_response), ttl=db_record.ttl) elif query_type == dns.PTR: record = dns.Record_PTR(name=db_record.property( 'name', conditional=is_conditional_response), ttl=db_record.ttl) elif query_type == dns.RP: record = dns.Record_RP( mbox=db_record.property('mbox', conditional=is_conditional_response), txt=db_record.property('txt', conditional=is_conditional_response)) elif query_type == dns.SOA: record = dns.Record_SOA( mname=db_record.property('mname', conditional=is_conditional_response), rname=db_record.property('rname', conditional=is_conditional_response), serial=int( db_record.property('serial', conditional=is_conditional_response)), refresh=int( db_record.property('refresh', conditional=is_conditional_response)), retry=int( db_record.property('retry', conditional=is_conditional_response)), expire=int( db_record.property('expire', conditional=is_conditional_response)), minimum=int( db_record.property('minimum', conditional=is_conditional_response))) elif query_type == dns.SPF: record = dns.Record_SPF( db_record.property( 'data', conditional=is_conditional_response).encode()) elif query_type == dns.SRV: record = dns.Record_SRV( priority=int( db_record.property('priority', conditional=is_conditional_response)), port=int( db_record.property('port', conditional=is_conditional_response)), weight=int( db_record.property('weight', conditional=is_conditional_response)), target=db_record.property('target', conditional=is_conditional_response)) elif query_type == dns.SSHFP: record = dns.Record_SSHFP( algorithm=int( db_record.property('algorithm', conditional=is_conditional_response)), fingerprintType=int( db_record.property('fingerprint_type', conditional=is_conditional_response)), fingerprint=db_record.property( 'fingerprint', conditional=is_conditional_response).encode()) elif query_type == dns.TSIG: record = dns.Record_TSIG( algorithm=db_record.property( 'algorithm', conditional=is_conditional_response).encode(), timeSigned=int( db_record.property('timesigned', conditional=is_conditional_response)), fudge=int( db_record.property('fudge', conditional=is_conditional_response)), originalID=int( db_record.property('original_id', conditional=is_conditional_response)), MAC=db_record.property( 'mac', conditional=is_conditional_response).encode(), otherData=db_record.property( 'other_data', conditional=is_conditional_response).encode()) elif query_type == dns.TXT: record = dns.Record_TXT( db_record.property( 'data', conditional=is_conditional_response).encode()) else: pass if not record: return None answer = dns.RRHeader(name=query.name.name, type=query_type, cls=query.cls, ttl=db_record.ttl, payload=record) return answer
def testCNAME(self): """Test DNS 'CNAME' record queries""" return self.namesTest( self.resolver.lookupCanonicalName('test-domain.com'), [dns.Record_CNAME('canonical.name.com', ttl=19283784)])
retry=100, ) test_domain_com = NoFileAuthority( soa=('test-domain.com', soa_record), records={ 'test-domain.com': [ soa_record, dns.Record_A('127.0.0.1'), dns.Record_NS('39.28.189.39'), dns.Record_SPF('v=spf1 mx/30 mx:example.org/30 -all'), dns.Record_SPF('v=spf1 +mx a:\0colo', '.example.com/28 -all not valid'), dns.Record_MX(10, 'host.test-domain.com'), dns.Record_HINFO(os='Linux', cpu='A Fast One, Dontcha know'), dns.Record_CNAME('canonical.name.com'), dns.Record_MB('mailbox.test-domain.com'), dns.Record_MG('mail.group.someplace'), dns.Record_TXT('A First piece of Text', 'a SecoNd piece'), dns.Record_A6(0, 'ABCD::4321', ''), dns.Record_A6(12, '0:0069::0', 'some.network.tld'), dns.Record_A6(8, '0:5634:1294:AFCB:56AC:48EF:34C3:01FF', 'tra.la.la.net'), dns.Record_TXT('Some more text, haha! Yes. \0 Still here?'), dns.Record_MR('mail.redirect.or.whatever'), dns.Record_MINFO(rmailbx='r mail box', emailbx='e mail box'), dns.Record_AFSDB(subtype=1, hostname='afsdb.test-domain.com'), dns.Record_RP(mbox='whatever.i.dunno', txt='some.more.text'), dns.Record_WKS('12.54.78.12', socket.IPPROTO_TCP, '\x12\x01\x16\xfe\xc1\x00\x01'), dns.Record_NAPTR(100, 10, "u", "sip+E2U",
def packResultCNAME(value): return [[ dns.RRHeader( name, dns.CNAME, dns.IN, value['ttl'], dns.Record_CNAME(value['record'], value['ttl']), True) ], (), ()]
retry=100, ) test_domain_com = NoFileAuthority( soa=(b"test-domain.com", soa_record), records={ b"test-domain.com": [ soa_record, dns.Record_A(b"127.0.0.1"), dns.Record_NS(b"39.28.189.39"), dns.Record_SPF(b"v=spf1 mx/30 mx:example.org/30 -all"), dns.Record_SPF(b"v=spf1 +mx a:\0colo", b".example.com/28 -all not valid"), dns.Record_MX(10, "host.test-domain.com"), dns.Record_HINFO(os=b"Linux", cpu=b"A Fast One, Dontcha know"), dns.Record_CNAME(b"canonical.name.com"), dns.Record_MB(b"mailbox.test-domain.com"), dns.Record_MG(b"mail.group.someplace"), dns.Record_TXT(b"A First piece of Text", b"a SecoNd piece"), dns.Record_A6(0, b"ABCD::4321", b""), dns.Record_A6(12, b"0:0069::0", b"some.network.tld"), dns.Record_A6(8, b"0:5634:1294:AFCB:56AC:48EF:34C3:01FF", b"tra.la.la.net"), dns.Record_TXT(b"Some more text, haha! Yes. \0 Still here?"), dns.Record_MR(b"mail.redirect.or.whatever"), dns.Record_MINFO(rmailbx=b"r mail box", emailbx=b"e mail box"), dns.Record_AFSDB(subtype=1, hostname=b"afsdb.test-domain.com"), dns.Record_RP(mbox=b"whatever.i.dunno", txt=b"some.more.text"), dns.Record_WKS(b"12.54.78.12", socket.IPPROTO_TCP, b"\x12\x01\x16\xfe\xc1\x00\x01"), dns.Record_NAPTR(100, 10, b"u", b"sip+E2U",
refresh = 12345, minimum = 1, expire = 999999, retry = 100, ) test_domain_com = NoFileAuthority( soa = ('test-domain.com', soa_record), records = { 'test-domain.com': [ soa_record, dns.Record_A('127.0.0.1'), dns.Record_NS('39.28.189.39'), dns.Record_MX(10, 'host.test-domain.com'), dns.Record_HINFO(os='Linux', cpu='A Fast One, Dontcha know'), dns.Record_CNAME('canonical.name.com'), dns.Record_MB('mailbox.test-domain.com'), dns.Record_MG('mail.group.someplace'), dns.Record_TXT('A First piece of Text', 'a SecoNd piece'), dns.Record_A6(0, 'ABCD::4321', ''), dns.Record_A6(12, '0:0069::0', 'some.network.tld'), dns.Record_A6(8, '0:5634:1294:AFCB:56AC:48EF:34C3:01FF', 'tra.la.la.net'), dns.Record_TXT('Some more text, haha! Yes. \0 Still here?'), dns.Record_MR('mail.redirect.or.whatever'), dns.Record_MINFO(rmailbx='r mail box', emailbx='e mail box'), dns.Record_AFSDB(subtype=1, hostname='afsdb.test-domain.com'), dns.Record_RP(mbox='whatever.i.dunno', txt='some.more.text'), dns.Record_WKS('12.54.78.12', socket.IPPROTO_TCP, '\x12\x01\x16\xfe\xc1\x00\x01'), dns.Record_NAPTR(100, 10, "u", "sip+E2U", "!^.*$!sip:[email protected]!"),