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