summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2013-12-11 06:29:29 -0800
committerBob Halley <halley@dnspython.org>2013-12-11 06:29:29 -0800
commit04c88f405266ab515d9916f99740c78a5909fd22 (patch)
tree3e4b5dc49e4023253276a98876ec72762ed0154c
parenta9c362b858bcc2ee2370bc3d0a41f9a649262138 (diff)
downloaddnspython-04c88f405266ab515d9916f99740c78a5909fd22.tar.gz
Fix problems with the IXFR state machine which caused long diffs to
fail. Thanks to James Raftery for the fix and the repeated prodding to get it applied :)
-rw-r--r--ChangeLog6
-rw-r--r--dns/query.py17
2 files changed, 18 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 5537eb9..2e48d9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-12-11 Bob Halley <halley@dnspython.org>
+
+ * dns/query.py: Fix problems with the IXFR state machine which caused
+ long diffs to fail. Thanks to James Raftery for the fix and the
+ repeated prodding to get it applied :)
+
2013-09-02 Bob Halley <halley@dnspython.org>
* (Version 1.11.1 released)
diff --git a/dns/query.py b/dns/query.py
index 7a1b1f4..29965ca 100644
--- a/dns/query.py
+++ b/dns/query.py
@@ -411,6 +411,8 @@ def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
tcpmsg = struct.pack("!H", l) + wire
_net_write(s, tcpmsg, expiration)
done = False
+ delete_mode = True
+ expecting_SOA = False
soa_rrset = None
soa_count = 0
if relativize:
@@ -439,18 +441,16 @@ def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
tsig_ctx = r.tsig_ctx
first = False
answer_index = 0
- delete_mode = False
- expecting_SOA = False
if soa_rrset is None:
if not r.answer or r.answer[0].name != oname:
- raise dns.exception.FormError
+ raise dns.exception.FormError("No answer or RRset not for qname")
rrset = r.answer[0]
if rrset.rdtype != dns.rdatatype.SOA:
raise dns.exception.FormError("first RRset is not an SOA")
answer_index = 1
soa_rrset = rrset.copy()
if rdtype == dns.rdatatype.IXFR:
- if soa_rrset[0].serial == serial:
+ if soa_rrset[0].serial <= serial:
#
# We're already up-to-date.
#
@@ -471,7 +471,14 @@ def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
expecting_SOA = False
elif rdtype == dns.rdatatype.IXFR:
delete_mode = not delete_mode
- if rrset == soa_rrset and not delete_mode:
+ #
+ # If this SOA RRset is equal to the first we saw then we're
+ # finished. If this is an IXFR we also check that we're seeing
+ # the record in the expected part of the response.
+ #
+ if rrset == soa_rrset and \
+ (rdtype == dns.rdatatype.AXFR or \
+ (rdtype == dns.rdatatype.IXFR and delete_mode)):
done = True
elif expecting_SOA:
#