origin [#1236].
Ideally, we'd actually store this somewhere as in theory it is
needed for pathological cross zone dependencies. We are
not doing this as in practice such dependencies break a lot of
DNS software, and are usually not viable "in the wild".
raise ValueError("rdtype is not IXFR or AXFR")
self.serial = serial
self.is_udp = is_udp
- (_, _, self.origin) = txn_manager.origin_information()
+ (_, _, origin) = txn_manager.origin_information()
+ if origin is None:
+ raise ValueError("transaction manager must supply an origin for XFRs")
+ self.origin = origin
self.soa_rdataset: dns.rdataset.Rdataset | None = None
self.done = False
self.expecting_SOA = False
# Note we are falling through into the code below
# so whatever rdataset this was gets written.
#
+ # Ignore glue that is not a subdomain of the origin. For pathological
+ # cases it would be good if we could keep it in some side location, but
+ # dnspython zones don't have a place or an API for that, so we just ignore
+ # it at this time.
+ if not name.is_subdomain(self.origin):
+ continue
# Add or remove the data
if self.delete_mode:
self.txn.delete_exact(name, rdataset)
)
import dns.exception
-import dns.grange
import dns.immutable
import dns.name
import dns.node
import dns.rrset
import dns.tokenizer
import dns.transaction
-import dns.ttl
import dns.zonefile
from dns.zonetypes import DigestHashAlgorithm, DigestScheme, _digest_hashers
@ 3600 IN SOA foo bar 1 2 3 4 7
"""
+axfr_with_nonsubdomain_glue = """id 1
+opcode QUERY
+rcode NOERROR
+flags AA
+;QUESTION
+example. IN AXFR
+;ANSWER
+@ 3600 IN SOA foo bar 1 2 3 4 5
+bar.foo 300 IN MX 0 blaz.foo
+ns1 3600 IN A 10.0.0.1
+ns2 3600 IN A 10.0.0.2
+sub 300 IN NS ns1.other.
+ns1.other. 300 IN A 1.2.3.4
+@ 3600 IN SOA foo bar 1 2 3 4 5
+"""
+
ixfr = """id 1
opcode QUERY
rcode NOERROR
@ 3600 IN NS ns1
@ 3600 IN NS ns2
"""
+
ixfr_axfr2 = """id 1
opcode QUERY
rcode NOERROR
xfr.process_message(m)
+def test_axfr_with_non_subdomain_glue():
+ z = dns.versioned.Zone("example.")
+ m = dns.message.from_text(
+ axfr_with_nonsubdomain_glue, origin=z.origin, one_rr_per_rrset=True
+ )
+ with dns.xfr.Inbound(z, dns.rdatatype.AXFR) as xfr:
+ xfr.process_message(m)
+
+
def test_basic_ixfr():
z = dns.zone.from_text(base, "example.", zone_factory=dns.versioned.Zone)
m = dns.message.from_text(ixfr, origin=z.origin, one_rr_per_rrset=True)