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