diff options
author | Bob Halley <halley@dnspython.org> | 2013-12-11 06:29:29 -0800 |
---|---|---|
committer | Bob Halley <halley@dnspython.org> | 2013-12-11 06:29:29 -0800 |
commit | 04c88f405266ab515d9916f99740c78a5909fd22 (patch) | |
tree | 3e4b5dc49e4023253276a98876ec72762ed0154c | |
parent | a9c362b858bcc2ee2370bc3d0a41f9a649262138 (diff) | |
download | dnspython-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-- | ChangeLog | 6 | ||||
-rw-r--r-- | dns/query.py | 17 |
2 files changed, 18 insertions, 5 deletions
@@ -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: # |