class DnsServer(DatagramServer): ''' Answers DNS queries against the registry, falling back to the recursive resolver (if present). ''' def __init__(self, bindaddr, registry, dns_servers=None): DatagramServer.__init__(self, bindaddr) self._registry = registry self._resolver = None if dns_servers: self._resolver = Resolver(servers=dns_servers, timeout=DNS_RESOLVER_TIMEOUT, tries=1) def handle(self, data, peer): rec = DNSRecord.parse(data) addr = None if rec.q.qtype in (QTYPE.A, QTYPE.AAAA): log.debug('Quering DNS') addr = self._registry.resolve(rec.q.qname.idna()) if not addr: strArr = [] for l in rec.q.qname.label: strArr.append(str(l, 'utf-8')) domainName = '.'.join(strArr) addr = self._resolve(domainName) log.debug('Sending request to %s', addr) self.socket.sendto(self._reply(rec, addr), peer) def _reply(self, rec, addrs=None): reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1), q=rec.q) if addrs: if not isinstance(addrs, list): addrs = [addrs] for addr in addrs: if addr: reply.add_answer(RR(rec.q.qname, QTYPE.A, rdata=A(addr))) return reply.pack() def _resolve(self, name): log.debug('resolve name=%s', name) if not self._resolver: return None try: return self._resolver.gethostbyname(name) except socket.gaierror as e: log.debug('Host by name could not be resolved') msg = str(e) if not contains(msg, 'ETIMEOUT', 'ENOTFOUND'): print(msg)
class DnsServer(DatagramServer): ''' Answers DNS queries against the registry, falling back to the recursive resolver (if present). ''' def __init__(self, bindaddr, registry, dns_servers=None): DatagramServer.__init__(self, bindaddr) self._registry = registry self._resolver = None if dns_servers: self._resolver = Resolver(servers=dns_servers, timeout=DNS_RESOLVER_TIMEOUT, tries=1) def handle(self, data, peer): rec = DNSRecord.parse(data) addr = None if rec.q.qtype in (QTYPE.A, QTYPE.AAAA): log.debug('Quering DNS') addr = self._registry.resolve(rec.q.qname.idna()) if not addr: strArr = [] for l in rec.q.qname.label: strArr.append(str(l,'utf-8')) domainName = '.'.join(strArr) addr = self._resolve(domainName) log.debug('Sending request to %s', addr) self.socket.sendto(self._reply(rec, addr), peer) def _reply(self, rec, addrs=None): reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1), q=rec.q) if addrs: if not isinstance(addrs, list): addrs = [addrs] for addr in addrs: if addr: reply.add_answer(RR(rec.q.qname, QTYPE.A, rdata=A(addr))) return reply.pack() def _resolve(self, name): log.debug('resolve name=%s', name) if not self._resolver: return None try: return self._resolver.gethostbyname(name) except socket.gaierror as e: log.debug('Host by name could not be resolved') msg = str(e) if not contains(msg, 'ETIMEOUT', 'ENOTFOUND'): print(msg)
class DnsServer(DatagramServer): ''' Answers DNS queries against the registry, falling back to the recursive resolver (if present). ''' def __init__(self, bindaddr, registry, dns_servers=None): DatagramServer.__init__(self, bindaddr) self._registry = registry self._resolver = None if dns_servers: self._resolver = Resolver(servers=dns_servers, timeout=DNS_RESOLVER_TIMEOUT, tries=1) def handle(self, data, peer): rec = DNSRecord.parse(data) addr = None if rec.q.qtype in (QTYPE.A, QTYPE.AAAA): addr = self._registry.resolve(rec.q.qname.idna()) if not addr: addr = self._resolve('.'.join(rec.q.qname.label)) self.socket.sendto(self._reply(rec, addr), peer) def _reply(self, rec, addrs=None): reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1), q=rec.q) if addrs: if not isinstance(addrs, list): addrs = [addrs] for addr in addrs: if ":" in addr: reply.add_answer( RR(rec.q.qname, QTYPE.AAAA, rdata=AAAA(addr))) else: reply.add_answer(RR(rec.q.qname, QTYPE.A, rdata=A(addr))) return reply.pack() def _resolve(self, name): if not self._resolver: return None try: return self._resolver.gethostbyname(name) except socket.gaierror, e: msg = str(e) if not contains(msg, 'ETIMEOUT', 'ENOTFOUND'): print msg
class DnsServer(DatagramServer): """ Answers DNS queries against the name table, falling back to the recursive resolver (if present). """ def __init__(self, bindaddr, table, dns_servers=None): DatagramServer.__init__(self, bindaddr) self._table = table self._resolver = None if dns_servers: self._resolver = Resolver(servers=dns_servers, timeout=DNS_RESOLVER_TIMEOUT, tries=1) def handle(self, data, peer): rec = DNSRecord.parse(data) addr = None if rec.q.qtype in (QTYPE.A, QTYPE.AAAA): addr = self._table.get(rec.q.qname.idna()) if not addr: addr = self._resolve(".".join(rec.q.qname.label)) self.socket.sendto(self._reply(rec, addr), peer) def _reply(self, rec, addr=None): reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1), q=rec.q) if addr: qtype = QTYPE.A if QTYPE.A == rec.q.qtype else QTYPE.AAAA reply.add_answer(RR(rec.q.qname, qtype, rdata=A(addr))) rep = reply.pack() return rep def _resolve(self, name): if not self._resolver: return None try: return self._resolver.gethostbyname(name) except socket.gaierror, e: msg = str(e) if not contains(msg, "ETIMEOUT", "ENOTFOUND"): print msg
class DnsServer(DatagramServer): """ Answers DNS queries against the registry, falling back to the recursive resolver (if present). """ def __init__(self, bindaddr, registry, dns_servers=None): DatagramServer.__init__(self, bindaddr) self._registry = registry self._resolver = None if dns_servers: log.info("[namesrv] starting with failover resolver %s", dns_servers) self._resolver = Resolver(servers=dns_servers, timeout=DNS_RESOLVER_TIMEOUT, tries=1) def handle(self, data, peer): rec = DNSRecord.parse(data) addrs = None auth = False if rec.q.qtype in (QTYPE.A, QTYPE.AAAA, QTYPE.ANY): addrs = self._registry.resolve(rec.q.qname.idna()) or set() if addrs: auth = True # answer AAAA queries for existing A records # with an successful but empty result if rec.q.qtype == QTYPE.AAAA: addrs = None else: log.debug("[namesrv] resolved %s to %s", rec.q.qname.idna(), addrs) else: addr = self._resolve('.'.join(rec.q.qname.label)) if addr: addrs.add(addr) log.debug("[namesrv] externally resolved %s to %s", rec.q.qname.idna(), addrs) if addrs: addrs = list(addrs) self.socket.sendto(self._reply(rec, auth, addrs), peer) def _reply(self, rec, auth, addrs=None): reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=auth, ra=bool(self._resolver)), q=rec.q) if addrs: if not isinstance(addrs, list): addrs = [addrs] for addr in addrs[0:15]: reply.add_answer(RR(rec.q.qname, QTYPE.A, rdata=A(addr))) return reply.pack() def _resolve(self, name): if not self._resolver: log.info("DnsServer._resolve is not set") return None try: return self._resolver.gethostbyname(name) except Exception as e: # socket.gaierror as e: if not contains(str(e), 'ETIMEOUT', 'ENOTFOUND'): log.error("Exception in DnsServer._resolve", e) return None