try TCP if UDP response is truncated
authorBob Halley <halley@dnspython.org>
Sun, 8 Apr 2012 11:10:28 +0000 (12:10 +0100)
committerBob Halley <halley@dnspython.org>
Sun, 8 Apr 2012 11:10:28 +0000 (12:10 +0100)
ChangeLog
dns/resolver.py

index 5ab983875db9bd0316daa4fed58f4895f44261d1..9b5d4e7dd52f20a34e4de6f64f38945575438e29 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-04-08  Bob Halley  <halley@dnspython.org>
+
+       * dns/resolver.py (Resolver.query): Switch to TCP when a UDP
+         response is truncated.  Handle nameservers that serve on UDP
+         but not TCP.
 
 2012-04-07  Bob Halley  <halley@dnspython.org>
 
index 90f95e8ed0504f42bf86f66c55e488149ef4c8ff..2f56c7de67ac4ae8f1d88ffcccb661d3b05083be 100644 (file)
@@ -23,6 +23,7 @@ import sys
 import time
 
 import dns.exception
+import dns.flags
 import dns.ipv4
 import dns.ipv6
 import dns.message
@@ -778,6 +779,12 @@ class Resolver(object):
                             response = dns.query.udp(request, nameserver,
                                                      timeout, self.port,
                                                      source=source)
+                            if response.flags & dns.flags.TC:
+                                # Response truncated; retry with TCP.
+                                timeout = self._compute_timeout(start)
+                                response = dns.query.tcp(request, nameserver,
+                                                         timeout, self.port,
+                                                         source=source)
                     except (socket.error, dns.exception.Timeout):
                         #
                         # Communication failure or timeout.  Go to the
@@ -800,6 +807,16 @@ class Resolver(object):
                         nameservers.remove(nameserver)
                         response = None
                         continue
+                    except EOFError:
+                        #
+                        # We're using TCP and they hung up on us.
+                        # Probably they don't support TCP (though
+                        # they're supposed to!).  Take it out of the
+                        # mix and continue.
+                        #
+                        nameservers.remove(nameserver)
+                        response = None
+                        continue
                     rcode = response.rcode()
                     if rcode == dns.rcode.NOERROR or \
                            rcode == dns.rcode.NXDOMAIN: