diff options
| author | Bob Halley <halley@dnspython.org> | 2005-09-02 05:33:05 +0000 |
|---|---|---|
| committer | Bob Halley <halley@dnspython.org> | 2005-09-02 05:33:05 +0000 |
| commit | 6a40a92e7ded43ed1ada4ec0fa0a1572f5664446 (patch) | |
| tree | 5cd7e63b5ad81377d989abb3b03b7a55159ffd26 | |
| parent | 618ada31725e826ef47cc41b817bb9012191f39e (diff) | |
| download | dnspython-6a40a92e7ded43ed1ada4ec0fa0a1572f5664446.tar.gz | |
take servers out of the mix based on rcode; add exponential backoff
Original author: Bob Halley <halley@dnspython.org>
Date: 2005-06-04 20:55:45
| -rw-r--r-- | dns/resolver.py | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/dns/resolver.py b/dns/resolver.py index 6d4fa91..38e45d3 100644 --- a/dns/resolver.py +++ b/dns/resolver.py @@ -424,6 +424,16 @@ class Resolver(object): finally: lm.Close() + def _compute_timeout(self, start): + now = time.time() + if now < start: + # Time going backwards is bad. Just give up. + raise Timeout + duration = now - start + if duration >= self.lifetime: + raise Timeout + return min(self.lifetime - duration, self.timeout) + def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, tcp=False): """Query nameservers to find the answer to the question. @@ -481,18 +491,12 @@ class Resolver(object): # make a copy of the servers list so we can alter it later. # nameservers = self.nameservers[:] + backoff = 0.10 while response is None: if len(nameservers) == 0: raise NoNameservers for nameserver in nameservers: - now = time.time() - if now < start: - # Time going backwards is bad. Just give up. - raise Timeout - duration = now - start - if duration >= self.lifetime: - raise Timeout - timeout = min(self.lifetime - duration, self.timeout) + timeout = self._compute_timeout(start) try: if tcp: response = dns.query.tcp(request, nameserver, @@ -526,7 +530,26 @@ class Resolver(object): if rcode == dns.rcode.NOERROR or \ rcode == dns.rcode.NXDOMAIN: break + # + # We got a response, but we're not happy with the + # rcode in it. Remove the server from the mix if + # the rcode isn't SERVFAIL. + # + if rcode != dns.rcode.SERVFAIL: + nameservers.remove(nameserver) response = None + # + # All nameservers failed! + # + if len(nameservers) > 0: + # + # But we still have servers to try. Sleep a bit + # so we don't pound them! + # + timeout = self._compute_timeout(start) + sleep_time = min(timeout, backoff) + backoff *= 2 + time.sleep(sleep_time) if response.rcode() == dns.rcode.NXDOMAIN: continue all_nxdomain = False |
