dnspython  1.16.0
About: dnspython is a DNS toolkit (for Python 2.x) that supports almost all record types.
  Fossies Dox: dnspython-1.16.0.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

resolver.py
Go to the documentation of this file.
1 # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
2 
3 # Copyright (C) 2003-2017 Nominum, Inc.
4 #
5 # Permission to use, copy, modify, and distribute this software and its
6 # documentation for any purpose with or without fee is hereby granted,
7 # provided that the above copyright notice and this permission notice
8 # appear in all copies.
9 #
10 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
11 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
13 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 
18 """DNS stub resolver."""
19 
20 import socket
21 import sys
22 import time
23 import random
24 
25 try:
26  import threading as _threading
27 except ImportError:
28  import dummy_threading as _threading
29 
30 import dns.exception
31 import dns.flags
32 import dns.ipv4
33 import dns.ipv6
34 import dns.message
35 import dns.name
36 import dns.query
37 import dns.rcode
38 import dns.rdataclass
39 import dns.rdatatype
40 import dns.reversename
41 import dns.tsig
42 from ._compat import xrange, string_types
43 
44 if sys.platform == 'win32':
45  try:
46  import winreg as _winreg
47  except ImportError:
48  import _winreg # pylint: disable=import-error
49 
51  """The DNS query name does not exist."""
52  supp_kwargs = {'qnames', 'responses'}
53  fmt = None # we have our own __str__ implementation
54 
55  def _check_kwargs(self, qnames, responses=None):
56  if not isinstance(qnames, (list, tuple, set)):
57  raise AttributeError("qnames must be a list, tuple or set")
58  if len(qnames) == 0:
59  raise AttributeError("qnames must contain at least one element")
60  if responses is None:
61  responses = {}
62  elif not isinstance(responses, dict):
63  raise AttributeError("responses must be a dict(qname=response)")
64  kwargs = dict(qnames=qnames, responses=responses)
65  return kwargs
66 
67  def __str__(self):
68  if 'qnames' not in self.kwargs:
69  return super(NXDOMAIN, self).__str__()
70  qnames = self.kwargs['qnames']
71  if len(qnames) > 1:
72  msg = 'None of DNS query names exist'
73  else:
74  msg = 'The DNS query name does not exist'
75  qnames = ', '.join(map(str, qnames))
76  return "{}: {}".format(msg, qnames)
77 
78  def canonical_name(self):
79  if not 'qnames' in self.kwargs:
80  raise TypeError("parametrized exception required")
81  IN = dns.rdataclass.IN
82  CNAME = dns.rdatatype.CNAME
83  cname = None
84  for qname in self.kwargs['qnames']:
85  response = self.kwargs['responses'][qname]
86  for answer in response.answer:
87  if answer.rdtype != CNAME or answer.rdclass != IN:
88  continue
89  cname = answer.items[0].target.to_text()
90  if cname is not None:
91  return dns.name.from_text(cname)
92  return self.kwargs['qnames'][0]
93  canonical_name = property(canonical_name, doc=(
94  "Return the unresolved canonical name."))
95 
96  def __add__(self, e_nx):
97  """Augment by results from another NXDOMAIN exception."""
98  qnames0 = list(self.kwargs.get('qnames', []))
99  responses0 = dict(self.kwargs.get('responses', {}))
100  responses1 = e_nx.kwargs.get('responses', {})
101  for qname1 in e_nx.kwargs.get('qnames', []):
102  if qname1 not in qnames0:
103  qnames0.append(qname1)
104  if qname1 in responses1:
105  responses0[qname1] = responses1[qname1]
106  return NXDOMAIN(qnames=qnames0, responses=responses0)
107 
108  def qnames(self):
109  """All of the names that were tried.
110 
111  Returns a list of ``dns.name.Name``.
112  """
113  return self.kwargs['qnames']
114 
115  def responses(self):
116  """A map from queried names to their NXDOMAIN responses.
117 
118  Returns a dict mapping a ``dns.name.Name`` to a
119  ``dns.message.Message``.
120  """
121  return self.kwargs['responses']
122 
123  def response(self, qname):
124  """The response for query *qname*.
125 
126  Returns a ``dns.message.Message``.
127  """
128  return self.kwargs['responses'][qname]
129 
130 
132  """The DNS query name is too long after DNAME substitution."""
133 
134 # The definition of the Timeout exception has moved from here to the
135 # dns.exception module. We keep dns.resolver.Timeout defined for
136 # backwards compatibility.
137 
139 
140 
142  """The DNS response does not contain an answer to the question."""
143  fmt = 'The DNS response does not contain an answer ' + \
144  'to the question: {query}'
145  supp_kwargs = {'response'}
146 
147  def _fmt_kwargs(self, **kwargs):
148  return super(NoAnswer, self)._fmt_kwargs(
149  query=kwargs['response'].question)
150 
151 
153  """All nameservers failed to answer the query.
154 
155  errors: list of servers and respective errors
156  The type of errors is
157  [(server IP address, any object convertible to string)].
158  Non-empty errors list will add explanatory message ()
159  """
160 
161  msg = "All nameservers failed to answer the query."
162  fmt = "%s {query}: {errors}" % msg[:-1]
163  supp_kwargs = {'request', 'errors'}
164 
165  def _fmt_kwargs(self, **kwargs):
166  srv_msgs = []
167  for err in kwargs['errors']:
168  srv_msgs.append('Server {} {} port {} answered {}'.format(err[0],
169  'TCP' if err[1] else 'UDP', err[2], err[3]))
170  return super(NoNameservers, self)._fmt_kwargs(
171  query=kwargs['request'].question, errors='; '.join(srv_msgs))
172 
173 
175  """An absolute domain name is required but a relative name was provided."""
176 
177 
178 class NoRootSOA(dns.exception.DNSException):
179  """There is no SOA RR at the DNS root name. This should never happen!"""
180 
181 
183  """DNS metaqueries are not allowed."""
184 
185 
186 class Answer(object):
187  """DNS stub resolver answer.
188 
189  Instances of this class bundle up the result of a successful DNS
190  resolution.
191 
192  For convenience, the answer object implements much of the sequence
193  protocol, forwarding to its ``rrset`` attribute. E.g.
194  ``for a in answer`` is equivalent to ``for a in answer.rrset``.
195  ``answer[i]`` is equivalent to ``answer.rrset[i]``, and
196  ``answer[i:j]`` is equivalent to ``answer.rrset[i:j]``.
197 
198  Note that CNAMEs or DNAMEs in the response may mean that answer
199  RRset's name might not be the query name.
200  """
201 
202  def __init__(self, qname, rdtype, rdclass, response,
203  raise_on_no_answer=True):
204  self.qname = qname
205  self.rdtype = rdtype
206  self.rdclass = rdclass
207  self.response = response
208  min_ttl = -1
209  rrset = None
210  for count in xrange(0, 15):
211  try:
212  rrset = response.find_rrset(response.answer, qname,
213  rdclass, rdtype)
214  if min_ttl == -1 or rrset.ttl < min_ttl:
215  min_ttl = rrset.ttl
216  break
217  except KeyError:
218  if rdtype != dns.rdatatype.CNAME:
219  try:
220  crrset = response.find_rrset(response.answer,
221  qname,
222  rdclass,
223  dns.rdatatype.CNAME)
224  if min_ttl == -1 or crrset.ttl < min_ttl:
225  min_ttl = crrset.ttl
226  for rd in crrset:
227  qname = rd.target
228  break
229  continue
230  except KeyError:
231  if raise_on_no_answer:
232  raise NoAnswer(response=response)
233  if raise_on_no_answer:
234  raise NoAnswer(response=response)
235  if rrset is None and raise_on_no_answer:
236  raise NoAnswer(response=response)
237  self.canonical_name = qname
238  self.rrset = rrset
239  if rrset is None:
240  while 1:
241  # Look for a SOA RR whose owner name is a superdomain
242  # of qname.
243  try:
244  srrset = response.find_rrset(response.authority, qname,
245  rdclass, dns.rdatatype.SOA)
246  if min_ttl == -1 or srrset.ttl < min_ttl:
247  min_ttl = srrset.ttl
248  if srrset[0].minimum < min_ttl:
249  min_ttl = srrset[0].minimum
250  break
251  except KeyError:
252  try:
253  qname = qname.parent()
254  except dns.name.NoParent:
255  break
256  self.expiration = time.time() + min_ttl
257 
258  def __getattr__(self, attr):
259  if attr == 'name':
260  return self.rrset.name
261  elif attr == 'ttl':
262  return self.rrset.ttl
263  elif attr == 'covers':
264  return self.rrset.covers
265  elif attr == 'rdclass':
266  return self.rrset.rdclass
267  elif attr == 'rdtype':
268  return self.rrset.rdtype
269  else:
270  raise AttributeError(attr)
271 
272  def __len__(self):
273  return self.rrset and len(self.rrset) or 0
274 
275  def __iter__(self):
276  return self.rrset and iter(self.rrset) or iter(tuple())
277 
278  def __getitem__(self, i):
279  if self.rrset is None:
280  raise IndexError
281  return self.rrset[i]
282 
283  def __delitem__(self, i):
284  if self.rrset is None:
285  raise IndexError
286  del self.rrset[i]
287 
288 
289 class Cache(object):
290  """Simple thread-safe DNS answer cache."""
291 
292  def __init__(self, cleaning_interval=300.0):
293  """*cleaning_interval*, a ``float`` is the number of seconds between
294  periodic cleanings.
295  """
296 
297  self.data = {}
298  self.cleaning_interval = cleaning_interval
299  self.next_cleaning = time.time() + self.cleaning_interval
300  self.lock = _threading.Lock()
301 
302  def _maybe_clean(self):
303  """Clean the cache if it's time to do so."""
304 
305  now = time.time()
306  if self.next_cleaning <= now:
307  keys_to_delete = []
308  for (k, v) in self.data.items():
309  if v.expiration <= now:
310  keys_to_delete.append(k)
311  for k in keys_to_delete:
312  del self.data[k]
313  now = time.time()
314  self.next_cleaning = now + self.cleaning_interval
315 
316  def get(self, key):
317  """Get the answer associated with *key*.
318 
319  Returns None if no answer is cached for the key.
320 
321  *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the
322  query name, rdtype, and rdclass respectively.
323 
324  Returns a ``dns.resolver.Answer`` or ``None``.
325  """
326 
327  try:
328  self.lock.acquire()
329  self._maybe_clean()
330  v = self.data.get(key)
331  if v is None or v.expiration <= time.time():
332  return None
333  return v
334  finally:
335  self.lock.release()
336 
337  def put(self, key, value):
338  """Associate key and value in the cache.
339 
340  *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the
341  query name, rdtype, and rdclass respectively.
342 
343  *value*, a ``dns.resolver.Answer``, the answer.
344  """
345 
346  try:
347  self.lock.acquire()
348  self._maybe_clean()
349  self.data[key] = value
350  finally:
351  self.lock.release()
352 
353  def flush(self, key=None):
354  """Flush the cache.
355 
356  If *key* is not ``None``, only that item is flushed. Otherwise
357  the entire cache is flushed.
358 
359  *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the
360  query name, rdtype, and rdclass respectively.
361  """
362 
363  try:
364  self.lock.acquire()
365  if key is not None:
366  if key in self.data:
367  del self.data[key]
368  else:
369  self.data = {}
370  self.next_cleaning = time.time() + self.cleaning_interval
371  finally:
372  self.lock.release()
373 
374 
375 class LRUCacheNode(object):
376  """LRUCache node."""
377 
378  def __init__(self, key, value):
379  self.key = key
380  self.value = value
381  self.prev = self
382  self.next = self
383 
384  def link_before(self, node):
385  self.prev = node.prev
386  self.next = node
387  node.prev.next = self
388  node.prev = self
389 
390  def link_after(self, node):
391  self.prev = node
392  self.next = node.next
393  node.next.prev = self
394  node.next = self
395 
396  def unlink(self):
397  self.next.prev = self.prev
398  self.prev.next = self.next
399 
400 
401 class LRUCache(object):
402  """Thread-safe, bounded, least-recently-used DNS answer cache.
403 
404  This cache is better than the simple cache (above) if you're
405  running a web crawler or other process that does a lot of
406  resolutions. The LRUCache has a maximum number of nodes, and when
407  it is full, the least-recently used node is removed to make space
408  for a new one.
409  """
410 
411  def __init__(self, max_size=100000):
412  """*max_size*, an ``int``, is the maximum number of nodes to cache;
413  it must be greater than 0.
414  """
415 
416  self.data = {}
417  self.set_max_size(max_size)
418  self.sentinel = LRUCacheNode(None, None)
419  self.lock = _threading.Lock()
420 
421  def set_max_size(self, max_size):
422  if max_size < 1:
423  max_size = 1
424  self.max_size = max_size
425 
426  def get(self, key):
427  """Get the answer associated with *key*.
428 
429  Returns None if no answer is cached for the key.
430 
431  *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the
432  query name, rdtype, and rdclass respectively.
433 
434  Returns a ``dns.resolver.Answer`` or ``None``.
435  """
436 
437  try:
438  self.lock.acquire()
439  node = self.data.get(key)
440  if node is None:
441  return None
442  # Unlink because we're either going to move the node to the front
443  # of the LRU list or we're going to free it.
444  node.unlink()
445  if node.value.expiration <= time.time():
446  del self.data[node.key]
447  return None
448  node.link_after(self.sentinel)
449  return node.value
450  finally:
451  self.lock.release()
452 
453  def put(self, key, value):
454  """Associate key and value in the cache.
455 
456  *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the
457  query name, rdtype, and rdclass respectively.
458 
459  *value*, a ``dns.resolver.Answer``, the answer.
460  """
461 
462  try:
463  self.lock.acquire()
464  node = self.data.get(key)
465  if node is not None:
466  node.unlink()
467  del self.data[node.key]
468  while len(self.data) >= self.max_size:
469  node = self.sentinel.prev
470  node.unlink()
471  del self.data[node.key]
472  node = LRUCacheNode(key, value)
473  node.link_after(self.sentinel)
474  self.data[key] = node
475  finally:
476  self.lock.release()
477 
478  def flush(self, key=None):
479  """Flush the cache.
480 
481  If *key* is not ``None``, only that item is flushed. Otherwise
482  the entire cache is flushed.
483 
484  *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the
485  query name, rdtype, and rdclass respectively.
486  """
487 
488  try:
489  self.lock.acquire()
490  if key is not None:
491  node = self.data.get(key)
492  if node is not None:
493  node.unlink()
494  del self.data[node.key]
495  else:
496  node = self.sentinel.next
497  while node != self.sentinel:
498  next = node.next
499  node.prev = None
500  node.next = None
501  node = next
502  self.data = {}
503  finally:
504  self.lock.release()
505 
506 
507 class Resolver(object):
508  """DNS stub resolver."""
509 
510  def __init__(self, filename='/etc/resolv.conf', configure=True):
511  """*filename*, a ``text`` or file object, specifying a file
512  in standard /etc/resolv.conf format. This parameter is meaningful
513  only when *configure* is true and the platform is POSIX.
514 
515  *configure*, a ``bool``. If True (the default), the resolver
516  instance is configured in the normal fashion for the operating
517  system the resolver is running on. (I.e. by reading a
518  /etc/resolv.conf file on POSIX systems and from the registry
519  on Windows systems.)
520  """
521 
522  self.domain = None
523  self.nameservers = None
524  self.nameserver_ports = None
525  self.port = None
526  self.search = None
527  self.timeout = None
528  self.lifetime = None
529  self.keyring = None
530  self.keyname = None
531  self.keyalgorithm = None
532  self.edns = None
533  self.ednsflags = None
534  self.payload = None
535  self.cache = None
536  self.flags = None
537  self.retry_servfail = False
538  self.rotate = False
539 
540  self.reset()
541  if configure:
542  if sys.platform == 'win32':
543  self.read_registry()
544  elif filename:
545  self.read_resolv_conf(filename)
546 
547  def reset(self):
548  """Reset all resolver configuration to the defaults."""
549 
550  self.domain = \
551  dns.name.Name(dns.name.from_text(socket.gethostname())[1:])
552  if len(self.domain) == 0:
553  self.domain = dns.name.root
554  self.nameservers = []
555  self.nameserver_ports = {}
556  self.port = 53
557  self.search = []
558  self.timeout = 2.0
559  self.lifetime = 30.0
560  self.keyring = None
561  self.keyname = None
562  self.keyalgorithm = dns.tsig.default_algorithm
563  self.edns = -1
564  self.ednsflags = 0
565  self.payload = 0
566  self.cache = None
567  self.flags = None
568  self.retry_servfail = False
569  self.rotate = False
570 
571  def read_resolv_conf(self, f):
572  """Process *f* as a file in the /etc/resolv.conf format. If f is
573  a ``text``, it is used as the name of the file to open; otherwise it
574  is treated as the file itself."""
575 
576  if isinstance(f, string_types):
577  try:
578  f = open(f, 'r')
579  except IOError:
580  # /etc/resolv.conf doesn't exist, can't be read, etc.
581  # We'll just use the default resolver configuration.
582  self.nameservers = ['127.0.0.1']
583  return
584  want_close = True
585  else:
586  want_close = False
587  try:
588  for l in f:
589  if len(l) == 0 or l[0] == '#' or l[0] == ';':
590  continue
591  tokens = l.split()
592 
593  # Any line containing less than 2 tokens is malformed
594  if len(tokens) < 2:
595  continue
596 
597  if tokens[0] == 'nameserver':
598  self.nameservers.append(tokens[1])
599  elif tokens[0] == 'domain':
600  self.domain = dns.name.from_text(tokens[1])
601  elif tokens[0] == 'search':
602  for suffix in tokens[1:]:
603  self.search.append(dns.name.from_text(suffix))
604  elif tokens[0] == 'options':
605  if 'rotate' in tokens[1:]:
606  self.rotate = True
607  finally:
608  if want_close:
609  f.close()
610  if len(self.nameservers) == 0:
611  self.nameservers.append('127.0.0.1')
612 
613  def _determine_split_char(self, entry):
614  #
615  # The windows registry irritatingly changes the list element
616  # delimiter in between ' ' and ',' (and vice-versa) in various
617  # versions of windows.
618  #
619  if entry.find(' ') >= 0:
620  split_char = ' '
621  elif entry.find(',') >= 0:
622  split_char = ','
623  else:
624  # probably a singleton; treat as a space-separated list.
625  split_char = ' '
626  return split_char
627 
628  def _config_win32_nameservers(self, nameservers):
629  # we call str() on nameservers to convert it from unicode to ascii
630  nameservers = str(nameservers)
631  split_char = self._determine_split_char(nameservers)
632  ns_list = nameservers.split(split_char)
633  for ns in ns_list:
634  if ns not in self.nameservers:
635  self.nameservers.append(ns)
636 
637  def _config_win32_domain(self, domain):
638  # we call str() on domain to convert it from unicode to ascii
639  self.domain = dns.name.from_text(str(domain))
640 
641  def _config_win32_search(self, search):
642  # we call str() on search to convert it from unicode to ascii
643  search = str(search)
644  split_char = self._determine_split_char(search)
645  search_list = search.split(split_char)
646  for s in search_list:
647  if s not in self.search:
648  self.search.append(dns.name.from_text(s))
649 
650  def _config_win32_fromkey(self, key, always_try_domain):
651  try:
652  servers, rtype = _winreg.QueryValueEx(key, 'NameServer')
653  except WindowsError: # pylint: disable=undefined-variable
654  servers = None
655  if servers:
656  self._config_win32_nameservers(servers)
657  if servers or always_try_domain:
658  try:
659  dom, rtype = _winreg.QueryValueEx(key, 'Domain')
660  if dom:
661  self._config_win32_domain(dom)
662  except WindowsError: # pylint: disable=undefined-variable
663  pass
664  else:
665  try:
666  servers, rtype = _winreg.QueryValueEx(key, 'DhcpNameServer')
667  except WindowsError: # pylint: disable=undefined-variable
668  servers = None
669  if servers:
670  self._config_win32_nameservers(servers)
671  try:
672  dom, rtype = _winreg.QueryValueEx(key, 'DhcpDomain')
673  if dom:
674  self._config_win32_domain(dom)
675  except WindowsError: # pylint: disable=undefined-variable
676  pass
677  try:
678  search, rtype = _winreg.QueryValueEx(key, 'SearchList')
679  except WindowsError: # pylint: disable=undefined-variable
680  search = None
681  if search:
682  self._config_win32_search(search)
683 
684  def read_registry(self):
685  """Extract resolver configuration from the Windows registry."""
686 
687  lm = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
688  want_scan = False
689  try:
690  try:
691  # XP, 2000
692  tcp_params = _winreg.OpenKey(lm,
693  r'SYSTEM\CurrentControlSet'
694  r'\Services\Tcpip\Parameters')
695  want_scan = True
696  except EnvironmentError:
697  # ME
698  tcp_params = _winreg.OpenKey(lm,
699  r'SYSTEM\CurrentControlSet'
700  r'\Services\VxD\MSTCP')
701  try:
702  self._config_win32_fromkey(tcp_params, True)
703  finally:
704  tcp_params.Close()
705  if want_scan:
706  interfaces = _winreg.OpenKey(lm,
707  r'SYSTEM\CurrentControlSet'
708  r'\Services\Tcpip\Parameters'
709  r'\Interfaces')
710  try:
711  i = 0
712  while True:
713  try:
714  guid = _winreg.EnumKey(interfaces, i)
715  i += 1
716  key = _winreg.OpenKey(interfaces, guid)
717  if not self._win32_is_nic_enabled(lm, guid, key):
718  continue
719  try:
720  self._config_win32_fromkey(key, False)
721  finally:
722  key.Close()
723  except EnvironmentError:
724  break
725  finally:
726  interfaces.Close()
727  finally:
728  lm.Close()
729 
730  def _win32_is_nic_enabled(self, lm, guid, interface_key):
731  # Look in the Windows Registry to determine whether the network
732  # interface corresponding to the given guid is enabled.
733  #
734  # (Code contributed by Paul Marks, thanks!)
735  #
736  try:
737  # This hard-coded location seems to be consistent, at least
738  # from Windows 2000 through Vista.
739  connection_key = _winreg.OpenKey(
740  lm,
741  r'SYSTEM\CurrentControlSet\Control\Network'
742  r'\{4D36E972-E325-11CE-BFC1-08002BE10318}'
743  r'\%s\Connection' % guid)
744 
745  try:
746  # The PnpInstanceID points to a key inside Enum
747  (pnp_id, ttype) = _winreg.QueryValueEx(
748  connection_key, 'PnpInstanceID')
749 
750  if ttype != _winreg.REG_SZ:
751  raise ValueError
752 
753  device_key = _winreg.OpenKey(
754  lm, r'SYSTEM\CurrentControlSet\Enum\%s' % pnp_id)
755 
756  try:
757  # Get ConfigFlags for this device
758  (flags, ttype) = _winreg.QueryValueEx(
759  device_key, 'ConfigFlags')
760 
761  if ttype != _winreg.REG_DWORD:
762  raise ValueError
763 
764  # Based on experimentation, bit 0x1 indicates that the
765  # device is disabled.
766  return not flags & 0x1
767 
768  finally:
769  device_key.Close()
770  finally:
771  connection_key.Close()
772  except (EnvironmentError, ValueError):
773  # Pre-vista, enabled interfaces seem to have a non-empty
774  # NTEContextList; this was how dnspython detected enabled
775  # nics before the code above was contributed. We've retained
776  # the old method since we don't know if the code above works
777  # on Windows 95/98/ME.
778  try:
779  (nte, ttype) = _winreg.QueryValueEx(interface_key,
780  'NTEContextList')
781  return nte is not None
782  except WindowsError: # pylint: disable=undefined-variable
783  return False
784 
785  def _compute_timeout(self, start, lifetime=None):
786  lifetime = self.lifetime if lifetime is None else lifetime
787  now = time.time()
788  duration = now - start
789  if duration < 0:
790  if duration < -1:
791  # Time going backwards is bad. Just give up.
792  raise Timeout(timeout=duration)
793  else:
794  # Time went backwards, but only a little. This can
795  # happen, e.g. under vmware with older linux kernels.
796  # Pretend it didn't happen.
797  now = start
798  if duration >= lifetime:
799  raise Timeout(timeout=duration)
800  return min(lifetime - duration, self.timeout)
801 
802  def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
803  tcp=False, source=None, raise_on_no_answer=True, source_port=0,
804  lifetime=None):
805  """Query nameservers to find the answer to the question.
806 
807  The *qname*, *rdtype*, and *rdclass* parameters may be objects
808  of the appropriate type, or strings that can be converted into objects
809  of the appropriate type.
810 
811  *qname*, a ``dns.name.Name`` or ``text``, the query name.
812 
813  *rdtype*, an ``int`` or ``text``, the query type.
814 
815  *rdclass*, an ``int`` or ``text``, the query class.
816 
817  *tcp*, a ``bool``. If ``True``, use TCP to make the query.
818 
819  *source*, a ``text`` or ``None``. If not ``None``, bind to this IP
820  address when making queries.
821 
822  *raise_on_no_answer*, a ``bool``. If ``True``, raise
823  ``dns.resolver.NoAnswer`` if there's no answer to the question.
824 
825  *source_port*, an ``int``, the port from which to send the message.
826 
827  *lifetime*, a ``float``, how long query should run before timing out.
828 
829  Raises ``dns.exception.Timeout`` if no answers could be found
830  in the specified lifetime.
831 
832  Raises ``dns.resolver.NXDOMAIN`` if the query name does not exist.
833 
834  Raises ``dns.resolver.YXDOMAIN`` if the query name is too long after
835  DNAME substitution.
836 
837  Raises ``dns.resolver.NoAnswer`` if *raise_on_no_answer* is
838  ``True`` and the query name exists but has no RRset of the
839  desired type and class.
840 
841  Raises ``dns.resolver.NoNameservers`` if no non-broken
842  nameservers are available to answer the question.
843 
844  Returns a ``dns.resolver.Answer`` instance.
845  """
846 
847  if isinstance(qname, string_types):
848  qname = dns.name.from_text(qname, None)
849  if isinstance(rdtype, string_types):
850  rdtype = dns.rdatatype.from_text(rdtype)
851  if dns.rdatatype.is_metatype(rdtype):
852  raise NoMetaqueries
853  if isinstance(rdclass, string_types):
854  rdclass = dns.rdataclass.from_text(rdclass)
855  if dns.rdataclass.is_metaclass(rdclass):
856  raise NoMetaqueries
857  qnames_to_try = []
858  if qname.is_absolute():
859  qnames_to_try.append(qname)
860  else:
861  if len(qname) > 1:
862  qnames_to_try.append(qname.concatenate(dns.name.root))
863  if self.search:
864  for suffix in self.search:
865  qnames_to_try.append(qname.concatenate(suffix))
866  else:
867  qnames_to_try.append(qname.concatenate(self.domain))
868  all_nxdomain = True
869  nxdomain_responses = {}
870  start = time.time()
871  _qname = None # make pylint happy
872  for _qname in qnames_to_try:
873  if self.cache:
874  answer = self.cache.get((_qname, rdtype, rdclass))
875  if answer is not None:
876  if answer.rrset is None and raise_on_no_answer:
877  raise NoAnswer(response=answer.response)
878  else:
879  return answer
880  request = dns.message.make_query(_qname, rdtype, rdclass)
881  if self.keyname is not None:
882  request.use_tsig(self.keyring, self.keyname,
883  algorithm=self.keyalgorithm)
884  request.use_edns(self.edns, self.ednsflags, self.payload)
885  if self.flags is not None:
886  request.flags = self.flags
887  response = None
888  #
889  # make a copy of the servers list so we can alter it later.
890  #
891  nameservers = self.nameservers[:]
892  errors = []
893  if self.rotate:
894  random.shuffle(nameservers)
895  backoff = 0.10
896  while response is None:
897  if len(nameservers) == 0:
898  raise NoNameservers(request=request, errors=errors)
899  for nameserver in nameservers[:]:
900  timeout = self._compute_timeout(start, lifetime)
901  port = self.nameserver_ports.get(nameserver, self.port)
902  try:
903  tcp_attempt = tcp
904  if tcp:
905  response = dns.query.tcp(request, nameserver,
906  timeout, port,
907  source=source,
908  source_port=source_port)
909  else:
910  response = dns.query.udp(request, nameserver,
911  timeout, port,
912  source=source,
913  source_port=source_port)
914  if response.flags & dns.flags.TC:
915  # Response truncated; retry with TCP.
916  tcp_attempt = True
917  timeout = self._compute_timeout(start, lifetime)
918  response = \
919  dns.query.tcp(request, nameserver,
920  timeout, port,
921  source=source,
922  source_port=source_port)
923  except (socket.error, dns.exception.Timeout) as ex:
924  #
925  # Communication failure or timeout. Go to the
926  # next server
927  #
928  errors.append((nameserver, tcp_attempt, port, ex,
929  response))
930  response = None
931  continue
932  except dns.query.UnexpectedSource as ex:
933  #
934  # Who knows? Keep going.
935  #
936  errors.append((nameserver, tcp_attempt, port, ex,
937  response))
938  response = None
939  continue
940  except dns.exception.FormError as ex:
941  #
942  # We don't understand what this server is
943  # saying. Take it out of the mix and
944  # continue.
945  #
946  nameservers.remove(nameserver)
947  errors.append((nameserver, tcp_attempt, port, ex,
948  response))
949  response = None
950  continue
951  except EOFError as ex:
952  #
953  # We're using TCP and they hung up on us.
954  # Probably they don't support TCP (though
955  # they're supposed to!). Take it out of the
956  # mix and continue.
957  #
958  nameservers.remove(nameserver)
959  errors.append((nameserver, tcp_attempt, port, ex,
960  response))
961  response = None
962  continue
963  rcode = response.rcode()
964  if rcode == dns.rcode.YXDOMAIN:
965  ex = YXDOMAIN()
966  errors.append((nameserver, tcp_attempt, port, ex,
967  response))
968  raise ex
969  if rcode == dns.rcode.NOERROR or \
970  rcode == dns.rcode.NXDOMAIN:
971  break
972  #
973  # We got a response, but we're not happy with the
974  # rcode in it. Remove the server from the mix if
975  # the rcode isn't SERVFAIL.
976  #
977  if rcode != dns.rcode.SERVFAIL or not self.retry_servfail:
978  nameservers.remove(nameserver)
979  errors.append((nameserver, tcp_attempt, port,
980  dns.rcode.to_text(rcode), response))
981  response = None
982  if response is not None:
983  break
984  #
985  # All nameservers failed!
986  #
987  if len(nameservers) > 0:
988  #
989  # But we still have servers to try. Sleep a bit
990  # so we don't pound them!
991  #
992  timeout = self._compute_timeout(start, lifetime)
993  sleep_time = min(timeout, backoff)
994  backoff *= 2
995  time.sleep(sleep_time)
996  if response.rcode() == dns.rcode.NXDOMAIN:
997  nxdomain_responses[_qname] = response
998  continue
999  all_nxdomain = False
1000  break
1001  if all_nxdomain:
1002  raise NXDOMAIN(qnames=qnames_to_try, responses=nxdomain_responses)
1003  answer = Answer(_qname, rdtype, rdclass, response,
1004  raise_on_no_answer)
1005  if self.cache:
1006  self.cache.put((_qname, rdtype, rdclass), answer)
1007  return answer
1008 
1009  def use_tsig(self, keyring, keyname=None,
1010  algorithm=dns.tsig.default_algorithm):
1011  """Add a TSIG signature to the query.
1012 
1013  See the documentation of the Message class for a complete
1014  description of the keyring dictionary.
1015 
1016  *keyring*, a ``dict``, the TSIG keyring to use. If a
1017  *keyring* is specified but a *keyname* is not, then the key
1018  used will be the first key in the *keyring*. Note that the
1019  order of keys in a dictionary is not defined, so applications
1020  should supply a keyname when a keyring is used, unless they
1021  know the keyring contains only one key.
1022 
1023  *keyname*, a ``dns.name.Name`` or ``None``, the name of the TSIG key
1024  to use; defaults to ``None``. The key must be defined in the keyring.
1025 
1026  *algorithm*, a ``dns.name.Name``, the TSIG algorithm to use.
1027  """
1028 
1029  self.keyring = keyring
1030  if keyname is None:
1031  self.keyname = list(self.keyring.keys())[0]
1032  else:
1033  self.keyname = keyname
1034  self.keyalgorithm = algorithm
1035 
1036  def use_edns(self, edns, ednsflags, payload):
1037  """Configure EDNS behavior.
1038 
1039  *edns*, an ``int``, is the EDNS level to use. Specifying
1040  ``None``, ``False``, or ``-1`` means "do not use EDNS", and in this case
1041  the other parameters are ignored. Specifying ``True`` is
1042  equivalent to specifying 0, i.e. "use EDNS0".
1043 
1044  *ednsflags*, an ``int``, the EDNS flag values.
1045 
1046  *payload*, an ``int``, is the EDNS sender's payload field, which is the
1047  maximum size of UDP datagram the sender can handle. I.e. how big
1048  a response to this message can be.
1049  """
1050 
1051  if edns is None:
1052  edns = -1
1053  self.edns = edns
1054  self.ednsflags = ednsflags
1055  self.payload = payload
1056 
1057  def set_flags(self, flags):
1058  """Overrides the default flags with your own.
1059 
1060  *flags*, an ``int``, the message flags to use.
1061  """
1062 
1063  self.flags = flags
1064 
1065 
1066 #: The default resolver.
1067 default_resolver = None
1068 
1069 
1071  """Get the default resolver, initializing it if necessary."""
1072  if default_resolver is None:
1074  return default_resolver
1075 
1076 
1078  """Re-initialize default resolver.
1079 
1080  Note that the resolver configuration (i.e. /etc/resolv.conf on UNIX
1081  systems) will be re-read immediately.
1082  """
1083 
1084  global default_resolver
1085  default_resolver = Resolver()
1086 
1087 
1088 def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
1089  tcp=False, source=None, raise_on_no_answer=True,
1090  source_port=0, lifetime=None):
1091  """Query nameservers to find the answer to the question.
1092 
1093  This is a convenience function that uses the default resolver
1094  object to make the query.
1095 
1096  See ``dns.resolver.Resolver.query`` for more information on the
1097  parameters.
1098  """
1099 
1100  return get_default_resolver().query(qname, rdtype, rdclass, tcp, source,
1101  raise_on_no_answer, source_port,
1102  lifetime)
1103 
1104 
1105 def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None):
1106  """Find the name of the zone which contains the specified name.
1107 
1108  *name*, an absolute ``dns.name.Name`` or ``text``, the query name.
1109 
1110  *rdclass*, an ``int``, the query class.
1111 
1112  *tcp*, a ``bool``. If ``True``, use TCP to make the query.
1113 
1114  *resolver*, a ``dns.resolver.Resolver`` or ``None``, the resolver to use.
1115  If ``None``, the default resolver is used.
1116 
1117  Raises ``dns.resolver.NoRootSOA`` if there is no SOA RR at the DNS
1118  root. (This is only likely to happen if you're using non-default
1119  root servers in your network and they are misconfigured.)
1120 
1121  Returns a ``dns.name.Name``.
1122  """
1123 
1124  if isinstance(name, string_types):
1125  name = dns.name.from_text(name, dns.name.root)
1126  if resolver is None:
1127  resolver = get_default_resolver()
1128  if not name.is_absolute():
1129  raise NotAbsolute(name)
1130  while 1:
1131  try:
1132  answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp)
1133  if answer.rrset.name == name:
1134  return name
1135  # otherwise we were CNAMEd or DNAMEd and need to look higher
1137  pass
1138  try:
1139  name = name.parent()
1140  except dns.name.NoParent:
1141  raise NoRootSOA
1142 
1143 #
1144 # Support for overriding the system resolver for all python code in the
1145 # running process.
1146 #
1147 
1148 _protocols_for_socktype = {
1149  socket.SOCK_DGRAM: [socket.SOL_UDP],
1150  socket.SOCK_STREAM: [socket.SOL_TCP],
1151 }
1152 
1153 _resolver = None
1154 _original_getaddrinfo = socket.getaddrinfo
1155 _original_getnameinfo = socket.getnameinfo
1156 _original_getfqdn = socket.getfqdn
1157 _original_gethostbyname = socket.gethostbyname
1158 _original_gethostbyname_ex = socket.gethostbyname_ex
1159 _original_gethostbyaddr = socket.gethostbyaddr
1160 
1161 
1162 def _getaddrinfo(host=None, service=None, family=socket.AF_UNSPEC, socktype=0,
1163  proto=0, flags=0):
1164  if flags & (socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) != 0:
1165  raise NotImplementedError
1166  if host is None and service is None:
1167  raise socket.gaierror(socket.EAI_NONAME)
1168  v6addrs = []
1169  v4addrs = []
1170  canonical_name = None
1171  try:
1172  # Is host None or a V6 address literal?
1173  if host is None:
1174  canonical_name = 'localhost'
1175  if flags & socket.AI_PASSIVE != 0:
1176  v6addrs.append('::')
1177  v4addrs.append('0.0.0.0')
1178  else:
1179  v6addrs.append('::1')
1180  v4addrs.append('127.0.0.1')
1181  else:
1182  parts = host.split('%')
1183  if len(parts) == 2:
1184  ahost = parts[0]
1185  else:
1186  ahost = host
1187  addr = dns.ipv6.inet_aton(ahost)
1188  v6addrs.append(host)
1189  canonical_name = host
1190  except Exception:
1191  try:
1192  # Is it a V4 address literal?
1193  addr = dns.ipv4.inet_aton(host)
1194  v4addrs.append(host)
1195  canonical_name = host
1196  except Exception:
1197  if flags & socket.AI_NUMERICHOST == 0:
1198  try:
1199  if family == socket.AF_INET6 or family == socket.AF_UNSPEC:
1200  v6 = _resolver.query(host, dns.rdatatype.AAAA,
1201  raise_on_no_answer=False)
1202  # Note that setting host ensures we query the same name
1203  # for A as we did for AAAA.
1204  host = v6.qname
1205  canonical_name = v6.canonical_name.to_text(True)
1206  if v6.rrset is not None:
1207  for rdata in v6.rrset:
1208  v6addrs.append(rdata.address)
1209  if family == socket.AF_INET or family == socket.AF_UNSPEC:
1210  v4 = _resolver.query(host, dns.rdatatype.A,
1211  raise_on_no_answer=False)
1212  host = v4.qname
1213  canonical_name = v4.canonical_name.to_text(True)
1214  if v4.rrset is not None:
1215  for rdata in v4.rrset:
1216  v4addrs.append(rdata.address)
1217  except dns.resolver.NXDOMAIN:
1218  raise socket.gaierror(socket.EAI_NONAME)
1219  except Exception:
1220  raise socket.gaierror(socket.EAI_SYSTEM)
1221  port = None
1222  try:
1223  # Is it a port literal?
1224  if service is None:
1225  port = 0
1226  else:
1227  port = int(service)
1228  except Exception:
1229  if flags & socket.AI_NUMERICSERV == 0:
1230  try:
1231  port = socket.getservbyname(service)
1232  except Exception:
1233  pass
1234  if port is None:
1235  raise socket.gaierror(socket.EAI_NONAME)
1236  tuples = []
1237  if socktype == 0:
1238  socktypes = [socket.SOCK_DGRAM, socket.SOCK_STREAM]
1239  else:
1240  socktypes = [socktype]
1241  if flags & socket.AI_CANONNAME != 0:
1242  cname = canonical_name
1243  else:
1244  cname = ''
1245  if family == socket.AF_INET6 or family == socket.AF_UNSPEC:
1246  for addr in v6addrs:
1247  for socktype in socktypes:
1248  for proto in _protocols_for_socktype[socktype]:
1249  tuples.append((socket.AF_INET6, socktype, proto,
1250  cname, (addr, port, 0, 0)))
1251  if family == socket.AF_INET or family == socket.AF_UNSPEC:
1252  for addr in v4addrs:
1253  for socktype in socktypes:
1254  for proto in _protocols_for_socktype[socktype]:
1255  tuples.append((socket.AF_INET, socktype, proto,
1256  cname, (addr, port)))
1257  if len(tuples) == 0:
1258  raise socket.gaierror(socket.EAI_NONAME)
1259  return tuples
1260 
1261 
1262 def _getnameinfo(sockaddr, flags=0):
1263  host = sockaddr[0]
1264  port = sockaddr[1]
1265  if len(sockaddr) == 4:
1266  scope = sockaddr[3]
1267  family = socket.AF_INET6
1268  else:
1269  scope = None
1270  family = socket.AF_INET
1271  tuples = _getaddrinfo(host, port, family, socket.SOCK_STREAM,
1272  socket.SOL_TCP, 0)
1273  if len(tuples) > 1:
1274  raise socket.error('sockaddr resolved to multiple addresses')
1275  addr = tuples[0][4][0]
1276  if flags & socket.NI_DGRAM:
1277  pname = 'udp'
1278  else:
1279  pname = 'tcp'
1280  qname = dns.reversename.from_address(addr)
1281  if flags & socket.NI_NUMERICHOST == 0:
1282  try:
1283  answer = _resolver.query(qname, 'PTR')
1284  hostname = answer.rrset[0].target.to_text(True)
1286  if flags & socket.NI_NAMEREQD:
1287  raise socket.gaierror(socket.EAI_NONAME)
1288  hostname = addr
1289  if scope is not None:
1290  hostname += '%' + str(scope)
1291  else:
1292  hostname = addr
1293  if scope is not None:
1294  hostname += '%' + str(scope)
1295  if flags & socket.NI_NUMERICSERV:
1296  service = str(port)
1297  else:
1298  service = socket.getservbyport(port, pname)
1299  return (hostname, service)
1300 
1301 
1302 def _getfqdn(name=None):
1303  if name is None:
1304  name = socket.gethostname()
1305  try:
1306  return _getnameinfo(_getaddrinfo(name, 80)[0][4])[0]
1307  except Exception:
1308  return name
1309 
1310 
1311 def _gethostbyname(name):
1312  return _gethostbyname_ex(name)[2][0]
1313 
1314 
1316  aliases = []
1317  addresses = []
1318  tuples = _getaddrinfo(name, 0, socket.AF_INET, socket.SOCK_STREAM,
1319  socket.SOL_TCP, socket.AI_CANONNAME)
1320  canonical = tuples[0][3]
1321  for item in tuples:
1322  addresses.append(item[4][0])
1323  # XXX we just ignore aliases
1324  return (canonical, aliases, addresses)
1325 
1326 
1328  try:
1329  dns.ipv6.inet_aton(ip)
1330  sockaddr = (ip, 80, 0, 0)
1331  family = socket.AF_INET6
1332  except Exception:
1333  sockaddr = (ip, 80)
1334  family = socket.AF_INET
1335  (name, port) = _getnameinfo(sockaddr, socket.NI_NAMEREQD)
1336  aliases = []
1337  addresses = []
1338  tuples = _getaddrinfo(name, 0, family, socket.SOCK_STREAM, socket.SOL_TCP,
1339  socket.AI_CANONNAME)
1340  canonical = tuples[0][3]
1341  for item in tuples:
1342  addresses.append(item[4][0])
1343  # XXX we just ignore aliases
1344  return (canonical, aliases, addresses)
1345 
1346 
1347 def override_system_resolver(resolver=None):
1348  """Override the system resolver routines in the socket module with
1349  versions which use dnspython's resolver.
1350 
1351  This can be useful in testing situations where you want to control
1352  the resolution behavior of python code without having to change
1353  the system's resolver settings (e.g. /etc/resolv.conf).
1354 
1355  The resolver to use may be specified; if it's not, the default
1356  resolver will be used.
1357 
1358  resolver, a ``dns.resolver.Resolver`` or ``None``, the resolver to use.
1359  """
1360 
1361  if resolver is None:
1362  resolver = get_default_resolver()
1363  global _resolver
1364  _resolver = resolver
1365  socket.getaddrinfo = _getaddrinfo
1366  socket.getnameinfo = _getnameinfo
1367  socket.getfqdn = _getfqdn
1368  socket.gethostbyname = _gethostbyname
1369  socket.gethostbyname_ex = _gethostbyname_ex
1370  socket.gethostbyaddr = _gethostbyaddr
1371 
1372 
1374  """Undo the effects of prior override_system_resolver()."""
1375 
1376  global _resolver
1377  _resolver = None
1378  socket.getaddrinfo = _original_getaddrinfo
1379  socket.getnameinfo = _original_getnameinfo
1380  socket.getfqdn = _original_getfqdn
1381  socket.gethostbyname = _original_gethostbyname
1382  socket.gethostbyname_ex = _original_gethostbyname_ex
1383  socket.gethostbyaddr = _original_gethostbyaddr
dns.resolver.LRUCacheNode.link_before
def link_before(self, node)
Definition: resolver.py:384
dns.resolver.Resolver.query
def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, tcp=False, source=None, raise_on_no_answer=True, source_port=0, lifetime=None)
Definition: resolver.py:802
dns.message
Definition: message.py:1
dns.resolver.Resolver.read_registry
def read_registry(self)
Definition: resolver.py:684
dns.resolver.NXDOMAIN.canonical_name
canonical_name
Definition: resolver.py:93
dns.ipv4
Definition: ipv4.py:1
dns.reversename.from_address
def from_address(text)
Definition: reversename.py:32
dns.name.Name
Definition: name.py:318
dns.exception.FormError
Definition: exception.py:109
dns.resolver.Answer.rdclass
rdclass
Definition: resolver.py:205
dns.resolver.Resolver._config_win32_search
def _config_win32_search(self, search)
Definition: resolver.py:641
dns.resolver.LRUCacheNode.__init__
def __init__(self, key, value)
Definition: resolver.py:378
dns.tsig
Definition: tsig.py:1
dns.ipv6.inet_aton
def inet_aton(text)
Definition: ipv6.py:100
dns.name.from_text
def from_text(text, origin=root, idna_codec=None)
Definition: name.py:873
dns.resolver.Resolver.rotate
rotate
Definition: resolver.py:538
dns.reversename
Definition: reversename.py:1
dns.resolver.Answer.__init__
def __init__(self, qname, rdtype, rdclass, response, raise_on_no_answer=True)
Definition: resolver.py:202
dns.resolver.Answer.response
response
Definition: resolver.py:206
dns.resolver._gethostbyname
def _gethostbyname(name)
Definition: resolver.py:1311
dns.resolver.Resolver.retry_servfail
retry_servfail
Definition: resolver.py:537
dns.resolver.Timeout
Timeout
Definition: resolver.py:138
dns.resolver.Resolver
Definition: resolver.py:507
dns.resolver.Answer
Definition: resolver.py:186
dns.exception.Timeout
Definition: exception.py:125
dns.resolver.NXDOMAIN.__add__
def __add__(self, e_nx)
Definition: resolver.py:96
dns.resolver.query
def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, tcp=False, source=None, raise_on_no_answer=True, source_port=0, lifetime=None)
Definition: resolver.py:1088
dns.resolver.Resolver.__init__
def __init__(self, filename='/etc/resolv.conf', configure=True)
Definition: resolver.py:510
dns.resolver.NoNameservers._fmt_kwargs
def _fmt_kwargs(self, **kwargs)
Definition: resolver.py:165
dns.rdataclass
Definition: rdataclass.py:1
dns.resolver.Resolver.keyname
keyname
Definition: resolver.py:530
dns.resolver.LRUCache.data
data
Definition: resolver.py:416
dns.resolver.Resolver.nameservers
nameservers
Definition: resolver.py:523
dns.resolver.Answer.rrset
rrset
Definition: resolver.py:237
dns.resolver.Cache.next_cleaning
next_cleaning
Definition: resolver.py:299
dns.resolver.Resolver._config_win32_domain
def _config_win32_domain(self, domain)
Definition: resolver.py:637
dns.rcode
Definition: rcode.py:1
dns.exception.DNSException
Definition: exception.py:24
dns.resolver.Resolver.use_tsig
def use_tsig(self, keyring, keyname=None, algorithm=dns.tsig.default_algorithm)
Definition: resolver.py:1009
dns.resolver.NXDOMAIN.response
def response(self, qname)
Definition: resolver.py:123
dns.resolver.NoAnswer._fmt_kwargs
def _fmt_kwargs(self, **kwargs)
Definition: resolver.py:147
dns.exception.DNSException.kwargs
kwargs
Definition: exception.py:54
dns.resolver.Resolver.use_edns
def use_edns(self, edns, ednsflags, payload)
Definition: resolver.py:1036
dns.resolver.Cache
Definition: resolver.py:289
dns.resolver.LRUCache.put
def put(self, key, value)
Definition: resolver.py:453
dns.resolver._gethostbyaddr
def _gethostbyaddr(ip)
Definition: resolver.py:1327
dns.resolver.LRUCacheNode
Definition: resolver.py:375
dns.resolver._getfqdn
def _getfqdn(name=None)
Definition: resolver.py:1302
dns.resolver.Resolver.reset
def reset(self)
Definition: resolver.py:547
dns.rdataclass.is_metaclass
def is_metaclass(rdclass)
Definition: rdataclass.py:112
dns.resolver.YXDOMAIN
Definition: resolver.py:131
dns.resolver.LRUCache.flush
def flush(self, key=None)
Definition: resolver.py:478
dns.resolver.Cache.__init__
def __init__(self, cleaning_interval=300.0)
Definition: resolver.py:292
dns.resolver.Answer.qname
qname
Definition: resolver.py:203
dns.resolver.Resolver._win32_is_nic_enabled
def _win32_is_nic_enabled(self, lm, guid, interface_key)
Definition: resolver.py:730
dns.resolver.LRUCacheNode.prev
prev
Definition: resolver.py:381
dns.rcode.to_text
def to_text(value)
Definition: rcode.py:129
dns.query.tcp
def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False)
Definition: query.py:442
dns.resolver.Cache.data
data
Definition: resolver.py:297
dns.flags
Definition: flags.py:1
dns.resolver.LRUCache.sentinel
sentinel
Definition: resolver.py:418
dns.resolver.LRUCacheNode.unlink
def unlink(self)
Definition: resolver.py:396
dns.resolver.LRUCache.get
def get(self, key)
Definition: resolver.py:426
dns.rdatatype.is_metatype
def is_metatype(rdtype)
Definition: rdatatype.py:238
dns.resolver.Answer.canonical_name
canonical_name
Definition: resolver.py:236
dns.resolver.Cache.lock
lock
Definition: resolver.py:300
dns.resolver.NotAbsolute
Definition: resolver.py:174
dns.resolver.Answer.rdtype
rdtype
Definition: resolver.py:204
dns.hash.get
def get(algorithm)
Definition: hash.py:36
dns.ipv4.inet_aton
def inet_aton(text)
Definition: ipv4.py:40
dns.resolver.Cache.get
def get(self, key)
Definition: resolver.py:316
dns.resolver.NXDOMAIN.responses
def responses(self)
Definition: resolver.py:115
dns.ipv6
Definition: ipv6.py:1
dns.resolver.Cache.cleaning_interval
cleaning_interval
Definition: resolver.py:298
dns.resolver.NXDOMAIN._check_kwargs
def _check_kwargs(self, qnames, responses=None)
Definition: resolver.py:55
dns.resolver.restore_system_resolver
def restore_system_resolver()
Definition: resolver.py:1373
dns.resolver.Resolver.ednsflags
ednsflags
Definition: resolver.py:533
dns.name
Definition: name.py:1
dns.resolver.get_default_resolver
def get_default_resolver()
Definition: resolver.py:1070
dns.resolver.Answer.__delitem__
def __delitem__(self, i)
Definition: resolver.py:283
dns.resolver.Answer.__getattr__
def __getattr__(self, attr)
Definition: resolver.py:258
dns.resolver.LRUCacheNode.key
key
Definition: resolver.py:379
dns.resolver.Resolver.read_resolv_conf
def read_resolv_conf(self, f)
Definition: resolver.py:571
dns.resolver.NoNameservers
Definition: resolver.py:152
dns.resolver.Resolver.set_flags
def set_flags(self, flags)
Definition: resolver.py:1057
dns.resolver.Resolver.port
port
Definition: resolver.py:525
dns.resolver.NXDOMAIN
Definition: resolver.py:50
dns.resolver.Resolver.lifetime
lifetime
Definition: resolver.py:528
dns.resolver.LRUCache.__init__
def __init__(self, max_size=100000)
Definition: resolver.py:411
dns.resolver.Resolver._compute_timeout
def _compute_timeout(self, start, lifetime=None)
Definition: resolver.py:785
dns.name.NoParent
Definition: name.py:91
dns.resolver._getnameinfo
def _getnameinfo(sockaddr, flags=0)
Definition: resolver.py:1262
dns.resolver.Cache.flush
def flush(self, key=None)
Definition: resolver.py:353
dns.resolver.Resolver.flags
flags
Definition: resolver.py:536
dns.resolver._gethostbyname_ex
def _gethostbyname_ex(name)
Definition: resolver.py:1315
dns.resolver.Cache.put
def put(self, key, value)
Definition: resolver.py:337
dns.rdatatype
Definition: rdatatype.py:1
dns.resolver.Cache._maybe_clean
def _maybe_clean(self)
Definition: resolver.py:302
dns.resolver.Resolver.search
search
Definition: resolver.py:526
dns.resolver.LRUCacheNode.value
value
Definition: resolver.py:380
dns.resolver.Resolver.nameserver_ports
nameserver_ports
Definition: resolver.py:524
dns.resolver.Resolver.timeout
timeout
Definition: resolver.py:527
dns.resolver.Resolver.payload
payload
Definition: resolver.py:534
dns.query.udp
def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0, ignore_unexpected=False, one_rr_per_rrset=False, ignore_trailing=False)
Definition: query.py:274
dns.resolver.Answer.__getitem__
def __getitem__(self, i)
Definition: resolver.py:278
dns.resolver.LRUCache.lock
lock
Definition: resolver.py:419
dns.resolver.Resolver.cache
cache
Definition: resolver.py:535
dns.rdatatype.from_text
def from_text(text)
Definition: rdatatype.py:193
dns.resolver.LRUCache.set_max_size
def set_max_size(self, max_size)
Definition: resolver.py:421
dns.resolver.Resolver._determine_split_char
def _determine_split_char(self, entry)
Definition: resolver.py:613
dns.resolver.Resolver.domain
domain
Definition: resolver.py:522
dns.resolver.Resolver._config_win32_fromkey
def _config_win32_fromkey(self, key, always_try_domain)
Definition: resolver.py:650
dns.resolver.LRUCacheNode.link_after
def link_after(self, node)
Definition: resolver.py:390
dns.resolver.Resolver.keyalgorithm
keyalgorithm
Definition: resolver.py:531
dns.resolver.Answer.__len__
def __len__(self)
Definition: resolver.py:272
dns.query.UnexpectedSource
Definition: query.py:47
dns.resolver.LRUCache.max_size
max_size
Definition: resolver.py:424
dns.resolver.reset_default_resolver
def reset_default_resolver()
Definition: resolver.py:1077
dns.resolver.Answer.expiration
expiration
Definition: resolver.py:255
dns.resolver.Answer.__iter__
def __iter__(self)
Definition: resolver.py:275
dns.query
Definition: query.py:1
dns._compat.xrange
xrange
Definition: _compat.py:11
dns.resolver.Resolver.keyring
keyring
Definition: resolver.py:529
dns.resolver.override_system_resolver
def override_system_resolver(resolver=None)
Definition: resolver.py:1347
dns.resolver.NXDOMAIN.qnames
def qnames(self)
Definition: resolver.py:108
dns.resolver.Resolver.edns
edns
Definition: resolver.py:532
dns.resolver.zone_for_name
def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None)
Definition: resolver.py:1105
dns.resolver.LRUCache
Definition: resolver.py:401
dns.resolver.NoMetaqueries
Definition: resolver.py:182
dns.message.make_query
def make_query(qname, rdtype, rdclass=dns.rdataclass.IN, use_edns=None, want_dnssec=False, ednsflags=None, payload=None, request_payload=None, options=None)
Definition: message.py:1061
dns.exception
Definition: exception.py:1
dns.resolver.NXDOMAIN.__str__
def __str__(self)
Definition: resolver.py:67
dns.resolver.LRUCacheNode.next
next
Definition: resolver.py:382
dns.resolver.NoAnswer
Definition: resolver.py:141
dns.rdataclass.from_text
def from_text(text)
Definition: rdataclass.py:67
dns.resolver._getaddrinfo
def _getaddrinfo(host=None, service=None, family=socket.AF_UNSPEC, socktype=0, proto=0, flags=0)
Definition: resolver.py:1162
dns.resolver.Resolver._config_win32_nameservers
def _config_win32_nameservers(self, nameservers)
Definition: resolver.py:628