def query(self, domain, dns_type=1): try: t0 = time.time() client = self.get_connection() url = self.server d = DNSRecord(DNSHeader()) d.add_question(DNSQuestion(domain, dns_type)) data = d.pack() r = client.request("POST", url, headers={"accept": "application/dns-message", "content-type": "application/dns-message"}, body=data) t2 = time.time() p = DNSRecord.parse(r.text) ips = [] for r in p.rr: ip = utils.to_bytes(str(r.rdata)) ips.append(ip) self.connections.append([client, time.time()]) xlog.debug("Dns %s %s return %s t:%f", self.protocol, domain, ips, t2 - t0) return ips except Exception as e: xlog.exception("DnsOverHttpsQuery query fail:%r", e) return []
def manufactory_DNS(self): response_packet = DNSRecord() response_packet.header.id = self.query_id response_packet.add_question(DNSQuestion(self.qname, self.qtype)) related_rr = filter(lambda rr: self.qname in rr, intercept_rr) for answer in related_rr: response_packet.add_answer(*RR.fromZone(answer)) self.response_packet = response_packet.pack().__str__()
def send_dns_packet(sock, server_addr, name, ip, id): """ Construct and send dns packet """ ans = DNSRecord(DNSHeader(id=id, qr=1)) ans.add_question(DNSQuestion(name)) ans.add_answer(RR(name, ttl=3600, rdata=A(ip))) # print(ans) sock.sendto(ans.pack(), (server_addr, 7131))
def send_request(self, id, server_ip, domain, dns_type): try: d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(domain, dns_type)) req4_pack = d.pack() self.sock.sendto(req4_pack, (server_ip, 53)) except Exception as e: xlog.warn("send_request except:%r", e)
def query(self, domain, dns_type=1): t0 = time.time() try: sock = self.get_connection() if not sock: xlog.warn("query_over_tcp %s type:%s connect fail.", domain, dns_type) return [] d = DNSRecord(DNSHeader()) d.add_question(DNSQuestion(domain, dns_type)) data = d.pack() data = struct.pack("!H", len(data)) + data sock.sendall(data) response = sock.recv(8192) if not response: return [] length = struct.unpack("!H", bytes(response[:2]))[0] while len(response) - 2 < length: response += sock.recv(8192) t2 = time.time() p = DNSRecord.parse(response[2:]) if len(p.rr) == 0: xlog.warn("query_over_tcp for %s type:%d return none, cost:%f", domain, dns_type, t2 - t0) ips = [] for r in p.rr: ip = utils.to_bytes(str(r.rdata)) if not utils.check_ip_valid(ip): if ip == domain: continue ip_ips = self.query(ip, dns_type) ips += ip_ips else: ips.append(ip) xlog.debug("DNS %s %s return %s t:%f", self.protocol, domain, ips, t2 - t0) self.connections.append([sock, time.time()]) return ips except socket.timeout: xlog.warn("query_over_tcp %s type:%s timeout", domain, dns_type) return [] except Exception as e: xlog.exception("query_over_tcp %s type:%s except:%r", domain, dns_type, e) return []
def query(self, domain, dns_type=1): t0 = time.time() try: client = self.get_connection() url = self.server d = DNSRecord(DNSHeader()) d.add_question(DNSQuestion(domain, dns_type)) data = d.pack() r = client.request("POST", url, headers={ "accept": "application/dns-message", "content-type": "application/dns-message" }, body=data) t2 = time.time() ips = [] if not r: xlog.warn("DNS s:%s query:%s fail t:%f", self.server, domain, t2 - t0) return ips p = DNSRecord.parse(r.text) self.connections.append([client, time.time()]) for r in p.rr: ip = utils.to_bytes(str(r.rdata)) if not utils.check_ip_valid(ip): if ip == domain: continue ip_ips = self.query(ip, dns_type) ips += ip_ips else: ips.append(ip) xlog.debug("DNS %s %s return %s t:%f", self.protocol, domain, ips, t2 - t0) return ips except Exception as e: t1 = time.time() t = t1 - t0 xlog.exception("DnsOverHttpsQuery query %s cost:%f fail:%r", domain, t, e) return []
def cache_hit(self): cache_key = "cache:{}:{}".format(self.qtype, self.qname) cache_ret = cache_db.get(cache_key) if cache_ret: log.info("cache_hit: {}".format(self.query_id)) response_packet = DNSRecord() response_packet.header.id = self.query_id response_packet.add_question(DNSQuestion(self.qname)) for answer in loads(cache_ret): response_packet.add_answer(answer) log.info(response_packet.__str__()) log.info("DNS response id {}".format(self.query_id)) response_packet_str = response_packet.pack().__str__() self.wfile.write(response_packet_str) return True
def send_request(self, id, domain, server): try: d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(domain, QTYPE.A)) req4_pack = d.pack() d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(domain, QTYPE.AAAA)) req6_pack = d.pack() self.sock.sendto(req4_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) self.sock.sendto(req6_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) except Exception as e: xlog.warn("send_request except:%r", e)
def send_request(self, id, domain, server): try: d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(domain, QTYPE.A)) req4_pack = d.pack() d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(domain, QTYPE.AAAA)) req6_pack = d.pack() self.sock.sendto(req4_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) self.sock.sendto(req6_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) except Exception as e: xlog.warn("send_request except:%r", e)
def query_over_tcp(self, domain, type=None): if type is None: types = [1, 28] else: types = [type] ips = [] for t in types: query_time = 0 for server_ip in self.dns_server.public_list: query_time += 1 if query_time > 3: break try: d = DNSRecord(DNSHeader()) d.add_question(DNSQuestion(domain, t)) a_pkt = d.send(server_ip, 53, tcp=True, timeout=1) p = DNSRecord.parse(a_pkt) if len(p.rr) == 0: xlog.warn( "query_over_tcp for %s type:%d server:%s return none", domain, t, server_ip) continue for r in p.rr: ip = str(r.rdata) if "." in ip and g.ip_region.check_ip(ip): cn = g.ip_region.cn else: cn = "XX" ips.append(ip + "|" + cn) break except Exception as e: xlog.warn("query_over_tcp %s type:%s server:%s except:%r", domain, type, server_ip, e) if ips: g.domain_cache.set_ips(domain, ips, type) return ips
def make_fake_request(_uuid: str, data, host_name): ''' 进行伪装查询 0 12 49 | header | UUID | ''' assert len(data) <= 63 * 3 data_segments = Encapsulator.__split_with_length(data, 63) request_msg = DNSRecord() request_msg.add_question( DNSQuestion(_uuid + '.' + host_name, QTYPE.TXT)) request_data = request_msg.pack() _idx = 13 + len(_uuid) modified_data = request_data[:_idx] for data_seg in data_segments: data_len = struct.pack('>B', len(data_seg)) modified_data += data_len + data_seg modified_data += request_data[_idx:] return modified_data
def query_over_tcp(self, domain, type=None): if type is None: types = [1, 28] else: types = [type] ips = [] for t in types: query_time = 0 for server_ip in self.dns_server.public_list: query_time += 1 if query_time > 3: break try: d = DNSRecord(DNSHeader()) d.add_question(DNSQuestion(domain, t)) a_pkt = d.send(server_ip, 53, tcp=True, timeout=1) p = DNSRecord.parse(a_pkt) if len(p.rr) == 0: xlog.warn("query_over_tcp for %s type:%d server:%s return none", domain, t, server_ip) continue for r in p.rr: ip = str(r.rdata) if "." in ip and g.ip_region.check_ip(ip): cn = g.ip_region.cn else: cn = "XX" ips.append(ip+"|"+cn) break except Exception as e: xlog.warn("query_over_tcp %s type:%s server:%s except:%r", domain, type, server_ip,e) if ips: g.domain_cache.set_ips(domain, ips, type) return ips
def send_request(self, id, domain): try: d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(domain, QTYPE.A)) req4_pack = d.pack() d = DNSRecord() d.add_question(DNSQuestion(domain, QTYPE.AAAA)) req6_pack = d.pack() if "." in domain: server = self.dns_server.get() else: server = self.dns_server.get_local_server() self.sock.sendto(req4_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) self.sock.sendto(req6_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) except Exception as e: xlog.warn("request dns except:%r", e)
def send_request(self, id, domain): try: d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(domain, QTYPE.A)) req4_pack = d.pack() d = DNSRecord() d.add_question(DNSQuestion(domain, QTYPE.AAAA)) req6_pack = d.pack() if "." in domain: server = self.dns_server.get() else: server = self.dns_server.get_local_server() self.sock.sendto(req4_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) self.sock.sendto(req6_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) except Exception as e: xlog.warn("request dns except:%r", e)
def recv_worker(self): while self.running: try: try: response, server = self.sock.recvfrom(8192) server, port = server except Exception as e: # xlog.exception("sock.recvfrom except:%r", e) continue if not response: continue try: p = DNSRecord.parse(response) except Exception as e: xlog.exception("dns client parse response fail:%r", e) continue if len(p.questions) == 0: xlog.warn("received response without question") continue id = p.header.id if id not in self.waiters: continue que = self.waiters[id] org_domain = que.domain domain = str(p.questions[0].qname) xlog.debug("recev %s from:%s domain:%s org:%s", len(p.rr), server, domain, org_domain) ips = [] for r in p.rr: ip = str(r.rdata) if r.rtype == 5: # CNAME if ip.endswith("."): ip = ip[:-1] if ip == domain: xlog.warn("recv domain[%s] == ip[%s]", domain, ip) continue query_count = g.domain_cache.get_query_count(domain) if query_count >= 50: xlog.warn("%s ip:%s query_count:%d", domain, ip, query_count) continue g.domain_cache.add_query_count(domain) xlog.debug("local dns %s recv %s cname:%s from:%s", org_domain, domain, ip, server) d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(ip, QTYPE.A)) req_pack = d.pack() self.sock.sendto(req_pack, (server, 53)) d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(ip, QTYPE.AAAA)) req_pack = d.pack() self.sock.sendto(req_pack, (server, 53)) continue if "." in ip and g.ip_region.check_ip(ip): cn = g.ip_region.cn else: cn = "XX" ips.append(ip + "|" + cn) if ips: que.put(ips) except Exception as e: xlog.exception("dns recv_worker except:%r", e) xlog.info("DNS Client recv worker exit.") self.sock.close()
def query_over_tcp(self, domain, type=None, loop_count=0): if loop_count > 10: return [] if type is None: types = [1, 28] else: types = [type] ips = [] for t in types: query_time = 0 for i in range(0, 3): server_ip = self.dns_server.get_fastest_public() if not server_ip: return [] query_time += 1 if query_time > 3: break t0 = time.time() try: d = DNSRecord(DNSHeader()) d.add_question(DNSQuestion(domain, t)) a_pkt = d.send(server_ip, 53, tcp=True, timeout=2) t1 = time.time() self.dns_server.update_public_server(server_ip, t1-t0) p = DNSRecord.parse(a_pkt) if len(p.rr) == 0: xlog.warn("query_over_tcp for %s type:%d server:%s return none, cost:%f", domain, t, server_ip, t1-t0) continue for r in p.rr: ip = bytes(r.rdata) if utils.check_ip_valid(ip): if b"." in ip and g.ip_region.check_ip(ip): cn = g.ip_region.cn else: cn = b"XX" if type == 1 and b"." not in ip: continue ips.append(ip + b"|" + cn) else: # It is domain, loop search it. ipss = self.query_over_tcp(ip, type, loop_count+1) if not ipss: continue ips += ipss break except Exception as e: t1 = time.time() self.dns_server.update_public_server(server_ip, t1 - t0) xlog.warn("query_over_tcp %s type:%s server:%s except:%r", domain, type, server_ip,e) if ips: g.domain_cache.set_ips(domain, ips, type) return ips
def recv_worker(self): while self.running: try: response, server = self.sock.recvfrom(8192) except Exception as e: # xlog.exception("sock.recvfrom except:%r", e) continue if not response: continue try: p = DNSRecord.parse(response) except Exception as e: xlog.exception("parse response fail:%r", e) continue if len(p.questions) == 0: xlog.warn("received response without question") continue id = p.header.id if id not in self.waiters: continue que = self.waiters[id] org_domain = que.domain domain = str(p.questions[0].qname) xlog.debug("recev %s from:%s domain:%s org:%s", len(p.rr), server, domain, org_domain) ips = [] for r in p.rr: ip = str(r.rdata) if r.rtype == 5: # CNAME xlog.debug("local dns %s recv %s cname:%s from:%s", org_domain, domain, ip, server) d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(ip, QTYPE.A)) req_pack = d.pack() server = self.dns_server.get() self.sock.sendto(req_pack, (server, 53)) d = DNSRecord() d.add_question(DNSQuestion(ip, QTYPE.AAAA)) req_pack = d.pack() server = self.dns_server.get() self.sock.sendto(req_pack, (server, 53)) continue if "." in ip and g.ip_region.check_ip(ip): cn = g.ip_region.cn else: cn = "XX" ips.append(ip+"|"+cn) if len(ips): g.domain_cache.set_ips(org_domain, ips) que.notify_all() xlog.info("DNS Client recv worker exit.") self.sock.close()
def serve(self): try: udpsocket = socket(AF_INET, SOCK_DGRAM) udpsocket.bind((self.ip, self.port)) self.socket = udpsocket logging.getLogger().debug("now serving on %s/%s" % (self.ip, self.port)) while self.stayAlive: try: data, addr = self.socket.recvfrom(512) d = DNSRecord.parse(data) # print "Question from ",addr # print d question = d.get_q() qname = str(question.qname) qtype = str(QTYPE[question.qtype]).upper() try: ansdict = self.rbldnsd.lookup(qname) # logging.getLogger().debug("ansdict: %s"%ansdict) if qtype == "SOA": if ansdict["SOA"] != None: response = DNSRecord(DNSHeader(id=d.header.id, gr=1, aa=1, ra=1, qr=1, q=d.get_q())) soa = ansdict["SOA"] packet = SOA() packet.set_mname(soa[0]) packet.set_rname(soa[1]) packet.times = soa[2:] if "SOATTL" in ansdict: packet.ttl = ansdict["SOATTL"] response.rr.append(packet) self.socket.sendto(response.pack(), addr) continue else: self.send_nxdomain(d, addr) continue elif qtype == "NS": if ansdict["NS"] != None: # TODO pass else: self.send_nxdomain(d, addr) continue elif qtype == "A" or qtype == "TXT": if "results" not in ansdict: self.send_nxdomain(d, addr) logging.getLogger().debug("client=%s q=%s %s -> NXDOMAIN" % (addr[0], qname, qtype)) continue anslist = ansdict["results"] anspacklist = [] for answer in anslist: if answer == None: continue if qtype not in answer: continue packet = RR( question.qname, question.qtype, rdata=RDMAP[QTYPE[question.qtype]](answer[qtype]) ) if "TTL" in answer and answer["TTL"] != None: packet.ttl = answer["TTL"] anspacklist.append(packet) if len(anspacklist) > 0: response = DNSRecord( DNSHeader(id=d.header.id, bitmap=d.header.bitmap, aa=1, ra=0, qr=1, q=1) ) response.add_question(question) response.rr.extend(anspacklist) response.set_header_qa() # logging.getLogger().debug(response) # make sure answer bit is set # response.header.qr=1 self.socket.sendto(response.pack(), addr) logging.getLogger().debug("client=%s q=%s %s -> NOERROR" % (addr[0], qname, qtype)) else: self.send_nxdomain(d, addr) logging.getLogger().debug("client=%s q=%s %s -> NXDOMAIN" % (addr[0], qname, qtype)) continue else: logging.getLogger().warning("unsupported qtype %s" % qtype) except: fmt = traceback.format_exc() logging.getLogger().error(fmt) self.send_servfail(d, addr) continue except Exception: fmt = traceback.format_exc() logging.getLogger().error(fmt) except: fmt = traceback.format_exc() logging.getLogger().error("Could not start serversocket on %s/%s: %s" % (self.ip, self.port, fmt)) logging.getLogger().debug("serve() complete")
def query_local_dns(self, domain, timeout=5): start_time = time.time() ips = {} ipv4_num = 0 ipv6_num = 0 return_num = 0 sock_timeout = 0.1 try: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) except Exception as e: xlog.error("query_local_dns e:%r", e) return [] d4 = DNSRecord() d4.add_question(DNSQuestion(domain, QTYPE.A)) req4_pack = d4.pack() d6 = DNSRecord() d6.add_question(DNSQuestion(domain, QTYPE.AAAA)) req6_pack = d6.pack() try: for i in range(0, timeout): sock_timeout *= 2 sock.settimeout(sock_timeout) server = self.local_dns[i % len(self.local_dns)] sock.sendto(req4_pack, (server, 53)) sock.sendto(req6_pack, (server, 53)) # xlog.debug("send req:%s to:%s", domain, server) try: response, server_c = sock.recvfrom(8192) except Exception as e: if time.time() - start_time > timeout: break else: continue p = DNSRecord.parse(response) # xlog.debug("recev %s from:%s", len(p.rr), server) for r in p.rr: ip = str(r.rdata) if r.rtype == 5: # CNAME d = DNSRecord() d.add_question(DNSQuestion(ip, QTYPE.A)) req_pack = d.pack() sock.sendto(req_pack, (server, 53)) d = DNSRecord() d.add_question(DNSQuestion(ip, QTYPE.AAAA)) req_pack = d.pack() sock.sendto(req_pack, (server, 53)) continue if "." in ip: try: socket.inet_aton(ip) # legal except socket.error: # Not legal xlog.warn("query:%s rr:%s", domain, r) continue ipv4_num += 1 elif ":" in ip: ipv6_num += 1 ips[ip] = 1 return_num += 1 if len(ips) > 10 or return_num > 3: break except Exception as e: xlog.exception("request dns except:%r", e) finally: sock.close() ip_list = [] for ip in ips: ip_list.append(ip + "|XX") return ip_list
def recv_worker(self): while self.running: try: try: response, server = self.sock.recvfrom(8192) server, port = server except Exception as e: # xlog.exception("sock.recvfrom except:%r", e) continue if not response: continue try: p = DNSRecord.parse(response) except Exception as e: xlog.exception("dns client parse response fail:%r", e) continue if len(p.questions) == 0: xlog.warn("received response without question") continue id = p.header.id if id not in self.waiters: continue que = self.waiters[id] org_domain = que.domain domain = str(p.questions[0].qname) xlog.debug("recev %s from:%s domain:%s org:%s", len(p.rr), server, domain, org_domain) ips = [] for r in p.rr: ip = str(r.rdata) if r.rtype == 5: # CNAME if ip.endswith("."): ip = ip[:-1] if ip == domain: xlog.warn("recv domain[%s] == ip[%s]", domain, ip) continue query_count = g.domain_cache.get_query_count(domain) if query_count >= 50: xlog.warn("%s ip:%s query_count:%d", domain, ip, query_count) continue g.domain_cache.add_query_count(domain) xlog.debug("local dns %s recv %s cname:%s from:%s", org_domain, domain, ip, server) d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(ip, QTYPE.A)) req_pack = d.pack() self.sock.sendto(req_pack, (server, 53)) d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(ip, QTYPE.AAAA)) req_pack = d.pack() self.sock.sendto(req_pack, (server, 53)) continue if "." in ip and g.ip_region.check_ip(ip): cn = g.ip_region.cn else: cn = "XX" ips.append(ip+"|"+cn) if ips: que.put(ips) except Exception as e: xlog.exception("dns recv_worker except:%r", e) xlog.info("DNS Client recv worker exit.") self.sock.close()
async def handle_query( self, request: DNSRecord, source: TSource, ) -> DNSRecord: reply = request.reply() queries: List[asyncio.Future[DNSRecord]] = [] nxdomain = False for question in request.questions: qname = question.qname qtype = question.qtype self.validate_query_label(qname) self.logger.debug('Question %r %r', qname, QTYPE[qtype]) if len(qname.label) > 2: remote_qname = str(DNSLabel(qname.label[-2:])) remote_records = self.get_addr_records(remote_qname) self.logger.debug('Remote question %r', question.qname) if remote_records: q = DNSRecord() q.add_question(question) queries.append(asyncio.wait_for( dns_query( ipaddress.ip_address(repr(remote_records[0])), 53, q, ), 0.5 )) else: nxdomain = True continue if not self.has_name(qname): nxdomain = True records = self.get_records(qname, qtype) self.logger.debug('Record %r', records) for record in records: reply.add_answer(dnslib.RR( rname=qname, rtype=qtype, rdata=record, )) if queries: self.logger.debug('Awaiting gather') try: answers = await asyncio.gather( *queries, return_exceptions=True) except Exception as e: self.logger.error(e) else: self.logger.debug('gather complete %r', answers) for answer in answers: self.logger.debug('answer %r', answer) if isinstance(answer, Exception): self.logger.exception(answer) else: reply.add_answer(*answer.rr) if nxdomain: self.logger.debug('No answers') reply.header.set_rcode(RCODE.NXDOMAIN) return reply
def recv_worker(self): while self.running: try: response, server = self.sock.recvfrom(8192) except Exception as e: # xlog.exception("sock.recvfrom except:%r", e) continue if not response: continue try: p = DNSRecord.parse(response) except Exception as e: xlog.exception("parse response fail:%r", e) continue if len(p.questions) == 0: xlog.warn("received response without question") continue id = p.header.id if id not in self.waiters: continue que = self.waiters[id] org_domain = que.domain domain = str(p.questions[0].qname) xlog.debug("recev %s from:%s domain:%s org:%s", len(p.rr), server, domain, org_domain) ips = [] for r in p.rr: ip = str(r.rdata) if r.rtype == 5: # CNAME xlog.debug("local dns %s recv %s cname:%s from:%s", org_domain, domain, ip, server) d = DNSRecord(DNSHeader(id)) d.add_question(DNSQuestion(ip, QTYPE.A)) req_pack = d.pack() server = self.dns_server.get() self.sock.sendto(req_pack, (server, 53)) d = DNSRecord() d.add_question(DNSQuestion(ip, QTYPE.AAAA)) req_pack = d.pack() server = self.dns_server.get() self.sock.sendto(req_pack, (server, 53)) continue if "." in ip and g.ip_region.check_ip(ip): cn = g.ip_region.cn else: cn = "XX" ips.append(ip + "|" + cn) if len(ips): g.domain_cache.set_ips(org_domain, ips) que.notify_all() xlog.info("DNS Client recv worker exit.") self.sock.close()
def serve(self): try: udpsocket = socket(AF_INET, SOCK_DGRAM) udpsocket.bind((self.ip, self.port)) self.socket = udpsocket logging.getLogger().debug('now serving on %s/%s' % (self.ip, self.port)) while self.stayAlive: try: data, addr = self.socket.recvfrom(512) d = DNSRecord.parse(data) #print "Question from ",addr #print d question = d.get_q() qname = str(question.qname) qtype = str(QTYPE[question.qtype]).upper() try: ansdict = self.rbldnsd.lookup(qname) #logging.getLogger().debug("ansdict: %s"%ansdict) if qtype=='SOA': if ansdict['SOA']!=None: response = DNSRecord(DNSHeader(id=d.header.id, gr=1, aa=1, ra=1, qr=1, q=d.get_q())) soa=ansdict['SOA'] packet=SOA() packet.set_mname(soa[0]) packet.set_rname(soa[1]) packet.times=soa[2:] if 'SOATTL' in ansdict: packet.ttl=ansdict['SOATTL'] response.rr.append(packet) self.socket.sendto(response.pack(), addr) continue else: self.send_nxdomain(d, addr) continue elif qtype=='NS': if ansdict['NS']!=None: #TODO pass else: self.send_nxdomain(d, addr) continue elif qtype=='A' or qtype=='TXT': if 'results' not in ansdict: self.send_nxdomain(d, addr) logging.getLogger().debug("client=%s q=%s %s -> NXDOMAIN"%(addr[0],qname,qtype)) continue anslist=ansdict['results'] anspacklist=[] for answer in anslist: if answer==None: continue if qtype not in answer: continue packet=RR(question.qname,question.qtype,rdata=RDMAP[QTYPE[question.qtype]](answer[qtype])) if 'TTL' in answer and answer['TTL']!=None: packet.ttl=answer['TTL'] anspacklist.append(packet) if len(anspacklist)>0: response = DNSRecord(DNSHeader(id=d.header.id,bitmap=d.header.bitmap, aa=1, ra=0, qr=1,q=1)) response.add_question(question) response.rr.extend(anspacklist) response.set_header_qa() #logging.getLogger().debug(response) #make sure answer bit is set #response.header.qr=1 self.socket.sendto(response.pack(), addr) logging.getLogger().debug("client=%s q=%s %s -> NOERROR"%(addr[0],qname,qtype)) else: self.send_nxdomain(d, addr) logging.getLogger().debug("client=%s q=%s %s -> NXDOMAIN"%(addr[0],qname,qtype)) continue else: logging.getLogger().warning("unsupported qtype %s"%qtype) except: fmt = traceback.format_exc() logging.getLogger().error(fmt) self.send_servfail(d, addr) continue except Exception: fmt = traceback.format_exc() logging.getLogger().error(fmt) except: fmt = traceback.format_exc() logging.getLogger().error("Could not start serversocket on %s/%s: %s" % (self.ip, self.port, fmt)) logging.getLogger().debug('serve() complete')