diff options
| author | Bob Halley <halley@dnspython.org> | 2013-12-11 06:31:08 -0800 |
|---|---|---|
| committer | Bob Halley <halley@dnspython.org> | 2013-12-11 06:31:08 -0800 |
| commit | 84ec693830d440a98d25b263b4d9d1409a3f2ad6 (patch) | |
| tree | 9b5d839703b52defd50f67dbc601c85dc24800e6 | |
| parent | 8bddf55ddc61ca813f8e1faa241ec7ee786012be (diff) | |
| download | dnspython-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-- | 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 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: # |
