mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-10 22:39:58 -04:00
QNAME miminimization should create a separate fetch context for each fetch -
this makes the cache more efficient and eliminates duplicates queries.
This commit is contained in:
parent
36e431d632
commit
70a1ba20ec
26 changed files with 456 additions and 255 deletions
|
|
@ -771,7 +771,7 @@ main(int argc, char *argv[]) {
|
|||
if (noexact_zonecut)
|
||||
zcoptions |= DNS_DBFIND_NOEXACT;
|
||||
result = dns_db_findzonecut(db, &name, zcoptions,
|
||||
0, &node, fname,
|
||||
0, &node, fname, NULL,
|
||||
&rdataset, &sigrdataset);
|
||||
} else {
|
||||
result = dns_db_find(db, &name, version, type,
|
||||
|
|
|
|||
|
|
@ -220,14 +220,15 @@ find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
static isc_result_t
|
||||
findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
dns_name_t *dcname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
sampledb_t *sampledb = (sampledb_t *) db;
|
||||
|
||||
REQUIRE(VALID_SAMPLEDB(sampledb));
|
||||
|
||||
return (dns_db_findzonecut(sampledb->rbtdb, name, options,
|
||||
now, nodep, foundname, rdataset,
|
||||
now, nodep, foundname, dcname, rdataset,
|
||||
sigrdataset));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from datetime import datetime, timedelta
|
|||
import time
|
||||
import functools
|
||||
|
||||
import dns, dns.message, dns.query
|
||||
import dns, dns.message, dns.query, dns.flags
|
||||
from dns.rdatatype import *
|
||||
from dns.rdataclass import *
|
||||
from dns.rcode import *
|
||||
|
|
@ -44,6 +44,8 @@ def logquery(type, qname):
|
|||
#
|
||||
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
|
||||
#
|
||||
# For ugly. it works the same as for good., but returns garbage to non-empty terminals
|
||||
#
|
||||
# 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.
|
||||
# 1.0.0.2.ip6.arpa. IN NS ns2.good
|
||||
|
|
@ -61,6 +63,7 @@ def create_response(msg):
|
|||
if typename == "A" or typename == "AAAA":
|
||||
typename = "ADDR"
|
||||
bad = False
|
||||
ugly = False
|
||||
slow = False
|
||||
|
||||
# log this query
|
||||
|
|
@ -76,9 +79,11 @@ def create_response(msg):
|
|||
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:
|
||||
# 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.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"))
|
||||
|
|
@ -91,6 +96,7 @@ def create_response(msg):
|
|||
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.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"))
|
||||
|
|
@ -103,6 +109,10 @@ def create_response(msg):
|
|||
bad = True
|
||||
suffix = "bad."
|
||||
lqname = lqname[:-4]
|
||||
elif lqname.endswith("ugly."):
|
||||
ugly = True
|
||||
suffix = "ugly."
|
||||
lqname = lqname[:-5]
|
||||
elif lqname.endswith("good."):
|
||||
suffix = "good."
|
||||
lqname = lqname[:-5]
|
||||
|
|
@ -114,25 +124,33 @@ def create_response(msg):
|
|||
r.set_rcode(REFUSED)
|
||||
return r
|
||||
|
||||
# Good/bad differs only in how we treat non-empty terminals
|
||||
# Good/bad/ugly differs only in how we treat non-empty terminals
|
||||
if lqname.endswith("zoop.boing."):
|
||||
r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, NS, "ns3." + suffix))
|
||||
elif lqname == "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z." and rrtype == A:
|
||||
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.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.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.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.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.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"))
|
||||
r.flags |= dns.flags.AA
|
||||
elif lqname == "a.bit.longer.ns.name." and rrtype == AAAA:
|
||||
r.answer.append(dns.rrset.from_text("a.bit.longer.ns.name."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::4"))
|
||||
r.flags |= dns.flags.AA
|
||||
else:
|
||||
r.authority.append(dns.rrset.from_text(suffix, 1, IN, SOA, "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
||||
if bad or not \
|
||||
|
|
@ -140,6 +158,8 @@ def create_response(msg):
|
|||
"many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.".endswith(lqname) or \
|
||||
"a.bit.longer.ns.name.".endswith(lqname)):
|
||||
r.set_rcode(NXDOMAIN)
|
||||
if ugly:
|
||||
r.set_rcode(FORMERR)
|
||||
if slow:
|
||||
time.sleep(0.2)
|
||||
return r
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from datetime import datetime, timedelta
|
|||
import time
|
||||
import functools
|
||||
|
||||
import dns, dns.message, dns.query
|
||||
import dns, dns.message, dns.query, dns.flags
|
||||
from dns.rdatatype import *
|
||||
from dns.rdataclass import *
|
||||
from dns.rcode import *
|
||||
|
|
@ -41,6 +41,8 @@ def logquery(type, qname):
|
|||
# For slow. it works the same as for good., but each response is delayed by 400 miliseconds
|
||||
#
|
||||
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
|
||||
#
|
||||
# For ugly. it works the same as for good., but returns garbage to non-empty terminals
|
||||
############################################################################
|
||||
def create_response(msg):
|
||||
m = dns.message.from_wire(msg)
|
||||
|
|
@ -54,6 +56,7 @@ def create_response(msg):
|
|||
if typename == "A" or typename == "AAAA":
|
||||
typename = "ADDR"
|
||||
bad = False
|
||||
ugly = False
|
||||
slow = False
|
||||
|
||||
# log this query
|
||||
|
|
@ -68,6 +71,10 @@ def create_response(msg):
|
|||
bad = True
|
||||
suffix = "bad."
|
||||
lqname = lqname[:-4]
|
||||
elif lqname.endswith("ugly."):
|
||||
ugly = True
|
||||
suffix = "ugly."
|
||||
lqname = lqname[:-5]
|
||||
elif lqname.endswith("good."):
|
||||
suffix = "good."
|
||||
lqname = lqname[:-5]
|
||||
|
|
@ -82,12 +89,15 @@ def create_response(msg):
|
|||
# Good/bad differs only in how we treat non-empty terminals
|
||||
if lqname == "zoop.boing." and rrtype == NS:
|
||||
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, NS, "ns3."+suffix))
|
||||
r.flags |= dns.flags.AA
|
||||
elif lqname.endswith("icky.ptang.zoop.boing."):
|
||||
r.authority.append(dns.rrset.from_text("icky.ptang.zoop.boing." + suffix, 1, IN, NS, "a.bit.longer.ns.name." + suffix))
|
||||
elif "icky.ptang.zoop.boing.".endswith(lqname):
|
||||
r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, SOA, "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
||||
if bad:
|
||||
r.set_rcode(NXDOMAIN)
|
||||
if ugly:
|
||||
r.set_rcode(FORMERR)
|
||||
elif "zoop.boing.".endswith(lqname):
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from datetime import datetime, timedelta
|
|||
import time
|
||||
import functools
|
||||
|
||||
import dns, dns.message, dns.query
|
||||
import dns, dns.message, dns.query, dns.flags
|
||||
from dns.rdatatype import *
|
||||
from dns.rdataclass import *
|
||||
from dns.rcode import *
|
||||
|
|
@ -42,6 +42,8 @@ def logquery(type, qname):
|
|||
# For slow. it works the same as for good., but each response is delayed by 400 miliseconds
|
||||
#
|
||||
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
|
||||
#
|
||||
# For ugly. it works the same as for good., but returns garbage to non-empty terminals
|
||||
############################################################################
|
||||
def create_response(msg):
|
||||
m = dns.message.from_wire(msg)
|
||||
|
|
@ -56,6 +58,7 @@ def create_response(msg):
|
|||
typename = "ADDR"
|
||||
bad = False
|
||||
slow = False
|
||||
ugly = False
|
||||
|
||||
# log this query
|
||||
with open("query.log", "a") as f:
|
||||
|
|
@ -69,6 +72,10 @@ def create_response(msg):
|
|||
bad = True
|
||||
suffix = "bad."
|
||||
lqname = lqname[:-4]
|
||||
elif lqname.endswith("ugly."):
|
||||
ugly = True
|
||||
suffix = "ugly."
|
||||
lqname = lqname[:-5]
|
||||
elif lqname.endswith("good."):
|
||||
suffix = "good."
|
||||
lqname = lqname[:-5]
|
||||
|
|
@ -83,14 +90,19 @@ def create_response(msg):
|
|||
# Good/bad differs only in how we treat non-empty terminals
|
||||
if lqname == "icky.icky.icky.ptang.zoop.boing." and rrtype == A:
|
||||
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.1"))
|
||||
r.flags |= dns.flags.AA
|
||||
elif lqname == "more.icky.icky.icky.ptang.zoop.boing." and rrtype == A:
|
||||
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
|
||||
r.flags |= dns.flags.AA
|
||||
elif lqname == "icky.ptang.zoop.boing." and rrtype == NS:
|
||||
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, NS, "a.bit.longer.ns.name."+suffix))
|
||||
r.flags |= dns.flags.AA
|
||||
elif lqname.endswith("icky.ptang.zoop.boing."):
|
||||
r.authority.append(dns.rrset.from_text("icky.ptang.zoop.boing." + suffix, 1, IN, SOA, "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
|
||||
if bad or not "more.icky.icky.icky.ptang.zoop.boing.".endswith(lqname):
|
||||
r.set_rcode(NXDOMAIN)
|
||||
if ugly:
|
||||
r.set_rcode(FORMERR)
|
||||
else:
|
||||
r.set_rcode(REFUSED)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,5 +28,5 @@ ns2.bad. A 10.53.0.2
|
|||
slow NS ns2.slow.
|
||||
ns2.slow. A 10.53.0.2
|
||||
|
||||
horrible. NS ns2.horrible.
|
||||
ns2.horrible. A 10.53.0.2
|
||||
ugly. NS ns2.ugly.
|
||||
ns2.ugly. A 10.53.0.2
|
||||
|
|
|
|||
|
|
@ -85,6 +85,29 @@ for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null
|
|||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "query for .ugly is not minimized when qname-minimization is off ($n)"
|
||||
ret=0
|
||||
$CLEANQL
|
||||
$RNDCCMD 10.53.0.5 flush
|
||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.ugly. @10.53.0.5 > dig.out.test$n
|
||||
sleep 5
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "icky.icky.icky.ptang.zoop.boing.ugly. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
ADDR icky.icky.icky.ptang.zoop.boing.ugly.
|
||||
ADDR ns3.ugly.
|
||||
ADDR ns3.ugly.
|
||||
ADDR a.bit.longer.ns.name.ugly.
|
||||
ADDR a.bit.longer.ns.name.ugly.
|
||||
__EOF
|
||||
echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans3/query.log - > /dev/null || ret=1
|
||||
echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans4/query.log - > /dev/null || ret=1
|
||||
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "query for .good is properly minimized when qname-minimization is on ($n)"
|
||||
ret=0
|
||||
|
|
@ -94,31 +117,22 @@ $DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.good. @10.53.0.6 > dig.out.test$n
|
|||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "icky.icky.icky.ptang.zoop.boing.good. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
# Duplicated NS queries are there because we're not creating
|
||||
# a separate fetch when doing qname minimization - so two
|
||||
# queries running for the same name but different RRTYPE
|
||||
# (A and AAAA in this case) will create separate queries
|
||||
# for NSes on the way. Those will be cached though, so it
|
||||
# should not be a problem
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
NS good.
|
||||
NS boing.good.
|
||||
NS zoop.boing.good.
|
||||
ADDR ns3.good.
|
||||
ADDR ns3.good.
|
||||
NS name.good.
|
||||
NS name.good.
|
||||
NS ns.name.good.
|
||||
NS ns.name.good.
|
||||
NS longer.ns.name.good.
|
||||
NS longer.ns.name.good.
|
||||
ADDR a.bit.longer.ns.name.good.
|
||||
ADDR a.bit.longer.ns.name.good.
|
||||
__EOF
|
||||
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
|
||||
NS zoop.boing.good.
|
||||
NS ptang.zoop.boing.good.
|
||||
NS icky.ptang.zoop.boing.good.
|
||||
__EOF
|
||||
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
|
||||
NS icky.ptang.zoop.boing.good.
|
||||
NS icky.icky.ptang.zoop.boing.good.
|
||||
ADDR icky.icky.icky.ptang.zoop.boing.good.
|
||||
__EOF
|
||||
|
|
@ -134,7 +148,10 @@ $RNDCCMD 10.53.0.6 flush
|
|||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.bad. @10.53.0.6 > dig.out.test$n
|
||||
grep "status: NXDOMAIN" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
echo "NS boing.bad." | diff ans2/query.log - > /dev/null || ret=1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
NS bad.
|
||||
NS boing.bad.
|
||||
__EOF
|
||||
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
|
@ -149,12 +166,11 @@ grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
|||
grep "icky.icky.icky.ptang.zoop.boing.bad. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
NS bad.
|
||||
NS boing.bad.
|
||||
ADDR icky.icky.icky.ptang.zoop.boing.bad.
|
||||
ADDR ns3.bad.
|
||||
ADDR ns3.bad.
|
||||
NS name.bad.
|
||||
NS name.bad.
|
||||
ADDR a.bit.longer.ns.name.bad.
|
||||
ADDR a.bit.longer.ns.name.bad.
|
||||
__EOF
|
||||
|
|
@ -164,6 +180,52 @@ for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null
|
|||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "query for .ugly fails when qname-minimization is in strict mode ($n)"
|
||||
ret=0
|
||||
$CLEANQL
|
||||
$RNDCCMD 10.53.0.6 flush
|
||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.ugly. @10.53.0.6 > dig.out.test$n
|
||||
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
NS ugly.
|
||||
NS boing.ugly.
|
||||
NS boing.ugly.
|
||||
NS boing.ugly.
|
||||
__EOF
|
||||
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
$RNDCCMD 10.53.0.6 flush
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "query for .ugly succeds when qname-minimization is in relaxed mode ($n)"
|
||||
ret=0
|
||||
$CLEANQL
|
||||
$RNDCCMD 10.53.0.7 flush
|
||||
$DIG $DIGOPTS icky.icky.icky.ptang.zoop.boing.ugly. @10.53.0.7 > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || (ret=1; echo "A")
|
||||
grep "icky.icky.icky.ptang.zoop.boing.ugly. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || (ret=1; echo "X")
|
||||
sleep 1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || (ret=1; echo "Y")
|
||||
NS ugly.
|
||||
NS boing.ugly.
|
||||
NS boing.ugly.
|
||||
NS boing.ugly.
|
||||
ADDR icky.icky.icky.ptang.zoop.boing.ugly.
|
||||
ADDR ns3.ugly.
|
||||
ADDR ns3.ugly.
|
||||
ADDR a.bit.longer.ns.name.ugly.
|
||||
ADDR a.bit.longer.ns.name.ugly.
|
||||
__EOF
|
||||
echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans3/query.log - > /dev/null || ret=1
|
||||
echo "ADDR icky.icky.icky.ptang.zoop.boing.ugly." | diff ans4/query.log - > /dev/null || ret=1
|
||||
for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null || true; done
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
$RNDCCMD 10.53.0.7 flush
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "query for .slow is properly minimized when qname-minimization is on ($n)"
|
||||
ret=0
|
||||
|
|
@ -174,24 +236,22 @@ sleep 5
|
|||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "icky.icky.icky.ptang.zoop.boing.slow. 1 IN A 192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
NS slow.
|
||||
NS boing.slow.
|
||||
NS zoop.boing.slow.
|
||||
ADDR ns3.slow.
|
||||
ADDR ns3.slow.
|
||||
NS name.slow.
|
||||
NS name.slow.
|
||||
NS ns.name.slow.
|
||||
NS ns.name.slow.
|
||||
NS longer.ns.name.slow.
|
||||
NS longer.ns.name.slow.
|
||||
NS icky.ptang.zoop.boing.slow.
|
||||
ADDR a.bit.longer.ns.name.slow.
|
||||
ADDR a.bit.longer.ns.name.slow.
|
||||
__EOF
|
||||
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
|
||||
NS zoop.boing.slow.
|
||||
NS ptang.zoop.boing.slow.
|
||||
NS icky.ptang.zoop.boing.slow.
|
||||
__EOF
|
||||
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
|
||||
NS icky.ptang.zoop.boing.slow.
|
||||
NS icky.icky.ptang.zoop.boing.slow.
|
||||
ADDR icky.icky.icky.ptang.zoop.boing.slow.
|
||||
__EOF
|
||||
|
|
@ -220,25 +280,6 @@ for ans in ans2 ans3 ans4; do mv -f $ans/query.log query-$ans-$n.log 2>/dev/null
|
|||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "query for multiple label name skips after 3rd no-delegation response ($n)"
|
||||
ret=0
|
||||
$CLEANQL
|
||||
$RNDCCMD 10.53.0.6 flush
|
||||
$DIG $DIGOPTS many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good. @10.53.0.6 > dig.out.test$n
|
||||
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||
grep "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good. 1 IN A 192.0.2.2" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
# We skipped after third no-delegation.
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
NS z.good.
|
||||
NS y.z.good.
|
||||
NS x.y.z.good.
|
||||
ADDR many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good.
|
||||
__EOF
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "query for multiple label name skips after 7th label ($n)"
|
||||
ret=0
|
||||
|
|
@ -249,25 +290,22 @@ grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
|||
grep "more.icky.icky.icky.ptang.zoop.boing.good. 1 IN A 192.0.2.2" dig.out.test$n > /dev/null || ret=1
|
||||
sleep 1
|
||||
cat << __EOF | diff ans2/query.log - > /dev/null || ret=1
|
||||
NS good.
|
||||
NS boing.good.
|
||||
NS zoop.boing.good.
|
||||
ADDR ns3.good.
|
||||
ADDR ns3.good.
|
||||
NS name.good.
|
||||
NS name.good.
|
||||
NS ns.name.good.
|
||||
NS ns.name.good.
|
||||
NS longer.ns.name.good.
|
||||
NS longer.ns.name.good.
|
||||
ADDR a.bit.longer.ns.name.good.
|
||||
ADDR a.bit.longer.ns.name.good.
|
||||
__EOF
|
||||
cat << __EOF | diff ans3/query.log - > /dev/null || ret=1
|
||||
NS zoop.boing.good.
|
||||
NS ptang.zoop.boing.good.
|
||||
NS icky.ptang.zoop.boing.good.
|
||||
__EOF
|
||||
# There's no NS icky.icky.ptang.zoop.boing.good. query - we skipped it.
|
||||
# There's no NS icky.icky.icky.ptang.zoop.boing.good. query - we skipped it.
|
||||
cat << __EOF | diff ans4/query.log - > /dev/null || ret=1
|
||||
NS icky.ptang.zoop.boing.good.
|
||||
NS icky.icky.ptang.zoop.boing.good.
|
||||
ADDR more.icky.icky.icky.ptang.zoop.boing.good.
|
||||
__EOF
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ options {
|
|||
notify no;
|
||||
minimal-responses no;
|
||||
recursion yes;
|
||||
qname-minimization disabled;
|
||||
dnssec-validation yes;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ options {
|
|||
notify yes;
|
||||
minimal-responses no;
|
||||
recursion yes;
|
||||
qname-minimization disabled;
|
||||
dnssec-validation yes;
|
||||
|
||||
response-policy {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ options {
|
|||
notify no;
|
||||
minimal-responses no;
|
||||
recursion yes;
|
||||
qname-minimization disabled;
|
||||
dnssec-validation yes;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ options {
|
|||
notify yes;
|
||||
minimal-responses no;
|
||||
recursion yes;
|
||||
qname-minimization disabled;
|
||||
dnssec-validation yes;
|
||||
|
||||
# turn rpz on or off
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ options {
|
|||
forwarders { 10.53.0.3; };
|
||||
minimal-responses no;
|
||||
recursion yes;
|
||||
qname-minimization disabled;
|
||||
dnssec-validation yes;
|
||||
|
||||
response-policy {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ options {
|
|||
listen-on-v6 { none; };
|
||||
minimal-responses no;
|
||||
recursion yes;
|
||||
qname-minimization disabled;
|
||||
dnssec-validation yes;
|
||||
|
||||
response-policy {
|
||||
|
|
|
|||
|
|
@ -4024,7 +4024,7 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone,
|
|||
adbname);
|
||||
name = dns_fixedname_initname(&fixed);
|
||||
result = dns_view_findzonecut(adb->view, &adbname->name, name,
|
||||
0, 0, true, false,
|
||||
NULL, 0, 0, true, false,
|
||||
&rdataset, NULL);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
|
||||
goto cleanup;
|
||||
|
|
@ -4032,14 +4032,6 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone,
|
|||
options |= DNS_FETCHOPT_UNSHARED;
|
||||
}
|
||||
|
||||
if (adb->view->qminimization) {
|
||||
options |= DNS_FETCHOPT_QMINIMIZE;
|
||||
options |= DNS_FETCHOPT_QMIN_SKIP_IP6A;
|
||||
if (adb->view->qmin_strict) {
|
||||
options |= DNS_FETCHOPT_QMIN_STRICT;
|
||||
}
|
||||
}
|
||||
|
||||
fetch = new_adbfetch(adb);
|
||||
if (fetch == NULL) {
|
||||
result = ISC_R_NOMEMORY;
|
||||
|
|
@ -4047,6 +4039,14 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone,
|
|||
}
|
||||
fetch->depth = depth;
|
||||
|
||||
/*
|
||||
* We're not minimizing this query, as nothing user-related should
|
||||
* be leaked here.
|
||||
* However, if we'd ever want to change it we'd have to modify
|
||||
* createfetch to find deepest cached name when we're providing
|
||||
* domain and nameservers.
|
||||
*/
|
||||
|
||||
result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
|
||||
type, name, nameservers, NULL,
|
||||
NULL, 0, options, depth, qc,
|
||||
|
|
|
|||
|
|
@ -559,10 +559,13 @@ isc_result_t
|
|||
dns_db_findzonecut(dns_db_t *db, const dns_name_t *name,
|
||||
unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
dns_name_t *dcname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
/*
|
||||
* Find the deepest known zonecut which encloses 'name' in 'db'.
|
||||
* foundname is the zonecut, dcname is the deepest name we have
|
||||
* in database that is part of queried name.
|
||||
*/
|
||||
|
||||
REQUIRE(DNS_DB_VALID(db));
|
||||
|
|
@ -574,7 +577,8 @@ dns_db_findzonecut(dns_db_t *db, const dns_name_t *name,
|
|||
! dns_rdataset_isassociated(sigrdataset)));
|
||||
|
||||
return ((db->methods->findzonecut)(db, name, options, now, nodep,
|
||||
foundname, rdataset, sigrdataset));
|
||||
foundname, dcname,
|
||||
rdataset, sigrdataset));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -311,7 +311,8 @@ static isc_result_t
|
|||
findzonecut(dns_db_t *db, const dns_name_t *name,
|
||||
unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
dns_name_t *dcname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
|
||||
|
||||
|
|
@ -322,6 +323,7 @@ findzonecut(dns_db_t *db, const dns_name_t *name,
|
|||
UNUSED(now);
|
||||
UNUSED(nodep);
|
||||
UNUSED(foundname);
|
||||
UNUSED(dcname);
|
||||
UNUSED(rdataset);
|
||||
UNUSED(sigrdataset);
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static struct tt {
|
|||
int type;
|
||||
char classname[TYPECLASSBUF];
|
||||
char typename[TYPECLASSBUF];
|
||||
char dirname[DIRNAMESIZE]; /* XXX Should be max path length */
|
||||
char dirname[DIRNAMESIZE-30]; /* XXX Should be max path length */
|
||||
} *types;
|
||||
|
||||
static struct ttnam {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ typedef struct dns_dbmethods {
|
|||
unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep,
|
||||
dns_name_t *foundname,
|
||||
dns_name_t *dcname,
|
||||
dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset);
|
||||
void (*attachnode)(dns_db_t *db,
|
||||
|
|
@ -936,7 +937,8 @@ isc_result_t
|
|||
dns_db_findzonecut(dns_db_t *db, const dns_name_t *name,
|
||||
unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
|
||||
dns_name_t *dcname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset);
|
||||
/*%<
|
||||
* Find the deepest known zonecut which encloses 'name' in 'db'.
|
||||
*
|
||||
|
|
@ -955,6 +957,8 @@ dns_db_findzonecut(dns_db_t *db, const dns_name_t *name,
|
|||
*
|
||||
* \li 'foundname' is a valid name with a dedicated buffer.
|
||||
*
|
||||
* \li 'dcname' is a valid name with a dedicated buffer.
|
||||
*
|
||||
* \li 'rdataset' is NULL, or is a valid unassociated rdataset.
|
||||
*
|
||||
* Ensures, on a non-error completion:
|
||||
|
|
@ -964,6 +968,9 @@ dns_db_findzonecut(dns_db_t *db, const dns_name_t *name,
|
|||
* \li If foundname != NULL, then it contains the full name of the
|
||||
* found node.
|
||||
*
|
||||
* \li If dcname != NULL, then it contains the deepest cached name
|
||||
* that exists in the database.
|
||||
*
|
||||
* \li If rdataset != NULL and type != dns_rdatatype_any, then
|
||||
* rdataset is bound to the found rdataset.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -704,7 +704,7 @@ dns_view_simplefind(dns_view_t *view, const dns_name_t *name,
|
|||
|
||||
isc_result_t
|
||||
dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
||||
dns_name_t *fname, isc_stdtime_t now,
|
||||
dns_name_t *fname, dns_name_t *dcname, isc_stdtime_t now,
|
||||
unsigned int options,
|
||||
bool use_hints, bool use_cache,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
|
||||
|
|
@ -730,6 +730,8 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
|||
*\li If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned
|
||||
* (if any) will be the deepest known ancestor of 'name'.
|
||||
*
|
||||
*\li If dcname is not NULL the deepest cached name is copied to it.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'view' is a valid, frozen view.
|
||||
|
|
|
|||
|
|
@ -4307,7 +4307,7 @@ zone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
static isc_result_t
|
||||
zone_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
isc_stdtime_t now, dns_dbnode_t **nodep,
|
||||
dns_name_t *foundname,
|
||||
dns_name_t *foundname, dns_name_t *dcname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
UNUSED(db);
|
||||
|
|
@ -4316,6 +4316,7 @@ zone_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
UNUSED(now);
|
||||
UNUSED(nodep);
|
||||
UNUSED(foundname);
|
||||
UNUSED(dcname);
|
||||
UNUSED(rdataset);
|
||||
UNUSED(sigrdataset);
|
||||
|
||||
|
|
@ -5034,7 +5035,7 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
static isc_result_t
|
||||
cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
isc_stdtime_t now, dns_dbnode_t **nodep,
|
||||
dns_name_t *foundname,
|
||||
dns_name_t *foundname, dns_name_t *dcname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
|
@ -5045,6 +5046,7 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
rdatasetheader_t *found, *foundsig;
|
||||
unsigned int rbtoptions = DNS_RBTFIND_EMPTYDATA;
|
||||
isc_rwlocktype_t locktype;
|
||||
bool dcnull = (dcname == NULL);
|
||||
|
||||
search.rbtdb = (dns_rbtdb_t *)db;
|
||||
|
||||
|
|
@ -5064,6 +5066,10 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
dns_rbtnodechain_init(&search.chain, search.rbtdb->common.mctx);
|
||||
search.now = now;
|
||||
|
||||
if (dcnull) {
|
||||
dcname = foundname;
|
||||
}
|
||||
|
||||
if ((options & DNS_DBFIND_NOEXACT) != 0)
|
||||
rbtoptions |= DNS_RBTFIND_NOEXACT;
|
||||
|
||||
|
|
@ -5072,17 +5078,18 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
/*
|
||||
* Search down from the root of the tree.
|
||||
*/
|
||||
result = dns_rbt_findnode(search.rbtdb->tree, name, foundname, &node,
|
||||
result = dns_rbt_findnode(search.rbtdb->tree, name, dcname, &node,
|
||||
&search.chain, rbtoptions, NULL, &search);
|
||||
|
||||
if (result == DNS_R_PARTIALMATCH) {
|
||||
find_ns:
|
||||
result = find_deepest_zonecut(&search, node, nodep, foundname,
|
||||
rdataset, sigrdataset);
|
||||
goto tree_exit;
|
||||
} else if (result != ISC_R_SUCCESS)
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
goto tree_exit;
|
||||
|
||||
} else if (!dcnull) {
|
||||
dns_name_copy(dcname, foundname, NULL);
|
||||
}
|
||||
/*
|
||||
* We now go looking for an NS rdataset at the node.
|
||||
*/
|
||||
|
|
@ -5129,7 +5136,9 @@ cache_findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
* No NS records here.
|
||||
*/
|
||||
NODE_UNLOCK(lock, locktype);
|
||||
goto find_ns;
|
||||
result = find_deepest_zonecut(&search, node, nodep, foundname,
|
||||
rdataset, sigrdataset);
|
||||
goto tree_exit;
|
||||
}
|
||||
|
||||
if (nodep != NULL) {
|
||||
|
|
|
|||
|
|
@ -261,8 +261,8 @@ struct fetchctx {
|
|||
/*% Not locked. */
|
||||
unsigned int magic;
|
||||
dns_resolver_t * res;
|
||||
dns_name_t fullname;
|
||||
dns_rdatatype_t fulltype;
|
||||
dns_name_t name;
|
||||
dns_rdatatype_t type;
|
||||
unsigned int options;
|
||||
unsigned int bucketnum;
|
||||
unsigned int dbucketnum;
|
||||
|
|
@ -311,10 +311,12 @@ struct fetchctx {
|
|||
isc_counter_t * qc;
|
||||
bool minimized;
|
||||
unsigned int qmin_labels;
|
||||
unsigned int qmin_steps;
|
||||
bool ip6arpaskip;
|
||||
dns_name_t name;
|
||||
dns_rdatatype_t type;
|
||||
bool ip6arpaskip;
|
||||
dns_name_t qminname;
|
||||
dns_rdatatype_t qmintype;
|
||||
dns_fetch_t * qminfetch;
|
||||
dns_rdataset_t qminrrset;
|
||||
dns_name_t qmindcname;
|
||||
|
||||
/*%
|
||||
* The number of events we're waiting for.
|
||||
|
|
@ -558,6 +560,12 @@ struct dns_resolver {
|
|||
#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
|
||||
#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
|
||||
|
||||
#define NXDOMAIN_RESULT(r) ((r) == DNS_R_NXDOMAIN || \
|
||||
(r) == DNS_R_NCACHENXDOMAIN)
|
||||
#define NXRRSET_RESULT(r) ((r) == DNS_R_NCACHENXRRSET || \
|
||||
(r) == DNS_R_NXRRSET || \
|
||||
(r) == DNS_R_HINTNXRRSET)
|
||||
|
||||
#ifdef ENABLE_AFL
|
||||
bool dns_fuzzing_resolver = false;
|
||||
void dns_resolver_setfuzzing() {
|
||||
|
|
@ -597,6 +605,7 @@ static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name,
|
|||
dns_name_t **noqname);
|
||||
static void fctx_increference(fetchctx_t *fctx);
|
||||
static bool fctx_decreference(fetchctx_t *fctx);
|
||||
static void resume_qmin(isc_task_t *task, isc_event_t *event);
|
||||
|
||||
/*%
|
||||
* The structure and functions defined below implement the resolver
|
||||
|
|
@ -766,12 +775,6 @@ rctx_referral(respctx_t *rctx);
|
|||
static isc_result_t
|
||||
rctx_answer_none(respctx_t *rctx);
|
||||
|
||||
static void
|
||||
rctx_follow_referral(respctx_t *rctx);
|
||||
|
||||
static isc_result_t
|
||||
rctx_answer_minimized(respctx_t *rctx);
|
||||
|
||||
static void
|
||||
rctx_nextserver(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo,
|
||||
isc_result_t result);
|
||||
|
|
@ -3339,6 +3342,7 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
|
|||
options, now, NULL,
|
||||
res->view->dstport,
|
||||
fctx->depth + 1, fctx->qc, &find);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (result == DNS_R_ALIAS) {
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
|
|
@ -3930,6 +3934,7 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
|
|||
isc_result_t result;
|
||||
dns_adbaddrinfo_t *addrinfo = NULL;
|
||||
dns_resolver_t *res;
|
||||
isc_task_t *task;
|
||||
unsigned int bucketnum;
|
||||
bool bucket_empty;
|
||||
|
||||
|
|
@ -3938,6 +3943,7 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
|
|||
REQUIRE(!ADDRWAIT(fctx));
|
||||
|
||||
res = fctx->res;
|
||||
bucketnum = fctx->bucketnum;
|
||||
|
||||
/* We've already exceeded maximum query count */
|
||||
if (isc_counter_used(fctx->qc) > res->maxqueries) {
|
||||
|
|
@ -3951,6 +3957,26 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're minimizing and we're not yet at the final NS -
|
||||
* we need to launch a query for NS for 'upper' domain
|
||||
*/
|
||||
if (fctx->minimized == true) {
|
||||
unsigned int options = fctx->options;
|
||||
options &= ~DNS_FETCHOPT_QMINIMIZE;
|
||||
fctx_increference(fctx);
|
||||
task = res->buckets[bucketnum].task;
|
||||
result = dns_resolver_createfetch(fctx->res, &fctx->qminname,
|
||||
fctx->qmintype, NULL,
|
||||
NULL, NULL, NULL, 0,
|
||||
options, 0, fctx->qc,
|
||||
task, resume_qmin, fctx,
|
||||
&fctx->qminrrset, NULL,
|
||||
&fctx->qminfetch);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
addrinfo = fctx_nextaddress(fctx);
|
||||
|
||||
/* Try to find an address that isn't over quota */
|
||||
|
|
@ -4005,7 +4031,6 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
|
|||
}
|
||||
}
|
||||
|
||||
bucketnum = fctx->bucketnum;
|
||||
fctx_increference(fctx);
|
||||
result = fctx_query(fctx, addrinfo, fctx->options);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -4019,6 +4044,118 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
|
|||
inc_stats(res, dns_resstatscounter_retry);
|
||||
}
|
||||
|
||||
static void
|
||||
resume_qmin(isc_task_t *task, isc_event_t *event) {
|
||||
dns_fetchevent_t *fevent;
|
||||
dns_resolver_t *res;
|
||||
fetchctx_t *fctx;
|
||||
isc_result_t result;
|
||||
bool bucket_empty;
|
||||
bool locked = false;
|
||||
unsigned int bucketnum;
|
||||
unsigned int findoptions = 0;
|
||||
dns_name_t *fname, *dcname;
|
||||
dns_fixedname_t ffixed, dcfixed;
|
||||
fname = dns_fixedname_initname(&ffixed);
|
||||
dcname = dns_fixedname_initname(&dcfixed);
|
||||
|
||||
REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
|
||||
fevent = (dns_fetchevent_t *)event;
|
||||
fctx = event->ev_arg;
|
||||
REQUIRE(VALID_FCTX(fctx));
|
||||
res = fctx->res;
|
||||
|
||||
UNUSED(task);
|
||||
FCTXTRACE("resume_qmin");
|
||||
|
||||
if (fevent->node != NULL)
|
||||
dns_db_detachnode(fevent->db, &fevent->node);
|
||||
if (fevent->db != NULL)
|
||||
dns_db_detach(&fevent->db);
|
||||
|
||||
bucketnum = fctx->bucketnum;
|
||||
|
||||
if (dns_rdataset_isassociated(fevent->rdataset)) {
|
||||
dns_rdataset_disassociate(fevent->rdataset);
|
||||
}
|
||||
result = fevent->result;
|
||||
fevent = NULL;
|
||||
isc_event_free(&event);
|
||||
|
||||
dns_resolver_destroyfetch(&fctx->qminfetch);
|
||||
|
||||
/*
|
||||
* Note: fevent->rdataset must be disassociated and
|
||||
* isc_event_free(&event) be called before resuming
|
||||
* processing of the 'fctx' to prevent use-after-free.
|
||||
* 'fevent' is set to NULL so as to not have a dangling
|
||||
* pointer.
|
||||
*/
|
||||
if (result == ISC_R_CANCELED) {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
goto cleanup;
|
||||
} else if (NXDOMAIN_RESULT(result) || result == DNS_R_FORMERR ||
|
||||
result == DNS_R_REMOTEFORMERR)
|
||||
{
|
||||
if ((fctx->options & DNS_FETCHOPT_QMIN_STRICT) == 0) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
|
||||
"disabling qname minimization for '%s' "
|
||||
"due to nxdomain", fctx->info);
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
} else {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dns_rdataset_isassociated(&fctx->nameservers)) {
|
||||
dns_rdataset_disassociate(&fctx->nameservers);
|
||||
}
|
||||
|
||||
if (dns_rdatatype_atparent(fctx->type)) {
|
||||
findoptions |= DNS_DBFIND_NOEXACT;
|
||||
}
|
||||
result = dns_view_findzonecut(res->view, &fctx->name, fname,
|
||||
dcname, fctx->now, findoptions,
|
||||
true, true, &fctx->nameservers, NULL);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
return;
|
||||
}
|
||||
fcount_decr(fctx);
|
||||
dns_name_free(&fctx->domain, fctx->mctx);
|
||||
dns_name_init(&fctx->domain, NULL);
|
||||
result = dns_name_dup(fname, fctx->mctx, &fctx->domain);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
return;
|
||||
}
|
||||
dns_name_free(&fctx->qmindcname, fctx->mctx);
|
||||
dns_name_init(&fctx->qmindcname, NULL);
|
||||
result = dns_name_dup(dcname, fctx->mctx, &fctx->qmindcname);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
return;
|
||||
}
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = true;
|
||||
fctx_minimize_qname(fctx);
|
||||
fctx_try(fctx, true, false);
|
||||
|
||||
cleanup:
|
||||
INSIST(event == NULL);
|
||||
INSIST(fevent == NULL);
|
||||
if (!locked)
|
||||
LOCK(&res->buckets[bucketnum].lock);
|
||||
bucket_empty = fctx_decreference(fctx);
|
||||
UNLOCK(&res->buckets[bucketnum].lock);
|
||||
if (bucket_empty)
|
||||
empty_bucket(res);
|
||||
}
|
||||
|
||||
static bool
|
||||
fctx_unlink(fetchctx_t *fctx) {
|
||||
dns_resolver_t *res;
|
||||
|
|
@ -4119,8 +4256,9 @@ fctx_destroy(fetchctx_t *fctx) {
|
|||
dns_name_free(&fctx->domain, fctx->mctx);
|
||||
if (dns_rdataset_isassociated(&fctx->nameservers))
|
||||
dns_rdataset_disassociate(&fctx->nameservers);
|
||||
dns_name_free(&fctx->fullname, fctx->mctx);
|
||||
dns_name_free(&fctx->name, fctx->mctx);
|
||||
dns_name_free(&fctx->qminname, fctx->mctx);
|
||||
dns_name_free(&fctx->qmindcname, fctx->mctx);
|
||||
dns_db_detach(&fctx->cache);
|
||||
dns_adb_detach(&fctx->adb);
|
||||
isc_mem_free(fctx->mctx, fctx->info);
|
||||
|
|
@ -4402,7 +4540,7 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, const isc_sockaddr_t *client,
|
|||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
event->result = DNS_R_SERVFAIL;
|
||||
event->qtype = fctx->fulltype;
|
||||
event->qtype = fctx->type;
|
||||
event->db = NULL;
|
||||
event->node = NULL;
|
||||
event->rdataset = rdataset;
|
||||
|
|
@ -4453,7 +4591,6 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
isc_result_t result;
|
||||
isc_result_t iresult;
|
||||
isc_interval_t interval;
|
||||
dns_fixedname_t fixed;
|
||||
unsigned int findoptions = 0;
|
||||
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
|
||||
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
||||
|
|
@ -4498,15 +4635,15 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
result = dns_name_dup(name, mctx, &fctx->name);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_info;
|
||||
dns_name_init(&fctx->fullname, NULL);
|
||||
result = dns_name_dup(name, mctx, &fctx->fullname);
|
||||
dns_name_init(&fctx->qminname, NULL);
|
||||
result = dns_name_dup(name, mctx, &fctx->qminname);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_name;
|
||||
goto cleanup_qminname;
|
||||
dns_name_init(&fctx->domain, NULL);
|
||||
dns_rdataset_init(&fctx->nameservers);
|
||||
|
||||
fctx->fulltype = type;
|
||||
fctx->type = type;
|
||||
fctx->qmintype = type;
|
||||
fctx->options = options;
|
||||
/*
|
||||
* Note! We do not attach to the task. We are relying on the
|
||||
|
|
@ -4524,7 +4661,9 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
fctx->minimized = false;
|
||||
fctx->ip6arpaskip = false;
|
||||
fctx->qmin_labels = 1;
|
||||
fctx->qmin_steps = 0;
|
||||
fctx->qminfetch = NULL;
|
||||
dns_rdataset_init(&fctx->qminrrset);
|
||||
dns_name_init(&fctx->qmindcname, NULL);
|
||||
isc_stdtime_get(&fctx->now);
|
||||
ISC_LIST_INIT(fctx->queries);
|
||||
ISC_LIST_INIT(fctx->finds);
|
||||
|
|
@ -4576,6 +4715,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
|
||||
if (domain == NULL) {
|
||||
dns_forwarders_t *forwarders = NULL;
|
||||
dns_fixedname_t fixed;
|
||||
unsigned int labels;
|
||||
const dns_name_t *fwdname = name;
|
||||
dns_name_t suffix;
|
||||
|
|
@ -4602,6 +4742,9 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
fctx->fwdpolicy = forwarders->fwdpolicy;
|
||||
|
||||
if (fctx->fwdpolicy != dns_fwdpolicy_only) {
|
||||
dns_fixedname_t dcfixed;
|
||||
dns_name_t *dcname;
|
||||
dcname = dns_fixedname_initname(&dcfixed);
|
||||
/*
|
||||
* The caller didn't supply a query domain and
|
||||
* nameservers, and we're not in forward-only mode,
|
||||
|
|
@ -4610,17 +4753,22 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
if (dns_rdatatype_atparent(fctx->type))
|
||||
findoptions |= DNS_DBFIND_NOEXACT;
|
||||
result = dns_view_findzonecut(res->view, name, fname,
|
||||
0, findoptions, true,
|
||||
true,
|
||||
dcname, fctx->now,
|
||||
findoptions, true, true,
|
||||
&fctx->nameservers,
|
||||
NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_nameservers;
|
||||
}
|
||||
|
||||
result = dns_name_dup(fname, mctx, &fctx->domain);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_nameservers;
|
||||
|
||||
}
|
||||
result = dns_name_dup(dcname, mctx, &fctx->qmindcname);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_domain;
|
||||
}
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = true;
|
||||
} else {
|
||||
|
|
@ -4628,13 +4776,27 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
* We're in forward-only mode. Set the query domain.
|
||||
*/
|
||||
result = dns_name_dup(fname, mctx, &fctx->domain);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_fullname;
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_name;
|
||||
}
|
||||
result = dns_name_dup(fname, mctx, &fctx->qmindcname);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_domain;
|
||||
}
|
||||
/*
|
||||
* Disable query minimization
|
||||
*/
|
||||
options &= ~DNS_FETCHOPT_QMINIMIZE;
|
||||
}
|
||||
} else {
|
||||
result = dns_name_dup(domain, mctx, &fctx->domain);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_fullname;
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_name;
|
||||
}
|
||||
result = dns_name_dup(domain, mctx, &fctx->qmindcname);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_domain;
|
||||
}
|
||||
dns_rdataset_clone(nameservers, &fctx->nameservers);
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = true;
|
||||
|
|
@ -4754,17 +4916,19 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
|||
cleanup_domain:
|
||||
if (dns_name_countlabels(&fctx->domain) > 0)
|
||||
dns_name_free(&fctx->domain, mctx);
|
||||
if (dns_name_countlabels(&fctx->qmindcname) > 0)
|
||||
dns_name_free(&fctx->qmindcname, mctx);
|
||||
|
||||
cleanup_nameservers:
|
||||
if (dns_rdataset_isassociated(&fctx->nameservers))
|
||||
dns_rdataset_disassociate(&fctx->nameservers);
|
||||
|
||||
cleanup_fullname:
|
||||
dns_name_free(&fctx->fullname, mctx);
|
||||
|
||||
cleanup_name:
|
||||
dns_name_free(&fctx->name, mctx);
|
||||
|
||||
cleanup_qminname:
|
||||
dns_name_free(&fctx->qminname, mctx);
|
||||
|
||||
cleanup_info:
|
||||
isc_mem_free(mctx, fctx->info);
|
||||
|
||||
|
|
@ -6469,10 +6633,13 @@ check_related(void *arg, const dns_name_t *addname, dns_rdatatype_t type) {
|
|||
#ifndef CHECK_FOR_GLUE_IN_ANSWER
|
||||
#define CHECK_FOR_GLUE_IN_ANSWER 0
|
||||
#endif
|
||||
|
||||
#if CHECK_FOR_GLUE_IN_ANSWER
|
||||
static isc_result_t
|
||||
check_answer(void *arg, const dns_name_t *addname, dns_rdatatype_t type) {
|
||||
return (check_section(arg, addname, type, DNS_SECTION_ANSWER));
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
|
||||
|
|
@ -7768,12 +7935,7 @@ rctx_answer(respctx_t *rctx) {
|
|||
fetchctx_t *fctx = rctx->fctx;
|
||||
resquery_t *query = rctx->query;
|
||||
|
||||
if (fctx->minimized) {
|
||||
result = rctx_answer_minimized(rctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
FCTXTRACE3("rctx_answer_minimized", result);
|
||||
}
|
||||
} else if ((fctx->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0 ||
|
||||
if ((fctx->rmessage->flags & DNS_MESSAGEFLAG_AA) != 0 ||
|
||||
ISFORWARDER(query->addrinfo))
|
||||
{
|
||||
result = rctx_answer_positive(rctx);
|
||||
|
|
@ -8478,19 +8640,6 @@ rctx_answer_none(respctx_t *rctx) {
|
|||
} else {
|
||||
log_formerr(fctx, "invalid response");
|
||||
}
|
||||
/*
|
||||
* If we're minimizing in relaxed mode, retry with full name,
|
||||
* just to be safe. The error will be logged.
|
||||
*/
|
||||
if (fctx->minimized &&
|
||||
(fctx->options & DNS_FETCHOPT_QMIN_STRICT) == 0) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
|
||||
"disabling qname minimization for '%s' "
|
||||
"due to formerr", fctx->info);
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
return (rctx_answer_minimized(rctx));
|
||||
}
|
||||
return (DNS_R_FORMERR);
|
||||
}
|
||||
|
||||
|
|
@ -8512,21 +8661,6 @@ rctx_answer_none(respctx_t *rctx) {
|
|||
return (rctx->result);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're doing qname minimization this is an empty non-terminal, add
|
||||
* the next label to query and restart it.
|
||||
*/
|
||||
if (fctx->minimized && fctx->rmessage->rcode == dns_rcode_noerror) {
|
||||
return (rctx_answer_minimized(rctx));
|
||||
}
|
||||
/*
|
||||
* Workaround for broken servers in relaxed mode - if we hit an
|
||||
* NXDOMAIN we go straight to the full query.
|
||||
*/
|
||||
if (fctx->minimized && !(fctx->options & DNS_FETCHOPT_QMIN_STRICT)) {
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
return (rctx_answer_minimized(rctx));
|
||||
}
|
||||
/*
|
||||
* Since we're not doing a referral, we don't want to cache any
|
||||
* NS RRs we may have found.
|
||||
|
|
@ -8894,10 +9028,6 @@ rctx_referral(respctx_t *rctx) {
|
|||
check_answer, fctx);
|
||||
}
|
||||
#endif
|
||||
if (fctx->minimized) {
|
||||
(void)dns_rdataset_additionaldata(rctx->ns_rdataset,
|
||||
check_answer, fctx);
|
||||
}
|
||||
fctx->attributes &= ~FCTX_ATTR_GLUING;
|
||||
|
||||
/*
|
||||
|
|
@ -8943,39 +9073,6 @@ rctx_referral(respctx_t *rctx) {
|
|||
log_ns_ttl(fctx, "DELEGATION");
|
||||
rctx->result = DNS_R_DELEGATION;
|
||||
|
||||
rctx_follow_referral(rctx);
|
||||
if (rctx->fctx->minimized) {
|
||||
/*
|
||||
* Reset the value
|
||||
*/
|
||||
fctx->qmin_labels = 1;
|
||||
fctx_minimize_qname(rctx->fctx);
|
||||
}
|
||||
return (ISC_R_COMPLETE);
|
||||
}
|
||||
|
||||
/*
|
||||
* rctx_answer_minimized():
|
||||
* Handles a positive response to a qname-minimized query.
|
||||
*/
|
||||
static isc_result_t
|
||||
rctx_answer_minimized(respctx_t *rctx) {
|
||||
fetchctx_t *fctx = rctx->fctx;
|
||||
|
||||
FCTXTRACE("rctx_answer_minimized");
|
||||
if (dns_rdataset_isassociated(&fctx->nameservers)) {
|
||||
dns_rdataset_disassociate(&fctx->nameservers);
|
||||
}
|
||||
rctx->result = DNS_R_DELEGATION;
|
||||
rctx_follow_referral(rctx);
|
||||
fctx->qmin_labels++;
|
||||
fctx_minimize_qname(rctx->fctx);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
rctx_follow_referral(respctx_t *rctx) {
|
||||
/*
|
||||
* Reinitialize 'rctx' to prepare for following the delegation:
|
||||
* set the get_nameservers and next_server flags appropriately and
|
||||
|
|
@ -8992,6 +9089,8 @@ rctx_follow_referral(respctx_t *rctx) {
|
|||
rctx->fctx->neterr = 0;
|
||||
rctx->fctx->badresp = 0;
|
||||
rctx->fctx->adberr = 0;
|
||||
|
||||
return (ISC_R_COMPLETE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -9058,11 +9157,12 @@ rctx_nextserver(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo,
|
|||
}
|
||||
|
||||
if (rctx->get_nameservers) {
|
||||
dns_fixedname_t foundname;
|
||||
dns_name_t *name, *fname;
|
||||
dns_fixedname_t foundname, founddc;
|
||||
dns_name_t *name, *fname, *dcname;
|
||||
unsigned int findoptions = 0;
|
||||
|
||||
fname = dns_fixedname_initname(&foundname);
|
||||
dcname = dns_fixedname_initname(&founddc);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||
|
|
@ -9075,11 +9175,9 @@ rctx_nextserver(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo,
|
|||
} else {
|
||||
name = &fctx->domain;
|
||||
}
|
||||
result = dns_view_findzonecut(fctx->res->view,
|
||||
name, fname,
|
||||
fctx->now, findoptions,
|
||||
true, true,
|
||||
&fctx->nameservers,
|
||||
result = dns_view_findzonecut(fctx->res->view, name, fname,
|
||||
dcname, fctx->now, findoptions,
|
||||
true, true, &fctx->nameservers,
|
||||
NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
FCTXTRACE("couldn't find a zonecut");
|
||||
|
|
@ -9096,6 +9194,7 @@ rctx_nextserver(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo,
|
|||
}
|
||||
|
||||
fcount_decr(fctx);
|
||||
|
||||
dns_name_free(&fctx->domain, fctx->mctx);
|
||||
dns_name_init(&fctx->domain, NULL);
|
||||
result = dns_name_dup(fname, fctx->mctx, &fctx->domain);
|
||||
|
|
@ -9103,6 +9202,14 @@ rctx_nextserver(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo,
|
|||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||
return;
|
||||
}
|
||||
dns_name_free(&fctx->qmindcname, fctx->mctx);
|
||||
dns_name_init(&fctx->qmindcname, NULL);
|
||||
result = dns_name_dup(dcname, fctx->mctx, &fctx->qmindcname);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
result = fcount_incr(fctx, true);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||
|
|
@ -9367,20 +9474,8 @@ rctx_badserver(respctx_t *rctx, isc_result_t result) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're minimizing in relaxed mode try to disable minimization.
|
||||
*/
|
||||
if (fctx->minimized &&
|
||||
(fctx->options & DNS_FETCHOPT_QMIN_STRICT) == 0)
|
||||
{
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
|
||||
"disabling qname minimization for '%s'"
|
||||
" due to bad server", fctx->info);
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
result = rctx_answer_minimized(rctx);
|
||||
} else if ((fctx->rmessage->rcode == dns_rcode_formerr) &&
|
||||
(rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0)
|
||||
if ((fctx->rmessage->rcode == dns_rcode_formerr) &&
|
||||
(rctx->retryopts & DNS_FETCHOPT_NOEDNS0) == 0)
|
||||
{
|
||||
/*
|
||||
* It's very likely they don't like EDNS0.
|
||||
|
|
@ -10189,9 +10284,9 @@ fctx_match(fetchctx_t *fctx, const dns_name_t *name, dns_rdatatype_t type,
|
|||
ISC_LIST_EMPTY(fctx->events))
|
||||
return (false);
|
||||
|
||||
if (fctx->fulltype != type || fctx->options != options)
|
||||
if (fctx->type != type || fctx->options != options)
|
||||
return (false);
|
||||
return (dns_name_equal(&fctx->fullname, name));
|
||||
return (dns_name_equal(&fctx->name, name));
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -10217,16 +10312,17 @@ log_fetch(const dns_name_t *name, dns_rdatatype_t type) {
|
|||
|
||||
void
|
||||
fctx_minimize_qname(fetchctx_t *fctx) {
|
||||
/*
|
||||
* XXXWPK TODO we should update info to show that this query
|
||||
* is minimized
|
||||
*/
|
||||
unsigned int dlabels, nlabels;
|
||||
|
||||
dlabels = dns_name_countlabels(&fctx->domain);
|
||||
nlabels = dns_name_countlabels(&fctx->fullname);
|
||||
dns_name_free(&fctx->name, fctx->mctx);
|
||||
dns_name_init(&fctx->name, NULL);
|
||||
dlabels = dns_name_countlabels(&fctx->qmindcname);
|
||||
nlabels = dns_name_countlabels(&fctx->name);
|
||||
dns_name_free(&fctx->qminname, fctx->mctx);
|
||||
dns_name_init(&fctx->qminname, NULL);
|
||||
if (dlabels > fctx->qmin_labels) {
|
||||
fctx->qmin_labels = dlabels+1;
|
||||
} else {
|
||||
fctx->qmin_labels++;
|
||||
}
|
||||
if (fctx->ip6arpaskip) {
|
||||
/*
|
||||
* For ip6.arpa we want to skip some of the labels, with
|
||||
|
|
@ -10235,43 +10331,39 @@ fctx_minimize_qname(fetchctx_t *fctx) {
|
|||
* 7 11 15 17 19 35
|
||||
* We fix fctx->qmin_labels to point to the nearest boundary
|
||||
*/
|
||||
if (dlabels + fctx->qmin_labels < 7) {
|
||||
fctx->qmin_labels = 7 - dlabels;
|
||||
} else if (dlabels + fctx->qmin_labels < 11) {
|
||||
fctx->qmin_labels = 11 - dlabels;
|
||||
} else if (dlabels + fctx->qmin_labels < 15) {
|
||||
fctx->qmin_labels = 15 - dlabels;
|
||||
} else if (dlabels + fctx->qmin_labels < 17) {
|
||||
fctx->qmin_labels = 17 - dlabels;
|
||||
} else if (dlabels + fctx->qmin_labels < 19) {
|
||||
fctx->qmin_labels = 19 - dlabels;
|
||||
} else if (dlabels + fctx->qmin_labels > 19) {
|
||||
fctx->qmin_labels = 35 - dlabels;
|
||||
if (fctx->qmin_labels < 7) {
|
||||
fctx->qmin_labels = 7;
|
||||
} else if (fctx->qmin_labels < 11) {
|
||||
fctx->qmin_labels = 11;
|
||||
} else if (fctx->qmin_labels < 15) {
|
||||
fctx->qmin_labels = 15;
|
||||
} else if (fctx->qmin_labels < 17) {
|
||||
fctx->qmin_labels = 17;
|
||||
} else if (fctx->qmin_labels < 19) {
|
||||
fctx->qmin_labels = 19;
|
||||
} else if (fctx->qmin_labels > 19) {
|
||||
fctx->qmin_labels = 35;
|
||||
}
|
||||
} else if (dlabels + fctx->qmin_labels > DNS_QMIN_MAXLABELS) {
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
} else if (fctx->qmin_labels > DNS_QMIN_MAX_NO_DELEGATION) {
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
} else if (fctx->qmin_labels > DNS_QMIN_MAXLABELS) {
|
||||
fctx->qmin_labels = DNS_MAX_LABELS + 1;
|
||||
}
|
||||
if (dlabels + fctx->qmin_labels < nlabels) {
|
||||
if (fctx->qmin_labels < nlabels) {
|
||||
/*
|
||||
* We want to query for
|
||||
* [qmin_labels from fctx->fullname] + fctx->domain
|
||||
* We want to query for qmin_labels from fctx->name
|
||||
*/
|
||||
dns_fixedname_t fname;
|
||||
dns_fixedname_init(&fname);
|
||||
dns_name_split(&fctx->fullname,
|
||||
dlabels + fctx->qmin_labels,
|
||||
dns_name_split(&fctx->name,
|
||||
fctx->qmin_labels,
|
||||
NULL, dns_fixedname_name(&fname));
|
||||
dns_name_dup(dns_fixedname_name(&fname), fctx->mctx,
|
||||
&fctx->name);
|
||||
fctx->type = dns_rdatatype_ns;
|
||||
&fctx->qminname);
|
||||
fctx->qmintype = dns_rdatatype_ns;
|
||||
fctx->minimized = true;
|
||||
fctx->qmin_steps++;
|
||||
} else {
|
||||
/* Minimization is done, we'll ask for whole qname */
|
||||
fctx->type = fctx->fulltype;
|
||||
dns_name_dup(&fctx->fullname, fctx->mctx, &fctx->name);
|
||||
fctx->qmintype = fctx->type;
|
||||
dns_name_dup(&fctx->name, fctx->mctx, &fctx->qminname);
|
||||
fctx->minimized = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -10540,8 +10632,7 @@ dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx,
|
|||
"%06" PRIu64 ": %s/%s "
|
||||
"[domain:%s,referral:%u,restart:%u,qrysent:%u,"
|
||||
"timeout:%u,lame:%u,quota:%u,neterr:%u,"
|
||||
"badresp:%u,adberr:%u,findfail:%u,valfail:%u,"
|
||||
"qminsteps:%u]",
|
||||
"badresp:%u,adberr:%u,findfail:%u,valfail:%u]",
|
||||
__FILE__, fctx->exitline, fctx->info,
|
||||
fctx->duration / US_PER_SEC,
|
||||
fctx->duration % US_PER_SEC,
|
||||
|
|
@ -10551,8 +10642,7 @@ dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx,
|
|||
fctx->querysent, fctx->timeouts,
|
||||
fctx->lamecount, fctx->quotacount,
|
||||
fctx->neterr, fctx->badresp, fctx->adberr,
|
||||
fctx->findfail, fctx->valfail,
|
||||
fctx->qmin_steps);
|
||||
fctx->findfail, fctx->valfail);
|
||||
fctx->logged = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -986,7 +986,8 @@ findext(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
|
|||
static isc_result_t
|
||||
findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
dns_name_t *dcname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
UNUSED(db);
|
||||
UNUSED(name);
|
||||
|
|
@ -994,6 +995,7 @@ findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
UNUSED(now);
|
||||
UNUSED(nodep);
|
||||
UNUSED(foundname);
|
||||
UNUSED(dcname);
|
||||
UNUSED(rdataset);
|
||||
UNUSED(sigrdataset);
|
||||
|
||||
|
|
|
|||
|
|
@ -715,7 +715,8 @@ findnode(dns_db_t *db, const dns_name_t *name, bool create,
|
|||
static isc_result_t
|
||||
findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
dns_name_t *dcname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
UNUSED(db);
|
||||
UNUSED(name);
|
||||
|
|
@ -723,6 +724,7 @@ findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
|||
UNUSED(now);
|
||||
UNUSED(nodep);
|
||||
UNUSED(foundname);
|
||||
UNUSED(dcname);
|
||||
UNUSED(rdataset);
|
||||
UNUSED(sigrdataset);
|
||||
|
||||
|
|
|
|||
|
|
@ -3400,7 +3400,7 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool resume)
|
|||
*/
|
||||
if (result == DNS_R_NXRRSET &&
|
||||
!dns_rdataset_isassociated(&val->frdataset) &&
|
||||
dns_view_findzonecut(val->view, tname, found,
|
||||
dns_view_findzonecut(val->view, tname, found, NULL,
|
||||
0, 0, false, false,
|
||||
NULL, NULL) == ISC_R_SUCCESS &&
|
||||
dns_name_equal(tname, found)) {
|
||||
|
|
|
|||
|
|
@ -1254,7 +1254,7 @@ dns_view_simplefind(dns_view_t *view, const dns_name_t *name,
|
|||
|
||||
isc_result_t
|
||||
dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
||||
dns_name_t *fname, isc_stdtime_t now,
|
||||
dns_name_t *fname, dns_name_t *dcname, isc_stdtime_t now,
|
||||
unsigned int options, bool use_hints,
|
||||
bool use_cache, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
|
|
@ -1357,7 +1357,8 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
|||
}
|
||||
} else {
|
||||
result = dns_db_findzonecut(db, name, options, now, NULL,
|
||||
fname, rdataset, sigrdataset);
|
||||
fname, dcname, rdataset,
|
||||
sigrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (zfname != NULL &&
|
||||
(!dns_name_issubdomain(fname, zfname) ||
|
||||
|
|
@ -1401,6 +1402,11 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
|||
result = dns_name_copy(zfname, fname, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
if (dcname != NULL) {
|
||||
result = dns_name_copy(zfname, dcname, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
dns_rdataset_clone(&zrdataset, rdataset);
|
||||
if (sigrdataset != NULL &&
|
||||
dns_rdataset_isassociated(&zrdataset))
|
||||
|
|
@ -1420,6 +1426,8 @@ dns_view_findzonecut(dns_view_t *view, const dns_name_t *name,
|
|||
if (dns_rdataset_isassociated(rdataset))
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
result = ISC_R_NOTFOUND;
|
||||
} else if (dcname != NULL) {
|
||||
dns_name_copy(fname, dcname, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10113,7 +10113,7 @@ query_addbestns(query_ctx_t *qctx) {
|
|||
} else {
|
||||
result = dns_db_findzonecut(db, client->query.qname,
|
||||
client->query.dboptions,
|
||||
client->now, &node, fname,
|
||||
client->now, &node, fname, NULL,
|
||||
rdataset, sigrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (zfname != NULL &&
|
||||
|
|
|
|||
Loading…
Reference in a new issue