--- dns/resolver.py.orig Wed Oct 11 12:33:30 2006 +++ dns/resolver.py Mon Oct 16 18:27:12 2006 @@ -467,14 +467,17 @@ raise Timeout return min(self.lifetime - duration, self.timeout) - def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, - tcp=False): + def query(self, qname=".", rdtype=dns.rdatatype.A, + rdclass=dns.rdataclass.IN, tcp=False, msg=None): """Query nameservers to find the answer to the question. The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects of the appropriate type, or strings that can be converted into objects of the appropriate type. E.g. For I{rdtype} the integer 2 and the the string 'NS' both mean to query for records with DNS rdata type NS. + If an instance of dns.message.Message is suppiled as I{msg} it is + used as the complete query. The search list is not applied in this + case. @param qname: the query name @type qname: dns.name.Name object or string @@ -484,30 +487,40 @@ @type rdclass: int or string @param tcp: use TCP to make the query (default is False). @type tcp: bool + @param msg: a pre-computed DNS message to use as the query + @type msg: dns.message.Message instance @rtype: dns.resolver.Answer instance @raises Timeout: no answers could be found in the specified lifetime @raises NXDOMAIN: the query name does not exist @raises NoAnswer: the response did not contain an answer @raises NoNameservers: no non-broken nameservers are available to answer the question.""" - - if isinstance(qname, (str, unicode)): - qname = dns.name.from_text(qname, None) - if isinstance(rdtype, str): - rdtype = dns.rdatatype.from_text(rdtype) - if isinstance(rdclass, str): - rdclass = dns.rdataclass.from_text(rdclass) + qnames_to_try = [] - if qname.is_absolute(): - qnames_to_try.append(qname) + if isinstance(msg, dns.message.Message): + qname = msg.question[0].name + rdtype = msg.question[0].rdtype + rdclass = msg.question[0].rdclass + qnames_to_try = [qname] else: - if len(qname) > 1: - qnames_to_try.append(qname.concatenate(dns.name.root)) - if self.search: - for suffix in self.search: - qnames_to_try.append(qname.concatenate(suffix)) + msg = None + if isinstance(qname, (str, unicode)): + qname = dns.name.from_text(qname, None) + if isinstance(rdtype, str): + rdtype = dns.rdatatype.from_text(rdtype) + if isinstance(rdclass, str): + rdclass = dns.rdataclass.from_text(rdclass) + if qname.is_absolute(): + qnames_to_try.append(qname) else: - qnames_to_try.append(qname.concatenate(self.domain)) + if len(qname) > 1: + qnames_to_try.append(qname.concatenate(dns.name.root)) + if self.search: + for suffix in self.search: + qnames_to_try.append(qname.concatenate(suffix)) + else: + qnames_to_try.append(qname.concatenate(self.domain)) + all_nxdomain = True start = time.time() for qname in qnames_to_try: @@ -515,7 +528,12 @@ answer = self.cache.get((qname, rdtype, rdclass)) if answer: return answer - request = dns.message.make_query(qname, rdtype, rdclass) + + if msg is None: + request = dns.message.make_query(qname, rdtype, rdclass) + else: + request = msg + if not self.keyname is None: request.use_tsig(self.keyring, self.keyname) request.use_edns(self.edns, self.ednsflags, self.payload)