summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2013-12-11 06:31:08 -0800
committerBob Halley <halley@dnspython.org>2013-12-11 06:31:08 -0800
commit84ec693830d440a98d25b263b4d9d1409a3f2ad6 (patch)
tree9b5d839703b52defd50f67dbc601c85dc24800e6
parent8bddf55ddc61ca813f8e1faa241ec7ee786012be (diff)
downloaddnspython-84ec693830d440a98d25b263b4d9d1409a3f2ad6.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 a66722c..56aeb41 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 2dc3f80..2a252c7 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:
#