Commit ff5f00f64f for bind
commit ff5f00f64f80cb1bc9f44fe5d7e24f3cf550264e
Author: Colin Vidal <colin@isc.org>
Date: Thu Jul 9 11:18:04 2026 +0200
Add system test returning TC=1 synthrecord
Add a system test which returns TC=1 for a synthrecord answer. This
ensures the plugin behaves as expected, even if ANSWER data is freed
earlier by `ns_client_send()`/`dns_message_renderend()`.
diff --git a/bin/tests/system/synthrecord/ns1/named.conf.j2 b/bin/tests/system/synthrecord/ns1/named.conf.j2
index d300f927f1..798af6b747 100644
--- a/bin/tests/system/synthrecord/ns1/named.conf.j2
+++ b/bin/tests/system/synthrecord/ns1/named.conf.j2
@@ -1,9 +1,13 @@
{% set inview = inview | default(False) %}
{% set toolongprefix = toolongprefix | default(False) %}
+{% set nocookieudpsize = nocookieudpsize | default(False) %}
options {
{% include_indented "_common/options-dual.conf.j2" %}
recursion no;
+{% if nocookieudpsize %}
+ nocookie-udp-size 128;
+{% endif %}
};
{% include "_common/controls.conf.j2" %}
diff --git a/bin/tests/system/synthrecord/tests_synthrecord.py b/bin/tests/system/synthrecord/tests_synthrecord.py
index 9026de2495..3ed1734efe 100644
--- a/bin/tests/system/synthrecord/tests_synthrecord.py
+++ b/bin/tests/system/synthrecord/tests_synthrecord.py
@@ -23,7 +23,7 @@ from dns.reversename import ipv4_reverse_domain, ipv6_reverse_domain
from hypothesis import assume, example, given
from hypothesis.strategies import ip_addresses
-import dns.message
+import dns.edns
import dns.name
import dns.rcode
import dns.rrset
@@ -88,7 +88,7 @@ def test_synthrecord_checkconf():
],
)
def test_synthrecord_reverse_hasdata(qname, rname, ttl):
- msg = dns.message.make_query(qname, "PTR")
+ msg = isctest.query.create(qname, "PTR")
res = isctest.query.udp(msg, SERVER)
isctest.check.noerror(res)
if qname[-1] != ".":
@@ -111,7 +111,7 @@ def test_synthrecord_reverse_hasdata(qname, rname, ttl):
],
)
def test_synthrecord_forward(qname, qtype, rname, rtype, ttl):
- msg = dns.message.make_query(qname, qtype)
+ msg = isctest.query.create(qname, qtype)
res = isctest.query.udp(msg, SERVER)
isctest.check.noerror(res)
if qname[-1] != ".":
@@ -126,7 +126,7 @@ def test_synthrecord_forward(qname, qtype, rname, rtype, ttl):
[("dynamic-10-53-0-44.example.", "AAAA"), ("dynamic-cafe-cafe--cafe.example", "A")],
)
def test_synthrecord_forward_wrongtype(qname, qtype):
- msg = dns.message.make_query(qname, qtype)
+ msg = isctest.query.create(qname, qtype)
res = isctest.query.udp(msg, SERVER)
isctest.check.rcode(res, dns.rcode.NOERROR)
if qname[-1] != ".":
@@ -150,7 +150,7 @@ def test_synthrecord_forward_wrongtype(qname, qtype):
],
)
def test_synthrecord_forward_nodata(qname, qtype, rcode):
- msg = dns.message.make_query(qname, qtype)
+ msg = isctest.query.create(qname, qtype)
res = isctest.query.udp(msg, SERVER)
assert len(res.answer) == 0
assert res.rcode() == rcode
@@ -215,7 +215,7 @@ def test_synthrecord_forward_nodata(qname, qtype, rcode):
],
)
def test_synthrecord_reverse_hasnodata(qname, qtype, rcode):
- msg = dns.message.make_query(qname, qtype)
+ msg = isctest.query.create(qname, qtype)
res = isctest.query.udp(msg, SERVER)
assert len(res.answer) == 0
assert res.rcode() == rcode
@@ -229,7 +229,7 @@ def test_synthrecord_reverse_hasnodata(qname, qtype, rcode):
],
)
def test_synthrecord_reverse_delegate(qname, rcode):
- msg = dns.message.make_query(qname, "PTR")
+ msg = isctest.query.create(qname, "PTR")
res = isctest.query.udp(msg, SERVER)
assert len(res.answer) == 0
assert res.rcode() == rcode
@@ -256,7 +256,7 @@ def test_synthrecord_reverse_delegate(qname, rcode):
)
def test_synthrecord_defaults(qname, rname):
ttl = 300
- msg = dns.message.make_query(qname, "PTR")
+ msg = isctest.query.create(qname, "PTR")
res = isctest.query.udp(msg, SERVER)
isctest.check.noerror(res)
if qname[-1] != ".":
@@ -280,7 +280,7 @@ def test_synthrecord_defaults(qname, rname):
],
)
def test_synthrecord_reverse_anysoa(qname, qtype, rcode, answerscount):
- msg = dns.message.make_query(qname, qtype)
+ msg = isctest.query.create(qname, qtype)
res = isctest.query.udp(msg, SERVER)
assert len(res.answer) == answerscount
assert res.rcode() == rcode
@@ -311,7 +311,7 @@ def test_synthrecord_reverse_randomdomains(domain):
or domain.is_subdomain(example_domain)
)
)
- query = dns.message.make_query(domain, "PTR")
+ query = isctest.query.create(domain, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.REFUSED
@@ -319,7 +319,7 @@ def test_synthrecord_reverse_randomdomains(domain):
@given(ip=ip_addresses(network="10.53.0.0/24"))
def test_sythreverse_noerror_hasdata_v4(ip):
assume(ip not in [IPv4Address("10.53.0.28"), IPv4Address("10.53.0.4")])
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.NOERROR
assert res.answer == [
@@ -335,7 +335,7 @@ def test_sythreverse_noerror_hasdata_v4(ip):
@given(ip=ip_addresses(network="10.53.2.0/24"))
def test_sythreverse_refused_v4(ip):
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.REFUSED
@@ -350,7 +350,7 @@ def test_sythreverse_refused_v6(ip):
assume(not dns.name.from_text(ip.reverse_pointer).is_subdomain(arpa_cafecafe))
assume(not dns.name.from_text(ip.reverse_pointer).is_subdomain(arpa_zeros16))
assume(not dns.name.from_text(ip.reverse_pointer).is_subdomain(arpa_ffff16))
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.REFUSED
@@ -365,7 +365,7 @@ def test_sythreverse_refused_v6(ip):
)
def test_synthreverse_idn_compat(addr, expected):
ip = IPv6Address(addr)
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.NOERROR
assert res.answer == [
@@ -380,7 +380,7 @@ def test_synthreverse_idn_compat(addr, expected):
@example(ip=IPv6Address("::"))
@given(ip=ip_addresses(network="cafe:cafe::/32"))
def test_sythreverse_noerror_hasdata_v6(ip):
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.NOERROR
assert res.answer == [
@@ -399,7 +399,7 @@ def test_sythreverse_unallowed_subnet_v4(ip):
# allow-nets is 10.53.1.0/29, so only addresses below 10.53.1.9 are allowed
# to have a synthetic record (_allow_subnet_v4 below checks the opposite)
assume(ip > IPv4Address("10.53.1.8"))
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert len(res.answer) == 0
assert res.rcode() == dns.rcode.NXDOMAIN
@@ -407,7 +407,7 @@ def test_sythreverse_unallowed_subnet_v4(ip):
@given(ip=ip_addresses(network="10.53.1.0/29"))
def test_sythreverse_allowed_subnet_v4(ip):
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.NOERROR
assert res.answer == [
@@ -427,7 +427,7 @@ def test_sythreverse_allowed_subnet_v4(ip):
)
)
def test_sythreverse_arpa_v4_nxdomain_toomanylabel(domain):
- query = dns.message.make_query(domain, "PTR")
+ query = isctest.query.create(domain, "PTR")
res = isctest.query.udp(query, SERVER)
assert len(res.answer) == 0
assert res.rcode() == dns.rcode.NXDOMAIN
@@ -442,7 +442,7 @@ def test_sythreverse_arpa_v4_nxdomain_toomanylabel(domain):
)
)
def test_sythforward_arpa_v4_nxdomain_toomanylabel(domain):
- query = dns.message.make_query(domain, "A")
+ query = isctest.query.create(domain, "A")
res = isctest.query.udp(query, SERVER)
assert len(res.answer) == 0
assert res.rcode() == dns.rcode.NXDOMAIN
@@ -457,7 +457,7 @@ def test_sythforward_arpa_v4_nxdomain_toomanylabel(domain):
)
)
def test_sythforward_arpa_v6_nxdomain_toomanylabel(domain):
- query = dns.message.make_query(domain, "AAAA")
+ query = isctest.query.create(domain, "AAAA")
res = isctest.query.udp(query, SERVER)
assert len(res.answer) == 0
assert res.rcode() == dns.rcode.NXDOMAIN
@@ -472,7 +472,7 @@ def test_sythforward_arpa_v6_nxdomain_toomanylabel(domain):
)
)
def test_sythforward_arpa_v6_nxdomain_unallowednet(domain):
- query = dns.message.make_query(domain, "AAAA")
+ query = isctest.query.create(domain, "AAAA")
res = isctest.query.udp(query, SERVER)
assert len(res.answer) == 0
assert res.rcode() == dns.rcode.NXDOMAIN
@@ -484,7 +484,7 @@ def test_sythforward_arpa_v6_nxdomain_unallowednet(domain):
)
)
def test_sythreverse_arpa_v6_nxdomain_toofewlabels(domain):
- query = dns.message.make_query(domain, "PTR")
+ query = isctest.query.create(domain, "PTR")
res = isctest.query.udp(query, SERVER)
assert len(res.answer) == 0
assert res.rcode() == dns.rcode.NXDOMAIN
@@ -496,7 +496,7 @@ def test_sythreverse_arpa_v6_nxdomain_toofewlabels(domain):
)
)
def test_sythreverse_arpa_v6_nxdomain_toomanylabels(domain):
- query = dns.message.make_query(domain, "PTR")
+ query = isctest.query.create(domain, "PTR")
res = isctest.query.udp(query, SERVER)
assert len(res.answer) == 0
assert res.rcode() == dns.rcode.NXDOMAIN
@@ -517,9 +517,33 @@ def test_synthrecord_toolongprefix(ns1, templates):
watcher.wait_for_line("running")
ip = IPv4Address("10.53.0.8")
with ns1.watch_log_from_here() as watcher:
- query = dns.message.make_query(ip.reverse_pointer, "PTR")
+ query = isctest.query.create(ip.reverse_pointer, "PTR")
res = isctest.query.udp(query, SERVER)
assert res.rcode() == dns.rcode.NXDOMAIN
watcher.wait_for_line(
"synthrecord cannot create reverse answer name: ran out of space"
)
+
+
+# No regression test for #6185
+def test_synthrecord_tooshortbuffer(ns1, templates):
+ qname = "f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.ip6.arpa"
+ templates.render("ns1/named.conf", {"nocookieudpsize": True})
+ with ns1.watch_log_from_here() as watcher:
+ ns1.rndc("reconfig")
+ watcher.wait_for_line("running")
+ msg = isctest.query.create(qname, "PTR")
+
+ # First, test with a valid cookie. The buffer is truncated and answer is missing.
+ res = isctest.query.udp(msg, ns1.ip)
+ isctest.check.noerror(res)
+ isctest.check.empty_answer(res)
+ isctest.check.tcflag(res)
+
+ # Send again the request, this time with an EDNS flag.
+ msg = isctest.query.create(qname, "PTR")
+ msg.ednsflags = dns.edns.COOKIE
+ res = isctest.query.udp(msg, ns1.ip)
+ isctest.check.noerror(res)
+ isctest.check.empty_answer(res)
+ isctest.check.tcflag(res)
diff --git a/pyproject.toml b/pyproject.toml
index b398ed0a91..501c2a704f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -92,6 +92,7 @@ ignore_names = [
# - bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py
"private",
"legacy",
+ "ednsflags",
]
[tool.ruff]