summaryrefslogtreecommitdiff
path: root/dns/query.py
diff options
context:
space:
mode:
Diffstat (limited to 'dns/query.py')
-rw-r--r--dns/query.py17
1 files changed, 12 insertions, 5 deletions
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:
#