Merge branch '1847-recursor-has-issues-recursing-ip6-arpa' into 'main'

Resolve "9.16.* recursor has issues recursing"

Closes #1847

See merge request isc-projects/bind9!4027
This commit is contained in:
Diego dos Santos Fronza 2020-09-01 18:49:23 +00:00
commit 61e8e13c91
7 changed files with 73 additions and 13 deletions

View file

@ -1,3 +1,7 @@
5495. [bug] With query minimization enabled, named failed to
resolve ip6.arpa. names that had more labels after the
IPv6 part. [GL #1847]
5494. [bug] Silence the EPROTO syslog message on older systems.
[GL #1928]

View file

@ -48,6 +48,7 @@ def logquery(type, qname):
#
# For 1.0.0.2.ip6.arpa it serves
# 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa. IN PTR nee.com.
# 8.2.6.0.1.0.0.2.ip6.arpa IN NS ns3.good
# 1.0.0.2.ip6.arpa. IN NS ns2.good
# ip6.arpa. IN NS ns2.good
############################################################################
@ -76,33 +77,37 @@ def create_response(msg):
if lqname.endswith("1.0.0.2.ip6.arpa."):
# Direct query - give direct answer
if lqname == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa." and rrtype == PTR:
if lqname.endswith("8.2.6.0.1.0.0.2.ip6.arpa."):
# Delegate to ns3
r.authority.append(dns.rrset.from_text("8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns3.good."))
r.additional.append(dns.rrset.from_text("ns3.good.", 60, IN, A, "10.53.0.3"))
elif lqname == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa." and rrtype == PTR:
# Direct query - give direct answer
r.answer.append(dns.rrset.from_text("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.", 1, IN, PTR, "nee.com."))
r.flags |= dns.flags.AA
elif lqname == "1.0.0.2.ip6.arpa." and rrtype == NS:
# NS query at the apex
r.answer.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 1, IN, NS, "ns2.good."))
r.answer.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, NS, "ns2.good."))
r.flags |= dns.flags.AA
elif "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.".endswith(lqname):
# NODATA answer
r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
else:
# NXDOMAIN
r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
r.set_rcode(NXDOMAIN)
return r
elif lqname.endswith("ip6.arpa."):
if lqname == "ip6.arpa." and rrtype == NS:
# NS query at the apex
r.answer.append(dns.rrset.from_text("ip6.arpa.", 1, IN, NS, "ns2.good."))
r.answer.append(dns.rrset.from_text("ip6.arpa.", 30, IN, NS, "ns2.good."))
r.flags |= dns.flags.AA
elif "1.0.0.2.ip6.arpa.".endswith(lqname):
# NODATA answer
r.authority.append(dns.rrset.from_text("ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
r.authority.append(dns.rrset.from_text("ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
else:
# NXDOMAIN
r.authority.append(dns.rrset.from_text("ip6.arpa.", 1, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
r.authority.append(dns.rrset.from_text("ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
r.set_rcode(NXDOMAIN)
return r
elif lqname.endswith("bad."):
@ -134,19 +139,25 @@ def create_response(msg):
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
r.flags |= dns.flags.AA
elif lqname == "" and rrtype == NS:
r.answer.append(dns.rrset.from_text(suffix, 1, IN, NS, "ns2." + suffix))
r.answer.append(dns.rrset.from_text(suffix, 30, IN, NS, "ns2." + suffix))
r.flags |= dns.flags.AA
elif lqname == "ns2." and rrtype == A:
r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, A, "10.53.0.2"))
r.answer.append(dns.rrset.from_text("ns2."+suffix, 30, IN, A, "10.53.0.2"))
r.flags |= dns.flags.AA
elif lqname == "ns2." and rrtype == AAAA:
r.answer.append(dns.rrset.from_text("ns2."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::2"))
r.answer.append(dns.rrset.from_text("ns2."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::2"))
r.flags |= dns.flags.AA
elif lqname == "ns3." and rrtype == A:
r.answer.append(dns.rrset.from_text("ns3."+suffix, 1, IN, A, "10.53.0.3"))
r.answer.append(dns.rrset.from_text("ns3."+suffix, 30, IN, A, "10.53.0.3"))
r.flags |= dns.flags.AA
elif lqname == "ns3." and rrtype == AAAA:
r.answer.append(dns.rrset.from_text("ns3."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::3"))
r.answer.append(dns.rrset.from_text("ns3."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::3"))
r.flags |= dns.flags.AA
elif lqname == "ns4." and rrtype == A:
r.answer.append(dns.rrset.from_text("ns4."+suffix, 30, IN, A, "10.53.0.4"))
r.flags |= dns.flags.AA
elif lqname == "ns4." and rrtype == AAAA:
r.answer.append(dns.rrset.from_text("ns4."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::4"))
r.flags |= dns.flags.AA
elif lqname == "a.bit.longer.ns.name." and rrtype == A:
r.answer.append(dns.rrset.from_text("a.bit.longer.ns.name."+suffix, 1, IN, A, "10.53.0.4"))

View file

@ -67,6 +67,8 @@ def create_response(msg):
r = dns.message.make_response(m)
r.set_rcode(NOERROR)
ip6req = False
if lqname.endswith("bad."):
bad = True
suffix = "bad."
@ -82,6 +84,8 @@ def create_response(msg):
slow = True
suffix = "slow."
lqname = lqname[:-5]
elif lqname.endswith("8.2.6.0.1.0.0.2.ip6.arpa."):
ip6req = True
else:
r.set_rcode(REFUSED)
return r
@ -101,6 +105,9 @@ def create_response(msg):
elif lqname.endswith("zoop.boing."):
r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, SOA, "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
r.set_rcode(NXDOMAIN)
elif ip6req:
r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns4.good."))
r.additional.append(dns.rrset.from_text("ns4.good.", 60, IN, A, "10.53.0.4"))
else:
r.set_rcode(REFUSED)

View file

@ -68,6 +68,8 @@ def create_response(msg):
r = dns.message.make_response(m)
r.set_rcode(NOERROR)
ip6req = False
if lqname.endswith("bad."):
bad = True
suffix = "bad."
@ -83,6 +85,8 @@ def create_response(msg):
slow = True
suffix = "slow."
lqname = lqname[:-5]
elif lqname.endswith("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa."):
ip6req = True
else:
r.set_rcode(REFUSED)
return r
@ -103,6 +107,17 @@ def create_response(msg):
r.set_rcode(NXDOMAIN)
if ugly:
r.set_rcode(FORMERR)
elif ip6req:
r.flags |= dns.flags.AA
if lqname == "test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa." and rrtype == TXT:
r.answer.append(dns.rrset.from_text("test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 1, IN, TXT, "long_ip6_name"))
elif "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.".endswith(lqname):
#NODATA answer
r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, SOA, "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16"))
else:
# NXDOMAIN
r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, SOA, "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16"))
r.set_rcode(NXDOMAIN)
else:
r.set_rcode(REFUSED)

View file

@ -383,5 +383,16 @@ for ans in ans2; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true;
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "qname minimization resolves unusual ip6.arpa. names ($n)"
ret=0
$CLEANQL
$DIG $DIGOPTS test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. txt @10.53.0.7 > dig.out.test$n 2>&1
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
# Expected output in dig.out.test$n:
# ;; ANSWER SECTION:
# test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa. 1 IN TXT "long_ip6_name"
grep 'ip6\.arpa.*TXT.*long_ip6_name' dig.out.test$n > /dev/null || ret=1
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1

View file

@ -45,3 +45,13 @@ Bug Fixes
seen on older operating systems where unhandled ICMPv6 errors result in a
generic protocol error being returned instead of the more specific error code.
[GL #1928]
- With query minimization enabled, named failed to resolve ip6.arpa. names
that had more labels before the IPv6 part. For example, when named
implemented query minimization on a name like
``A.B.1.2.3.4.(...).ip6.arpa.``, it stopped at the left-most IPv6 label, i.e.
``1.2.3.4.(...).ip6.arpa.`` without considering the extra labels ``A.B``.
That caused a query loop when resolving the name: if named received
NXDOMAIN answers, then the same query was repeatedly sent until the number
of queries sent reached the value in the ``max-recursion-queries``
configuration option. [GL #1847]

View file

@ -10646,8 +10646,10 @@ fctx_minimize_qname(fetchctx_t *fctx) {
fctx->qmin_labels = 17;
} else if (fctx->qmin_labels < 19) {
fctx->qmin_labels = 19;
} else if (fctx->qmin_labels > 19) {
} else if (fctx->qmin_labels < 35) {
fctx->qmin_labels = 35;
} else {
fctx->qmin_labels = nlabels;
}
} else if (fctx->qmin_labels > DNS_QMIN_MAXLABELS) {
fctx->qmin_labels = DNS_MAX_LABELS + 1;