mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +00:00
3593. [func] Update EDNS processing to better track remote server
capabilities. [RT #30655]
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -1,3 +1,6 @@
|
|||||||
|
3593. [func] Update EDNS processing to better track remote server
|
||||||
|
capabilities. [RT #30655]
|
||||||
|
|
||||||
3592. [doc] Moved documentation of rndc command options to the
|
3592. [doc] Moved documentation of rndc command options to the
|
||||||
rndc man page. [RT #33506]
|
rndc man page. [RT #33506]
|
||||||
|
|
||||||
|
31
EDNS-9.10
Normal file
31
EDNS-9.10
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
EDNS in BIND 9.10
|
||||||
|
|
||||||
|
The EDNS code in BIND 9.10 records successful plain and EDNS query
|
||||||
|
counts as well at timeouts for plain DNS and EDNS queries at various
|
||||||
|
EDNS buffer sizes: 4096, 1432, 1232 and 512 for each server named
|
||||||
|
talks to. A EDNS timeout for a lower buffer size is also counted
|
||||||
|
against higher buffer sizes. These are held in 8 bit counters and
|
||||||
|
are shifted on overflow of any counter. This will result in false
|
||||||
|
positives due to transitory network problems to be removed from the
|
||||||
|
history.
|
||||||
|
|
||||||
|
The buffer sizes of 1432 and 1232 are choosen to allow for a IPv4/IPv6
|
||||||
|
encapsulated UDP message to be sent without fragmentation at Ethernet
|
||||||
|
and IPv6 network mimimum MTU sizes.
|
||||||
|
|
||||||
|
Named also records the largest successful EDNS response size seen.
|
||||||
|
|
||||||
|
When talking to a new server named will send a EDNS query advertising
|
||||||
|
a 512 byte UDP buffer. This is the most conservative EDNS message
|
||||||
|
that can be sent. If this results in a response with TC=1 being
|
||||||
|
sent a larger EDNS buffer size will be used rather than a immediate
|
||||||
|
fallback to TCP.
|
||||||
|
|
||||||
|
If there are too many timeouts to EDNS queries without a successful EDNS
|
||||||
|
query and with successful plain DNS queries named will fallback to using
|
||||||
|
plain DNS when taking to a server. Named will periodically send a EDNS
|
||||||
|
query to see if the server now supports EDNS.
|
||||||
|
|
||||||
|
When talking to a server using EDNS named will choose a EDNS buffer size
|
||||||
|
based on the history of EDNS timeouts at various advertised sizes.
|
@@ -419,7 +419,7 @@ parse_command_line(int argc, char *argv[]) {
|
|||||||
|
|
||||||
isc_commandline_errprint = ISC_FALSE;
|
isc_commandline_errprint = ISC_FALSE;
|
||||||
while ((ch = isc_commandline_parse(argc, argv,
|
while ((ch = isc_commandline_parse(argc, argv,
|
||||||
"46c:C:d:E:fFgi:lm:n:N:p:P:"
|
"46c:C:d:D:E:fFgi:lm:n:N:p:P:"
|
||||||
"sS:t:T:U:u:vVx:")) != -1) {
|
"sS:t:T:U:u:vVx:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '4':
|
case '4':
|
||||||
@@ -455,6 +455,9 @@ parse_command_line(int argc, char *argv[]) {
|
|||||||
ns_g_debuglevel = parse_int(isc_commandline_argument,
|
ns_g_debuglevel = parse_int(isc_commandline_argument,
|
||||||
"debug level");
|
"debug level");
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
/* Descriptive comment for 'ps'. */
|
||||||
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
ns_g_engine = isc_commandline_argument;
|
ns_g_engine = isc_commandline_argument;
|
||||||
break;
|
break;
|
||||||
|
@@ -62,6 +62,7 @@
|
|||||||
<arg><option>-6</option></arg>
|
<arg><option>-6</option></arg>
|
||||||
<arg><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
|
<arg><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
|
||||||
<arg><option>-d <replaceable class="parameter">debug-level</replaceable></option></arg>
|
<arg><option>-d <replaceable class="parameter">debug-level</replaceable></option></arg>
|
||||||
|
<arg><option>-D <replaceable class="parameter">string</replaceable></option></arg>
|
||||||
<arg><option>-E <replaceable class="parameter">engine-name</replaceable></option></arg>
|
<arg><option>-E <replaceable class="parameter">engine-name</replaceable></option></arg>
|
||||||
<arg><option>-f</option></arg>
|
<arg><option>-f</option></arg>
|
||||||
<arg><option>-g</option></arg>
|
<arg><option>-g</option></arg>
|
||||||
@@ -149,6 +150,18 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>-D <replaceable class="parameter">string</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specifies a string that is used to identify a instance of
|
||||||
|
<command>named</command> in a process listing. The contents
|
||||||
|
of <replaceable class="parameter">string</replaceable> are
|
||||||
|
not examined.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-E <replaceable class="parameter">engine-name</replaceable></term>
|
<term>-E <replaceable class="parameter">engine-name</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
15
bin/tests/bigtest/README
Normal file
15
bin/tests/bigtest/README
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
bash buildzones.sh < zones # creates setup, run, servers/* master/*
|
||||||
|
# named.conf
|
||||||
|
sudo sh setup # configure interfaces
|
||||||
|
sh run # setup
|
||||||
|
|
||||||
|
../named/named [-g] -c named.conf
|
||||||
|
|
||||||
|
sh tests.sh < zones
|
||||||
|
|
||||||
|
sudo sh teardown # teardown interfaces
|
||||||
|
|
||||||
|
The test server can controlled with
|
||||||
|
|
||||||
|
rndc -k rndc.key -s 127.127.0.0 -p 5300
|
257
bin/tests/bigtest/buildzones.sh
Normal file
257
bin/tests/bigtest/buildzones.sh
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
TOP=$( (cd ../../.. && pwd) )
|
||||||
|
|
||||||
|
addr=127.127.0.0
|
||||||
|
ttl=300
|
||||||
|
named=${TOP}/bin/named/named
|
||||||
|
keygen=${TOP}/bin/dnssec/dnssec-keygen
|
||||||
|
dsfromkey=${TOP}/bin/dnssec/dnssec-dsfromkey
|
||||||
|
|
||||||
|
nextaddr() {
|
||||||
|
OLDIF="$IFS"
|
||||||
|
IFS="${IFS}."
|
||||||
|
set $1
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
_a=$1 _b=$2 _c=$3 _d=$4
|
||||||
|
_d=$(($_d + 1))
|
||||||
|
case $_d in
|
||||||
|
256) _c=$(($_c + 1)); _d=0;;
|
||||||
|
esac
|
||||||
|
case $_c in
|
||||||
|
256) _b=$(($_b + 1)); _c=0;;
|
||||||
|
esac
|
||||||
|
echo $_a.$_b.$_c.$_d
|
||||||
|
}
|
||||||
|
|
||||||
|
parent() {
|
||||||
|
OLDIF="$IFS"
|
||||||
|
IFS="${IFS}."
|
||||||
|
set $1
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
shift
|
||||||
|
while [ $# -ne 0 ]
|
||||||
|
do
|
||||||
|
printf %s ${1}
|
||||||
|
shift
|
||||||
|
printf %s ${1:+.}
|
||||||
|
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
blackhole() {
|
||||||
|
echo 'options {'
|
||||||
|
echo ' port 5300;'
|
||||||
|
echo " listen-on { $1; };"
|
||||||
|
echo " query-source $1;"
|
||||||
|
echo " notify-source $1;"
|
||||||
|
echo " transfer-source $1;"
|
||||||
|
echo ' key-directory "keys";'
|
||||||
|
echo " recursion ${2:-no};"
|
||||||
|
echo ' pid-file "pids/'"${addr}"'.pid";'
|
||||||
|
echo ' blackhole { 127.127.0.0; };'
|
||||||
|
echo '};'
|
||||||
|
}
|
||||||
|
|
||||||
|
refuse() {
|
||||||
|
echo 'options {'
|
||||||
|
echo ' port 5300;'
|
||||||
|
echo " listen-on { $1; };"
|
||||||
|
echo " query-source $1;"
|
||||||
|
echo " notify-source $1;"
|
||||||
|
echo " transfer-source $1;"
|
||||||
|
echo ' key-directory "keys";'
|
||||||
|
echo " recursion ${2:-no};"
|
||||||
|
echo ' pid-file "pids/'"${addr}"'.pid";'
|
||||||
|
echo ' allow-query { !127.127.0.0; any; };'
|
||||||
|
echo '};'
|
||||||
|
}
|
||||||
|
|
||||||
|
options() {
|
||||||
|
echo 'options {'
|
||||||
|
echo ' port 5300;'
|
||||||
|
echo " listen-on { $1; };"
|
||||||
|
echo " query-source $1;"
|
||||||
|
echo " notify-source $1;"
|
||||||
|
echo " transfer-source $1;"
|
||||||
|
echo ' key-directory "keys";'
|
||||||
|
echo " recursion ${2:-no};"
|
||||||
|
echo ' pid-file "pids/'"${addr}"'.pid";'
|
||||||
|
echo '};'
|
||||||
|
}
|
||||||
|
|
||||||
|
controls() {
|
||||||
|
echo 'include "rndc.key";'
|
||||||
|
echo "controls { inet $addr port 9953 allow { any; } keys { "rndc-key"; }; };"
|
||||||
|
}
|
||||||
|
|
||||||
|
delay() {
|
||||||
|
_s=$1
|
||||||
|
OLDIF="$IFS"
|
||||||
|
IFS="${IFS}/"
|
||||||
|
set ${2:-.}
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
.) _d=;;
|
||||||
|
*) _d=$1;;
|
||||||
|
esac
|
||||||
|
case $_s in
|
||||||
|
1) echo -T delay=${_d:-100};;
|
||||||
|
2) echo -T delay=${2:-50};;
|
||||||
|
3) echo -T delay=${3:-150};;
|
||||||
|
4) echo -T delay=${4:-250};;
|
||||||
|
5) echo -T delay=${5:-125};;
|
||||||
|
6) echo -T delay=${6:-25};;
|
||||||
|
7) echo -T delay=${7:-75};;
|
||||||
|
8) echo -T delay=${8:-125};;
|
||||||
|
9) echo -T delay=${9:-10};;
|
||||||
|
10) echo -T delay=${10:-40};;
|
||||||
|
11) echo -T delay=${11:-80};;
|
||||||
|
12) echo -T delay=${12:-90};;
|
||||||
|
*) echo -T delay=50;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
trusted-keys () {
|
||||||
|
awk '$3 == "DNSKEY" {
|
||||||
|
b = ""; for (i=7; i <= NF; i++) { b = b $i; };
|
||||||
|
print "trusted-keys { \""$1"\"",$4,$5,$6,"\""b"\"; };" };'
|
||||||
|
}
|
||||||
|
|
||||||
|
signed-zone () {
|
||||||
|
echo "zone "'"'"${1:-.}"'"'" {"
|
||||||
|
echo " type master;"
|
||||||
|
echo " file "'"'"master/${2}.db"'"'";"
|
||||||
|
echo " auto-dnssec maintain;"
|
||||||
|
echo " allow-update { any; };"
|
||||||
|
echo "};"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned-zone () {
|
||||||
|
echo "zone "'"'"${1:-.}"'"'" {"
|
||||||
|
echo " type master;"
|
||||||
|
echo " file "'"'"master/${2}.db"'"'";"
|
||||||
|
echo "};"
|
||||||
|
}
|
||||||
|
|
||||||
|
slave-zone () {
|
||||||
|
echo "zone "'"'"${zone:-.}"'"'" {"
|
||||||
|
echo " type slave;"
|
||||||
|
echo " masters { ${master}; };"
|
||||||
|
echo "};"
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf servers master keys setup teardown run
|
||||||
|
mkdir -p servers
|
||||||
|
mkdir -p master
|
||||||
|
mkdir -p keys
|
||||||
|
|
||||||
|
echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup
|
||||||
|
echo "ifconfig lo0 $addr -alias" >> teardown
|
||||||
|
controls $addr > named.conf
|
||||||
|
options $addr yes >> named.conf
|
||||||
|
echo 'zone "." { type hint; file "master/hint.db"; };' >> named.conf
|
||||||
|
|
||||||
|
while read zone servers nsfmt signed delay blackhole refuse flags
|
||||||
|
do
|
||||||
|
i=1
|
||||||
|
case "${zone}" in
|
||||||
|
.) file=root zone=;;
|
||||||
|
*) file="$zone";;
|
||||||
|
esac
|
||||||
|
if [ "${zone}" != "" ] ; then
|
||||||
|
p=$(parent $zone)
|
||||||
|
case "${p}" in
|
||||||
|
"") p=root;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
p=hint
|
||||||
|
fi
|
||||||
|
#echo "zone='${zone}' parent='${p}'"
|
||||||
|
addr=$(nextaddr $addr)
|
||||||
|
ns=$(printf "$nsfmt" ${i} "${zone}")
|
||||||
|
d=$(delay $i ${delay:-.})
|
||||||
|
|
||||||
|
echo "${zone}. ${ttl} soa ${ns}. hostmaster.${zone}${zone:+.} 1 3600 1200 604800 1200" >> master/${file}.db
|
||||||
|
echo "${zone}. ${ttl} ns ${ns}." >> master/${file}.db
|
||||||
|
echo "${ns}. ${ttl} a ${addr}" >> master/${file}.db
|
||||||
|
echo "${zone}. ${ttl} ns ${ns}." >> master/${p}.db
|
||||||
|
echo "${ns}. ${ttl} a ${addr}" >> master/${p}.db
|
||||||
|
if [ $signed = "S" ]; then
|
||||||
|
kskkey=`${keygen} -K keys -f KSK ${zone:-.}`
|
||||||
|
zskkey=`${keygen} -K keys ${zone:-.}`
|
||||||
|
if [ "${zone}" != "" ] ; then
|
||||||
|
${dsfromkey} -T ${ttl} keys/${kskkey}.key >> master/${p}.db
|
||||||
|
else
|
||||||
|
trusted-keys < keys/${kskkey}.key >> named.conf
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup
|
||||||
|
echo "ifconfig lo0 $addr -alias" >> teardown
|
||||||
|
echo "${named} -D bigtest -c servers/${addr}.conf $d $flags" >> run
|
||||||
|
options ${addr} > servers/${addr}.conf
|
||||||
|
case ${signed} in
|
||||||
|
S) signed-zone ${zone:-.} ${file} >> servers/${addr}.conf;;
|
||||||
|
P) unsigned-zone ${zone:-.} ${file} >> servers/${addr}.conf;;
|
||||||
|
*) echo ${signed}; exit 1;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# slave servers
|
||||||
|
while [ $i -lt $servers ]
|
||||||
|
do
|
||||||
|
master=$addr
|
||||||
|
i=$(($i + 1))
|
||||||
|
ns=$(printf "$nsfmt" ${i} "${zone}")
|
||||||
|
d=$(delay $i ${delay:-.})
|
||||||
|
addr=$(nextaddr $addr)
|
||||||
|
echo "${zone}. ${ttl} ns ${ns}." >> master/${file}.db
|
||||||
|
echo "${ns}. ${ttl} a ${addr}" >> master/${file}.db
|
||||||
|
echo "${zone}. ${ttl} ns ${ns}." >> master/${p}.db
|
||||||
|
echo "${ns}. ${ttl} a ${addr}" >> master/${p}.db
|
||||||
|
echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup
|
||||||
|
echo "ifconfig lo0 $addr -alias" >> teardown
|
||||||
|
echo "${named} -D bigtest -c servers/${addr}.conf $d $flags" >> run
|
||||||
|
if [ $i = ${refuse:-.} ]
|
||||||
|
then
|
||||||
|
refuse $addr > servers/${addr}.conf
|
||||||
|
elif [ $i = ${blackhole:-.} ]
|
||||||
|
then
|
||||||
|
blackhole $addr > servers/${addr}.conf
|
||||||
|
else
|
||||||
|
options $addr > servers/${addr}.conf
|
||||||
|
fi
|
||||||
|
slave-zone ${zone:-.} ${master} >> servers/${addr}.conf
|
||||||
|
done
|
||||||
|
if [ "${zone}" != "" ] ; then
|
||||||
|
echo "www.${zone}. ${ttl} a 127.0.0.1" >> master/${file}.db
|
||||||
|
echo "www.${zone}. ${ttl} aaaa ::1" >> master/${file}.db
|
||||||
|
echo "${zone}. ${ttl} mx 10 mail.${zone}." >> master/${file}.db
|
||||||
|
echo "mail.${zone}. ${ttl} a 127.0.0.1" >> master/${file}.db
|
||||||
|
echo "mail.${zone}. ${ttl} aaaa ::1" >> master/${file}.db
|
||||||
|
echo "*.big.${zone}. ${ttl} txt (" >> master/${file}.db
|
||||||
|
i=0
|
||||||
|
while [ $i -lt 150 ]
|
||||||
|
do
|
||||||
|
echo "1234567890" >> master/${file}.db
|
||||||
|
i=$(($i + 1))
|
||||||
|
done
|
||||||
|
echo ")" >> master/${file}.db
|
||||||
|
echo "*.medium.${zone}. ${ttl} txt (" >> master/${file}.db
|
||||||
|
i=0
|
||||||
|
while [ $i -lt 120 ]
|
||||||
|
do
|
||||||
|
echo "1234567890" >> master/${file}.db
|
||||||
|
i=$(($i + 1))
|
||||||
|
done
|
||||||
|
echo ")" >> master/${file}.db
|
||||||
|
echo "*.medium.${zone}. ${ttl} txt (" >> master/${file}.db
|
||||||
|
i=0
|
||||||
|
while [ $i -lt 120 ]
|
||||||
|
do
|
||||||
|
echo "1234567890" >> master/${file}.db
|
||||||
|
i=$(($i + 1))
|
||||||
|
done
|
||||||
|
echo ")" >> master/${file}.db
|
||||||
|
fi
|
||||||
|
done
|
5
bin/tests/bigtest/rndc.key
Normal file
5
bin/tests/bigtest/rndc.key
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
key "rndc-key" {
|
||||||
|
algorithm hmac-md5;
|
||||||
|
secret "xxxxxxxxxxxxxxxxxxxxHg==";
|
||||||
|
};
|
||||||
|
|
67
bin/tests/bigtest/tests.sh
Normal file
67
bin/tests/bigtest/tests.sh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
TOP=$( (cd ../../.. && pwd) )
|
||||||
|
dig=${TOP}/bin/dig/dig
|
||||||
|
|
||||||
|
cmd="${dig} -p 5300 @127.127.0.0 txt"
|
||||||
|
inner() {
|
||||||
|
zone=$1 i=$2 to=$3
|
||||||
|
x=$i
|
||||||
|
dout=dig$x.out
|
||||||
|
tout=time$x.out
|
||||||
|
while [ $i -lt $to ]
|
||||||
|
do
|
||||||
|
case $zone in
|
||||||
|
.) zone=;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
(time -p $cmd $i.${sub}$zone > $dout ) 2> $tout
|
||||||
|
s=`sed -n '/real/s/[^0-9]*\([0-9]*\)\..*/\1/p' $tout`
|
||||||
|
case $s in
|
||||||
|
0);;
|
||||||
|
1) t1=`expr ${t1:-0} + 1`;;
|
||||||
|
2) t2=`expr ${t2:-0} + 1`;;
|
||||||
|
3) t3=`expr ${t3:-0} + 1`;;
|
||||||
|
*) echo $i `grep real $tout`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
grep "status: \(NXDOMAIN\|NOERROR\)" $dout > /dev/null || {
|
||||||
|
echo $cmd $i.${sub}$zone
|
||||||
|
cat $dout
|
||||||
|
}
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
if test ${t1:-0} -ne 0 -o ${t2:-0} -ne 0 -o ${t3:-0} -ne 0
|
||||||
|
then
|
||||||
|
echo "$x timeouts: t1=${t1:-0} t2=${t2:-0} t3=${t3:-0}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
while read zone rest
|
||||||
|
do
|
||||||
|
for sub in "" medium. big.
|
||||||
|
do
|
||||||
|
case $zone in
|
||||||
|
.) echo doing ${sub:-.};;
|
||||||
|
*) echo doing $sub$zone;;
|
||||||
|
esac
|
||||||
|
( inner $zone 1 100) &
|
||||||
|
( inner $zone 101 200) &
|
||||||
|
( inner $zone 201 300) &
|
||||||
|
( inner $zone 301 400) &
|
||||||
|
( inner $zone 401 500) &
|
||||||
|
( inner $zone 501 600) &
|
||||||
|
( inner $zone 601 700) &
|
||||||
|
( inner $zone 701 800) &
|
||||||
|
( inner $zone 801 900) &
|
||||||
|
( inner $zone 901 1000) &
|
||||||
|
( inner $zone 1001 1100) &
|
||||||
|
( inner $zone 1101 1200) &
|
||||||
|
( inner $zone 1201 1300) &
|
||||||
|
( inner $zone 1301 1400) &
|
||||||
|
( inner $zone 1401 1500) &
|
||||||
|
( inner $zone 1501 1600) &
|
||||||
|
( inner $zone 1601 1700) &
|
||||||
|
wait
|
||||||
|
done
|
||||||
|
done
|
18
bin/tests/bigtest/zones
Normal file
18
bin/tests/bigtest/zones
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
noedns-1.tld 1 ns%u.%s P . x x -T noedns
|
||||||
|
dropedns-1.tld 1 ns%u.%s P . x x -T dropedns
|
||||||
|
maxudp512-1.tld 1 ns%u.%s S . x x -T maxudp=512
|
||||||
|
maxudp1460-1.tld 1 ns%u.%s S . x x -T maxudp=1460
|
||||||
|
plain-1.tld 1 ns%u.%s S . x x
|
||||||
|
noedns-3.tld 3 ns%u.%s P . 2 x -T noedns
|
||||||
|
dropedns-3.tld 3 ns%u.%s P . 2 x -T dropedns
|
||||||
|
maxudp512-3.tld 3 ns%u.%s S . x x -T maxudp=512
|
||||||
|
maxudp1460-3.tld 3 ns%u.%s S . x x -T maxudp=1460
|
||||||
|
plain-3.tld 3 ns%u.%s S . x 3
|
||||||
|
noedns-5.tld 5 ns%u.%s P . 3 x -T noedns
|
||||||
|
dropedns-5.tld 5 ns%u.%s P . x x -T dropedns
|
||||||
|
maxudp512-5.tld 5 ns%u.%s S . x x -T maxudp=512
|
||||||
|
maxudp1460-5.tld 5 ns%u.%s S . x x -T maxudp=1460
|
||||||
|
400ms-1.tld 5 ns%u.%s S 400/400/400/400/400 2 x
|
||||||
|
plain-5.tld 5 ns%u.%s S . x x
|
||||||
|
tld 12 ns%u.%s S . 5 8
|
||||||
|
. 12 ns%u.root-servers.nil%s S . x x
|
@@ -94,8 +94,8 @@ echo "I:reset and check that records are correctly cached initially"
|
|||||||
ret=0
|
ret=0
|
||||||
load_cache
|
load_cache
|
||||||
dump_cache
|
dump_cache
|
||||||
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l`
|
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | grep -w '\(TXT\|ANY\)'| wc -l`
|
||||||
[ $nrecords -eq 20 ] || ret=1
|
[ $nrecords -eq 17 ] || { ret=1; echo "I: found $nrecords records expected 17"; }
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
@@ -180,8 +180,8 @@ status=`expr $status + $ret`
|
|||||||
echo "I:check the number of cached records remaining"
|
echo "I:check the number of cached records remaining"
|
||||||
ret=0
|
ret=0
|
||||||
dump_cache
|
dump_cache
|
||||||
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l`
|
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | grep -w '\(TXT\|ANY\)' | wc -l`
|
||||||
[ $nrecords -eq 19 ] || ret=1
|
[ $nrecords -eq 17 ] || { ret=1; echo "I: found $nrecords records expected 17"; }
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
@@ -53,8 +53,8 @@ n=`expr $n + 1`
|
|||||||
# Entry should exist
|
# Entry should exist
|
||||||
echo "I: check that 'check-names response warn;' works ($n)"
|
echo "I: check that 'check-names response warn;' works ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG $DIGOPTS yy_yy.ignore.example. @10.53.0.1 a > dig.out.ns1.test$n || ret=1
|
$DIG $DIGOPTS +noauth yy_yy.ignore.example. @10.53.0.1 a > dig.out.ns1.test$n || ret=1
|
||||||
$DIG $DIGOPTS yy_yy.ignore.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
|
$DIG $DIGOPTS +noauth yy_yy.ignore.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.ns1.test$n dig.out.ns2.test$n || ret=1
|
$PERL ../digcomp.pl dig.out.ns1.test$n dig.out.ns2.test$n || ret=1
|
||||||
grep "check-names warning yy_yy.ignore.example/A/IN" ns2/named.run > /dev/null || ret=1
|
grep "check-names warning yy_yy.ignore.example/A/IN" ns2/named.run > /dev/null || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
@@ -76,6 +76,11 @@ israw1 () {
|
|||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# strip NS and RRSIG NS from input
|
||||||
|
stripns () {
|
||||||
|
awk '($4 == "NS") || ($4 == "RRSIG" && $5 == "NS") { next} { print }' $1
|
||||||
|
}
|
||||||
|
|
||||||
# Check the example. domain
|
# Check the example. domain
|
||||||
|
|
||||||
echo "I:checking that zone transfer worked ($n)"
|
echo "I:checking that zone transfer worked ($n)"
|
||||||
@@ -193,9 +198,13 @@ fi
|
|||||||
|
|
||||||
echo "I:checking positive wildcard validation NSEC ($n)"
|
echo "I:checking positive wildcard validation NSEC ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG $DIGOPTS a.wild.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
|
$DIG $DIGOPTS a.wild.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
|
||||||
$DIG $DIGOPTS a.wild.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
|
$DIG $DIGOPTS a.wild.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
|
stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
|
||||||
|
stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
|
||||||
|
$PERL ../digcomp.pl dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
|
||||||
|
grep "\*\.wild\.example\..*RRSIG NSEC" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
|
grep "\*\.wild\.example\..*NSEC z\.example" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
@@ -235,7 +244,9 @@ echo "I:checking positive wildcard validation NSEC3 ($n)"
|
|||||||
ret=0
|
ret=0
|
||||||
$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
|
$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
|
||||||
$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
|
$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
|
stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
|
||||||
|
stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
|
||||||
|
$PERL ../digcomp.pl dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
|
||||||
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
@@ -259,7 +270,9 @@ $DIG $DIGOPTS a.wild.optout.example. \
|
|||||||
@10.53.0.3 a > dig.out.ns3.test$n || ret=1
|
@10.53.0.3 a > dig.out.ns3.test$n || ret=1
|
||||||
$DIG $DIGOPTS a.wild.optout.example. \
|
$DIG $DIGOPTS a.wild.optout.example. \
|
||||||
@10.53.0.4 a > dig.out.ns4.test$n || ret=1
|
@10.53.0.4 a > dig.out.ns4.test$n || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
|
stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
|
||||||
|
stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
|
||||||
|
$PERL ../digcomp.pl dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
|
||||||
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
|
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
|
||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
|
@@ -27,56 +27,56 @@ status=0
|
|||||||
|
|
||||||
echo "I:checking that a forward zone overrides global forwarders"
|
echo "I:checking that a forward zone overrides global forwarders"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
$DIG +noadd +noauth txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
||||||
$DIG txt.example1. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
$DIG +noadd +noauth txt.example1. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.hidden dig.out.f1 || ret=1
|
$PERL ../digcomp.pl dig.out.hidden dig.out.f1 || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:checking that a forward first zone no forwarders recurses"
|
echo "I:checking that a forward first zone no forwarders recurses"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
|
$DIG +noadd +noauth txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
|
||||||
$DIG txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
$DIG +noadd +noauth txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.root dig.out.f1 || ret=1
|
$PERL ../digcomp.pl dig.out.root dig.out.f1 || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:checking that a forward only zone no forwarders fails"
|
echo "I:checking that a forward only zone no forwarders fails"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
|
$DIG +noadd +noauth txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
|
||||||
$DIG txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
$DIG +noadd +noauth txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.root dig.out.f1 || ret=1
|
$PERL ../digcomp.pl dig.out.root dig.out.f1 || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:checking that global forwarders work"
|
echo "I:checking that global forwarders work"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG txt.example4. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
$DIG +noadd +noauth txt.example4. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
||||||
$DIG txt.example4. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
$DIG +noadd +noauth txt.example4. txt @$f1 -p 5300 > dig.out.f1 || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.hidden dig.out.f1 || ret=1
|
$PERL ../digcomp.pl dig.out.hidden dig.out.f1 || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:checking that a forward zone works"
|
echo "I:checking that a forward zone works"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
$DIG +noadd +noauth txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
||||||
$DIG txt.example1. txt @$f2 -p 5300 > dig.out.f2 || ret=1
|
$DIG +noadd +noauth txt.example1. txt @$f2 -p 5300 > dig.out.f2 || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.hidden dig.out.f2 || ret=1
|
$PERL ../digcomp.pl dig.out.hidden dig.out.f2 || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:checking that forwarding doesn't spontaneously happen"
|
echo "I:checking that forwarding doesn't spontaneously happen"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
|
$DIG +noadd +noauth txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
|
||||||
$DIG txt.example2. txt @$f2 -p 5300 > dig.out.f2 || ret=1
|
$DIG +noadd +noauth txt.example2. txt @$f2 -p 5300 > dig.out.f2 || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.root dig.out.f2 || ret=1
|
$PERL ../digcomp.pl dig.out.root dig.out.f2 || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:checking that a forward zone with no specified policy works"
|
echo "I:checking that a forward zone with no specified policy works"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG txt.example3. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
$DIG +noadd +noauth txt.example3. txt @$hidden -p 5300 > dig.out.hidden || ret=1
|
||||||
$DIG txt.example3. txt @$f2 -p 5300 > dig.out.f2 || ret=1
|
$DIG +noadd +noauth txt.example3. txt @$f2 -p 5300 > dig.out.f2 || ret=1
|
||||||
$PERL ../digcomp.pl dig.out.hidden dig.out.f2 || ret=1
|
$PERL ../digcomp.pl dig.out.hidden dig.out.f2 || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
@@ -764,6 +764,7 @@ main(void) {
|
|||||||
test_getrrsetbyname("a.example1.", 1, 1, 1, 0, 1);
|
test_getrrsetbyname("a.example1.", 1, 1, 1, 0, 1);
|
||||||
test_getrrsetbyname("e.example1.", 1, 1, 1, 1, 1);
|
test_getrrsetbyname("e.example1.", 1, 1, 1, 1, 1);
|
||||||
test_getrrsetbyname("e.example1.", 1, 255, 1, 1, 0);
|
test_getrrsetbyname("e.example1.", 1, 255, 1, 1, 0);
|
||||||
|
test_getrrsetbyname("e.example1.", 1, 2, 1, 1, 1);
|
||||||
test_getrrsetbyname("e.example1.", 1, 46, 2, 0, 1);
|
test_getrrsetbyname("e.example1.", 1, 46, 2, 0, 1);
|
||||||
test_getrrsetbyname("", 1, 1, 0, 0, 0);
|
test_getrrsetbyname("", 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
# $Id: org.isc.bind.system,v 1.1 2010/08/25 04:51:51 marka Exp $
|
# $Id: org.isc.bind.system,v 1.1 2010/08/25 04:51:51 marka Exp $
|
||||||
|
|
||||||
for ns in 1 2 3 4 5 6 7
|
for ns in 1 2 3 4 5 6 7 8
|
||||||
do
|
do
|
||||||
/sbin/ifconfig lo0 10.53.0.$ns alias
|
/sbin/ifconfig lo0 10.53.0.$ns alias
|
||||||
/sbin/ifconfig lo0 inet6 fd92:7065:b8e:ffff::$ns alias
|
/sbin/ifconfig lo0 inet6 fd92:7065:b8e:ffff::$ns alias
|
||||||
|
@@ -155,12 +155,21 @@ sub start_server {
|
|||||||
close FH;
|
close FH;
|
||||||
$command .= "$options";
|
$command .= "$options";
|
||||||
} else {
|
} else {
|
||||||
|
$command .= "-D $server ";
|
||||||
$command .= "-m record,size,mctx ";
|
$command .= "-m record,size,mctx ";
|
||||||
$command .= "-T clienttest ";
|
$command .= "-T clienttest ";
|
||||||
$command .= "-T nosoa "
|
$command .= "-T nosoa "
|
||||||
if (-e "$testdir/$server/named.nosoa");
|
if (-e "$testdir/$server/named.nosoa");
|
||||||
$command .= "-T noaa "
|
$command .= "-T noaa "
|
||||||
if (-e "$testdir/$server/named.noaa");
|
if (-e "$testdir/$server/named.noaa");
|
||||||
|
$command .= "-T noedns "
|
||||||
|
if (-e "$testdir/$server/named.noedns");
|
||||||
|
$command .= "-T dropedns "
|
||||||
|
if (-e "$testdir/$server/named.dropedns");
|
||||||
|
$command .= "-T maxudp512 "
|
||||||
|
if (-e "$testdir/$server/named.maxudp512");
|
||||||
|
$command .= "-T maxudp1460 "
|
||||||
|
if (-e "$testdir/$server/named.maxudp1460");
|
||||||
$command .= "-c named.conf -d 99 -g -U 4 ";
|
$command .= "-c named.conf -d 99 -g -U 4 ";
|
||||||
}
|
}
|
||||||
if ($restart) {
|
if ($restart) {
|
||||||
|
@@ -11,9 +11,6 @@
|
|||||||
;; ANSWER SECTION:
|
;; ANSWER SECTION:
|
||||||
data.example. 5M IN TXT "some" "test" "data"
|
data.example. 5M IN TXT "some" "test" "data"
|
||||||
|
|
||||||
;; AUTHORITY SECTION:
|
|
||||||
example. 5M IN NS ns4.example.
|
|
||||||
|
|
||||||
;; Total query time: 8 msec
|
;; Total query time: 8 msec
|
||||||
;; FROM: draco to SERVER: 10.53.0.3
|
;; FROM: draco to SERVER: 10.53.0.3
|
||||||
;; WHEN: Wed Jun 21 10:58:54 2000
|
;; WHEN: Wed Jun 21 10:58:54 2000
|
||||||
|
@@ -80,7 +80,7 @@ status=`expr $status + $ret`
|
|||||||
n=`expr $n + 1`
|
n=`expr $n + 1`
|
||||||
echo "I:look for static-stub zone data with recursion (should be found) ($n)"
|
echo "I:look for static-stub zone data with recursion (should be found) ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG +tcp data.example. @10.53.0.2 txt -p 5300 > dig.out.ns2.test$n || ret=1
|
$DIG +tcp +noauth data.example. @10.53.0.2 txt -p 5300 > dig.out.ns2.test$n || ret=1
|
||||||
$PERL ../digcomp.pl knowngood.dig.out.rec dig.out.ns2.test$n || ret=1
|
$PERL ../digcomp.pl knowngood.dig.out.rec dig.out.ns2.test$n || ret=1
|
||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
@@ -11,12 +11,6 @@
|
|||||||
;; ANSWER SECTION:
|
;; ANSWER SECTION:
|
||||||
data.child.example. 5M IN TXT "some" "test" "data"
|
data.child.example. 5M IN TXT "some" "test" "data"
|
||||||
|
|
||||||
;; AUTHORITY SECTION:
|
|
||||||
child.example. 5M IN NS ns2.child.example.
|
|
||||||
|
|
||||||
;; ADDITIONAL SECTION:
|
|
||||||
ns2.child.example. 5M IN A 10.53.0.2
|
|
||||||
|
|
||||||
;; Total query time: 8 msec
|
;; Total query time: 8 msec
|
||||||
;; FROM: draco to SERVER: 10.53.0.3
|
;; FROM: draco to SERVER: 10.53.0.3
|
||||||
;; WHEN: Wed Jun 21 10:58:54 2000
|
;; WHEN: Wed Jun 21 10:58:54 2000
|
||||||
|
@@ -53,7 +53,7 @@ $PERL ../digcomp.pl knowngood.dig.out.norec dig.out.ns3 || ret=1
|
|||||||
|
|
||||||
echo "I:look for stub zone data with recursion (should be found) (pass=$pass)"
|
echo "I:look for stub zone data with recursion (should be found) (pass=$pass)"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG +tcp data.child.example. @10.53.0.3 txt -p 5300 > dig.out.ns3 || ret=1
|
$DIG +tcp +noauth +noadd data.child.example. @10.53.0.3 txt -p 5300 > dig.out.ns3 || ret=1
|
||||||
$PERL ../digcomp.pl knowngood.dig.out.rec dig.out.ns3 || ret=1
|
$PERL ../digcomp.pl knowngood.dig.out.rec dig.out.ns3 || ret=1
|
||||||
[ $ret = 0 ] || { status=1; echo "I:failed"; }
|
[ $ret = 0 ] || { status=1; echo "I:failed"; }
|
||||||
|
|
||||||
|
287
lib/dns/adb.c
287
lib/dns/adb.c
@@ -242,6 +242,18 @@ struct dns_adbentry {
|
|||||||
|
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
unsigned int srtt;
|
unsigned int srtt;
|
||||||
|
isc_uint16_t udpsize;
|
||||||
|
unsigned char plain;
|
||||||
|
unsigned char plainto;
|
||||||
|
unsigned char edns;
|
||||||
|
unsigned char to4096; /* Our max. */
|
||||||
|
/*
|
||||||
|
* Allow for encapsulated IPv4/IPv6 UDP packet over ethernet.
|
||||||
|
* Ethernet 1500 - IP(20) - IP6(40) - UDP(8) = 1432.
|
||||||
|
*/
|
||||||
|
unsigned char to1432; /* Ethernet */
|
||||||
|
unsigned char to1232; /* IPv6 nofrag */
|
||||||
|
unsigned char to512; /* plain DNS */
|
||||||
isc_sockaddr_t sockaddr;
|
isc_sockaddr_t sockaddr;
|
||||||
|
|
||||||
isc_stdtime_t expires;
|
isc_stdtime_t expires;
|
||||||
@@ -255,7 +267,6 @@ struct dns_adbentry {
|
|||||||
|
|
||||||
ISC_LIST(dns_adblameinfo_t) lameinfo;
|
ISC_LIST(dns_adblameinfo_t) lameinfo;
|
||||||
ISC_LINK(dns_adbentry_t) plink;
|
ISC_LINK(dns_adbentry_t) plink;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -952,12 +963,14 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
|
|||||||
DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
|
DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
|
||||||
adbname->expire_v4, now + rdataset->ttl);
|
adbname->expire_v4, now + rdataset->ttl);
|
||||||
adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
|
adbname->expire_v4 = ISC_MIN(adbname->expire_v4,
|
||||||
now + rdataset->ttl);
|
ISC_MIN(now + ADB_ENTRY_WINDOW,
|
||||||
|
now + rdataset->ttl));
|
||||||
} else {
|
} else {
|
||||||
DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
|
DP(NCACHE_LEVEL, "expire_v6 set to MIN(%u,%u) import_rdataset",
|
||||||
adbname->expire_v6, now + rdataset->ttl);
|
adbname->expire_v6, now + rdataset->ttl);
|
||||||
adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
|
adbname->expire_v6 = ISC_MIN(adbname->expire_v6,
|
||||||
now + rdataset->ttl);
|
ISC_MIN(now + ADB_ENTRY_WINDOW,
|
||||||
|
now + rdataset->ttl));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_addresses_added) {
|
if (new_addresses_added) {
|
||||||
@@ -1781,6 +1794,14 @@ new_adbentry(dns_adb_t *adb) {
|
|||||||
e->lock_bucket = DNS_ADB_INVALIDBUCKET;
|
e->lock_bucket = DNS_ADB_INVALIDBUCKET;
|
||||||
e->refcnt = 0;
|
e->refcnt = 0;
|
||||||
e->flags = 0;
|
e->flags = 0;
|
||||||
|
e->udpsize = 0;
|
||||||
|
e->edns = 0;
|
||||||
|
e->plain = 0;
|
||||||
|
e->plainto = 0;
|
||||||
|
e->to4096 = 0;
|
||||||
|
e->to1432 = 0;
|
||||||
|
e->to1232 = 0;
|
||||||
|
e->to512 = 0;
|
||||||
isc_random_get(&r);
|
isc_random_get(&r);
|
||||||
e->srtt = (r & 0x1f) + 1;
|
e->srtt = (r & 0x1f) + 1;
|
||||||
e->expires = 0;
|
e->expires = 0;
|
||||||
@@ -2043,6 +2064,7 @@ find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp,
|
|||||||
entry_next = ISC_LIST_NEXT(entry, plink);
|
entry_next = ISC_LIST_NEXT(entry, plink);
|
||||||
(void)check_expire_entry(adb, &entry, now);
|
(void)check_expire_entry(adb, &entry, now);
|
||||||
if (entry != NULL &&
|
if (entry != NULL &&
|
||||||
|
(entry->expires == 0 || entry->expires > now) &&
|
||||||
isc_sockaddr_equal(addr, &entry->sockaddr)) {
|
isc_sockaddr_equal(addr, &entry->sockaddr)) {
|
||||||
ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
|
ISC_LIST_UNLINK(adb->entries[bucket], entry, plink);
|
||||||
ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
|
ISC_LIST_PREPEND(adb->entries[bucket], entry, plink);
|
||||||
@@ -2815,6 +2837,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
unsigned int wanted_addresses;
|
unsigned int wanted_addresses;
|
||||||
unsigned int wanted_fetches;
|
unsigned int wanted_fetches;
|
||||||
unsigned int query_pending;
|
unsigned int query_pending;
|
||||||
|
char namebuf[DNS_NAME_FORMATSIZE];
|
||||||
|
|
||||||
REQUIRE(DNS_ADB_VALID(adb));
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
if (task != NULL) {
|
if (task != NULL) {
|
||||||
@@ -2875,6 +2898,11 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
REQUIRE(task != NULL);
|
REQUIRE(task != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isc_log_wouldlog(dns_lctx, DEF_LEVEL))
|
||||||
|
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||||
|
else
|
||||||
|
namebuf[0] = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to see if we know anything about this name at all.
|
* Try to see if we know anything about this name at all.
|
||||||
*/
|
*/
|
||||||
@@ -2932,8 +2960,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
* Yes, it is.
|
* Yes, it is.
|
||||||
*/
|
*/
|
||||||
DP(DEF_LEVEL,
|
DP(DEF_LEVEL,
|
||||||
"dns_adb_createfind: name %p is an alias (cached)",
|
"dns_adb_createfind: name %s (%p) is an alias (cached)",
|
||||||
adbname);
|
namebuf, adbname);
|
||||||
alias = ISC_TRUE;
|
alias = ISC_TRUE;
|
||||||
goto post_copy;
|
goto post_copy;
|
||||||
}
|
}
|
||||||
@@ -2948,8 +2976,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
result = dbfind_name(adbname, now, dns_rdatatype_a);
|
result = dbfind_name(adbname, now, dns_rdatatype_a);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
DP(DEF_LEVEL,
|
DP(DEF_LEVEL,
|
||||||
"dns_adb_createfind: found A for name %p in db",
|
"dns_adb_createfind: found A for name %s (%p) in db",
|
||||||
adbname);
|
namebuf, adbname);
|
||||||
goto v6;
|
goto v6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2958,8 +2986,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
*/
|
*/
|
||||||
if (result == DNS_R_ALIAS) {
|
if (result == DNS_R_ALIAS) {
|
||||||
DP(DEF_LEVEL,
|
DP(DEF_LEVEL,
|
||||||
"dns_adb_createfind: name %p is an alias",
|
"dns_adb_createfind: name %s (%p) is an alias",
|
||||||
adbname);
|
namebuf, adbname);
|
||||||
alias = ISC_TRUE;
|
alias = ISC_TRUE;
|
||||||
goto post_copy;
|
goto post_copy;
|
||||||
}
|
}
|
||||||
@@ -2988,8 +3016,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
|
result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
DP(DEF_LEVEL,
|
DP(DEF_LEVEL,
|
||||||
"dns_adb_createfind: found AAAA for name %p",
|
"dns_adb_createfind: found AAAA for name %s (%p)",
|
||||||
adbname);
|
namebuf, adbname);
|
||||||
goto fetch;
|
goto fetch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2998,8 +3026,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
*/
|
*/
|
||||||
if (result == DNS_R_ALIAS) {
|
if (result == DNS_R_ALIAS) {
|
||||||
DP(DEF_LEVEL,
|
DP(DEF_LEVEL,
|
||||||
"dns_adb_createfind: name %p is an alias",
|
"dns_adb_createfind: name %s (%p) is an alias",
|
||||||
adbname);
|
namebuf, adbname);
|
||||||
alias = ISC_TRUE;
|
alias = ISC_TRUE;
|
||||||
goto post_copy;
|
goto post_copy;
|
||||||
}
|
}
|
||||||
@@ -3039,9 +3067,9 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
if (WANT_INET(wanted_fetches) &&
|
if (WANT_INET(wanted_fetches) &&
|
||||||
fetch_name(adbname, start_at_zone,
|
fetch_name(adbname, start_at_zone,
|
||||||
dns_rdatatype_a) == ISC_R_SUCCESS) {
|
dns_rdatatype_a) == ISC_R_SUCCESS) {
|
||||||
DP(DEF_LEVEL,
|
DP(DEF_LEVEL, "dns_adb_createfind: "
|
||||||
"dns_adb_createfind: started A fetch for name %p",
|
"started A fetch for name %s (%p)",
|
||||||
adbname);
|
namebuf, adbname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3050,10 +3078,9 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
|
|||||||
if (WANT_INET6(wanted_fetches) &&
|
if (WANT_INET6(wanted_fetches) &&
|
||||||
fetch_name(adbname, start_at_zone,
|
fetch_name(adbname, start_at_zone,
|
||||||
dns_rdatatype_aaaa) == ISC_R_SUCCESS) {
|
dns_rdatatype_aaaa) == ISC_R_SUCCESS) {
|
||||||
DP(DEF_LEVEL,
|
DP(DEF_LEVEL, "dns_adb_createfind: "
|
||||||
"dns_adb_createfind: "
|
"started AAAA fetch for name %s (%p)",
|
||||||
"started AAAA fetch for name %p",
|
namebuf, adbname);
|
||||||
adbname);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3389,8 +3416,12 @@ dump_entry(FILE *f, dns_adbentry_t *entry, isc_boolean_t debug,
|
|||||||
if (debug)
|
if (debug)
|
||||||
fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt);
|
fprintf(f, ";\t%p: refcnt %u\n", entry, entry->refcnt);
|
||||||
|
|
||||||
fprintf(f, ";\t%s [srtt %u] [flags %08x]",
|
fprintf(f, ";\t%s [srtt %u] [flags %08x] [edns %u/%u/%u/%u/%u] "
|
||||||
addrbuf, entry->srtt, entry->flags);
|
"[plain %u/%u]", addrbuf, entry->srtt, entry->flags,
|
||||||
|
entry->edns, entry->to4096, entry->to1432, entry->to1232,
|
||||||
|
entry->to512, entry->plain, entry->plainto);
|
||||||
|
if (entry->udpsize != 0U)
|
||||||
|
fprintf(f, " [udpsize %u]", entry->udpsize);
|
||||||
if (entry->expires != 0)
|
if (entry->expires != 0)
|
||||||
fprintf(f, " [ttl %d]", entry->expires - now);
|
fprintf(f, " [ttl %d]", entry->expires - now);
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
@@ -3949,7 +3980,7 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
|
|||||||
unsigned int rtt, unsigned int factor)
|
unsigned int rtt, unsigned int factor)
|
||||||
{
|
{
|
||||||
int bucket;
|
int bucket;
|
||||||
unsigned int new_srtt;
|
isc_uint64_t new_srtt;
|
||||||
isc_stdtime_t now;
|
isc_stdtime_t now;
|
||||||
|
|
||||||
REQUIRE(DNS_ADB_VALID(adb));
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
@@ -3959,9 +3990,13 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
|
|||||||
bucket = addr->entry->lock_bucket;
|
bucket = addr->entry->lock_bucket;
|
||||||
LOCK(&adb->entrylocks[bucket]);
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
|
||||||
if (factor == DNS_ADB_RTTADJAGE)
|
|
||||||
new_srtt = addr->entry->srtt * 98 / 100;
|
if (factor == DNS_ADB_RTTADJAGE) {
|
||||||
else
|
new_srtt = addr->entry->srtt;
|
||||||
|
new_srtt <<= 9;
|
||||||
|
new_srtt -= addr->entry->srtt;
|
||||||
|
new_srtt >>= 9;
|
||||||
|
} else
|
||||||
new_srtt = (addr->entry->srtt / 10 * factor)
|
new_srtt = (addr->entry->srtt / 10 * factor)
|
||||||
+ (rtt / 10 * (10 - factor));
|
+ (rtt / 10 * (10 - factor));
|
||||||
|
|
||||||
@@ -4004,6 +4039,206 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
|
|||||||
UNLOCK(&adb->entrylocks[bucket]);
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EDNSTOS 3U
|
||||||
|
isc_boolean_t
|
||||||
|
dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
||||||
|
int bucket;
|
||||||
|
isc_boolean_t noedns = ISC_FALSE;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||||
|
|
||||||
|
bucket = addr->entry->lock_bucket;
|
||||||
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
if (addr->entry->edns == 0U &&
|
||||||
|
(addr->entry->plain > EDNSTOS || addr->entry->to4096 > EDNSTOS)) {
|
||||||
|
if (((addr->entry->plain + addr->entry->to4096) & 0x3f) != 0) {
|
||||||
|
noedns = ISC_TRUE;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Increment plain so we don't get stuck.
|
||||||
|
*/
|
||||||
|
addr->entry->plain++;
|
||||||
|
if (addr->entry->plain == 0xff) {
|
||||||
|
addr->entry->edns >>= 1;
|
||||||
|
addr->entry->to4096 >>= 1;
|
||||||
|
addr->entry->to1432 >>= 1;
|
||||||
|
addr->entry->to1232 >>= 1;
|
||||||
|
addr->entry->to512 >>= 1;
|
||||||
|
addr->entry->plain >>= 1;
|
||||||
|
addr->entry->plainto >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
|
return (noedns);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
||||||
|
int bucket;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||||
|
|
||||||
|
bucket = addr->entry->lock_bucket;
|
||||||
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
addr->entry->plain++;
|
||||||
|
if (addr->entry->plain == 0xff) {
|
||||||
|
addr->entry->edns >>= 1;
|
||||||
|
addr->entry->to4096 >>= 1;
|
||||||
|
addr->entry->to1432 >>= 1;
|
||||||
|
addr->entry->to1232 >>= 1;
|
||||||
|
addr->entry->to512 >>= 1;
|
||||||
|
addr->entry->plain >>= 1;
|
||||||
|
addr->entry->plainto >>= 1;
|
||||||
|
}
|
||||||
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
||||||
|
int bucket;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||||
|
|
||||||
|
bucket = addr->entry->lock_bucket;
|
||||||
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
/*
|
||||||
|
* If we have not had a successful query then clear all
|
||||||
|
* edns timeout information.
|
||||||
|
*/
|
||||||
|
if (addr->entry->edns == 0 && addr->entry->plain == 0) {
|
||||||
|
addr->entry->to512 = 0;
|
||||||
|
addr->entry->to1232 = 0;
|
||||||
|
addr->entry->to1432 = 0;
|
||||||
|
addr->entry->to4096 = 0;
|
||||||
|
} else {
|
||||||
|
addr->entry->to512 >>= 1;
|
||||||
|
addr->entry->to1232 >>= 1;
|
||||||
|
addr->entry->to1432 >>= 1;
|
||||||
|
addr->entry->to4096 >>= 1;
|
||||||
|
}
|
||||||
|
addr->entry->plainto++;
|
||||||
|
if (addr->entry->plainto == 0xff) {
|
||||||
|
addr->entry->edns >>= 1;
|
||||||
|
addr->entry->plain >>= 1;
|
||||||
|
addr->entry->plainto >>= 1;
|
||||||
|
}
|
||||||
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
|
||||||
|
int bucket;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||||
|
|
||||||
|
bucket = addr->entry->lock_bucket;
|
||||||
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
|
||||||
|
if (size <= 512U) {
|
||||||
|
if (addr->entry->to512 <= EDNSTOS) {
|
||||||
|
addr->entry->to512++;
|
||||||
|
addr->entry->to1232++;
|
||||||
|
addr->entry->to1432++;
|
||||||
|
addr->entry->to4096++;
|
||||||
|
}
|
||||||
|
} else if (size <= 1232U) {
|
||||||
|
if (addr->entry->to1232 <= EDNSTOS) {
|
||||||
|
addr->entry->to1232++;
|
||||||
|
addr->entry->to1432++;
|
||||||
|
addr->entry->to4096++;
|
||||||
|
}
|
||||||
|
} else if (size <= 1432U) {
|
||||||
|
if (addr->entry->to1432 <= EDNSTOS) {
|
||||||
|
addr->entry->to1432++;
|
||||||
|
addr->entry->to4096++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (addr->entry->to4096 <= EDNSTOS)
|
||||||
|
addr->entry->to4096++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr->entry->to4096 == 0xff) {
|
||||||
|
addr->entry->edns >>= 1;
|
||||||
|
addr->entry->to4096 >>= 1;
|
||||||
|
addr->entry->to1432 >>= 1;
|
||||||
|
addr->entry->to1232 >>= 1;
|
||||||
|
addr->entry->to512 >>= 1;
|
||||||
|
addr->entry->plain >>= 1;
|
||||||
|
addr->entry->plainto >>= 1;
|
||||||
|
}
|
||||||
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size) {
|
||||||
|
int bucket;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||||
|
|
||||||
|
bucket = addr->entry->lock_bucket;
|
||||||
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
if (size < 512U)
|
||||||
|
size = 512U;
|
||||||
|
if (size > addr->entry->udpsize)
|
||||||
|
addr->entry->udpsize = size;
|
||||||
|
addr->entry->edns++;
|
||||||
|
if (addr->entry->edns == 0xff) {
|
||||||
|
addr->entry->edns >>= 1;
|
||||||
|
addr->entry->to4096 >>= 1;
|
||||||
|
addr->entry->to1432 >>= 1;
|
||||||
|
addr->entry->to1232 >>= 1;
|
||||||
|
addr->entry->to512 >>= 1;
|
||||||
|
addr->entry->plain >>= 1;
|
||||||
|
addr->entry->plainto >>= 1;
|
||||||
|
}
|
||||||
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
||||||
|
int bucket;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||||
|
|
||||||
|
bucket = addr->entry->lock_bucket;
|
||||||
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
size = addr->entry->udpsize;
|
||||||
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
|
|
||||||
|
return (size);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
|
||||||
|
int bucket;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
|
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
|
||||||
|
|
||||||
|
bucket = addr->entry->lock_bucket;
|
||||||
|
LOCK(&adb->entrylocks[bucket]);
|
||||||
|
if (addr->entry->to1232 > EDNSTOS)
|
||||||
|
size = 512;
|
||||||
|
else if (addr->entry->to1432 > EDNSTOS)
|
||||||
|
size = 1232;
|
||||||
|
else if (addr->entry->to4096 > EDNSTOS)
|
||||||
|
size = 1432;
|
||||||
|
else
|
||||||
|
size = 4096;
|
||||||
|
UNLOCK(&adb->entrylocks[bucket]);
|
||||||
|
|
||||||
|
return (size);
|
||||||
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
|
dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
|
||||||
dns_adbaddrinfo_t **addrp, isc_stdtime_t now)
|
dns_adbaddrinfo_t **addrp, isc_stdtime_t now)
|
||||||
|
@@ -567,6 +567,93 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
|
|||||||
*\li addr be valid.
|
*\li addr be valid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_setudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size);
|
||||||
|
/*%
|
||||||
|
* Update seen UDP response size. The largest seen will be returned by
|
||||||
|
* dns_adb_getudpsize().
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li adb be valid.
|
||||||
|
*
|
||||||
|
*\li addr be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_adb_getudpsize(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
|
||||||
|
/*%
|
||||||
|
* Return the largest seen UDP response size.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li adb be valid.
|
||||||
|
*
|
||||||
|
*\li addr be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
dns_adb_probesize(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
|
||||||
|
/*%
|
||||||
|
* Return suggested EDNS UDP size based on observed responses / failures.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li adb be valid.
|
||||||
|
*
|
||||||
|
*\li addr be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_plainresponse(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
|
||||||
|
/*%
|
||||||
|
* Record a successful plain DNS response.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li adb be valid.
|
||||||
|
*
|
||||||
|
*\li addr be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_timeout(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
|
||||||
|
/*%
|
||||||
|
* Record a plain DNS UDP query failed.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li adb be valid.
|
||||||
|
*
|
||||||
|
*\li addr be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_adb_ednsto(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int size);
|
||||||
|
/*%
|
||||||
|
* Record a failed EDNS UDP response and the advertised EDNS UDP buffer size
|
||||||
|
* used.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li adb be valid.
|
||||||
|
*
|
||||||
|
*\li addr be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_boolean_t
|
||||||
|
dns_adb_noedns(dns_adb_t *adb, dns_adbaddrinfo_t *addr);
|
||||||
|
/*%
|
||||||
|
* Return whether EDNS should be disabled for this server.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li adb be valid.
|
||||||
|
*
|
||||||
|
*\li addr be valid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
|
dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa,
|
||||||
dns_adbaddrinfo_t **addrp, isc_stdtime_t now);
|
dns_adbaddrinfo_t **addrp, isc_stdtime_t now);
|
||||||
|
@@ -167,9 +167,16 @@ typedef struct query {
|
|||||||
unsigned int attributes;
|
unsigned int attributes;
|
||||||
unsigned int sends;
|
unsigned int sends;
|
||||||
unsigned int connects;
|
unsigned int connects;
|
||||||
|
unsigned int udpsize;
|
||||||
unsigned char data[512];
|
unsigned char data[512];
|
||||||
} resquery_t;
|
} resquery_t;
|
||||||
|
|
||||||
|
struct tried {
|
||||||
|
isc_sockaddr_t addr;
|
||||||
|
unsigned int count;
|
||||||
|
ISC_LINK(struct tried) link;
|
||||||
|
};
|
||||||
|
|
||||||
#define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!')
|
#define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!')
|
||||||
#define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC)
|
#define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC)
|
||||||
|
|
||||||
@@ -231,8 +238,8 @@ struct fetchctx {
|
|||||||
dns_forwarderlist_t forwarders;
|
dns_forwarderlist_t forwarders;
|
||||||
dns_fwdpolicy_t fwdpolicy;
|
dns_fwdpolicy_t fwdpolicy;
|
||||||
isc_sockaddrlist_t bad;
|
isc_sockaddrlist_t bad;
|
||||||
isc_sockaddrlist_t edns;
|
ISC_LIST(struct tried) edns;
|
||||||
isc_sockaddrlist_t edns512;
|
ISC_LIST(struct tried) edns512;
|
||||||
isc_sockaddrlist_t bad_edns;
|
isc_sockaddrlist_t bad_edns;
|
||||||
dns_validator_t *validator;
|
dns_validator_t *validator;
|
||||||
ISC_LIST(dns_validator_t) validators;
|
ISC_LIST(dns_validator_t) validators;
|
||||||
@@ -452,6 +459,8 @@ struct dns_resolver {
|
|||||||
#define FCTX_ADDRINFO_MARK 0x0001
|
#define FCTX_ADDRINFO_MARK 0x0001
|
||||||
#define FCTX_ADDRINFO_FORWARDER 0x1000
|
#define FCTX_ADDRINFO_FORWARDER 0x1000
|
||||||
#define FCTX_ADDRINFO_TRIED 0x2000
|
#define FCTX_ADDRINFO_TRIED 0x2000
|
||||||
|
#define FCTX_ADDRINFO_EDNSOK 0x4000
|
||||||
|
|
||||||
#define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \
|
#define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \
|
||||||
== 0)
|
== 0)
|
||||||
#define ISFORWARDER(a) (((a)->flags & \
|
#define ISFORWARDER(a) (((a)->flags & \
|
||||||
@@ -811,6 +820,10 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
|
|||||||
|
|
||||||
query->attributes |= RESQUERY_ATTR_CANCELED;
|
query->attributes |= RESQUERY_ATTR_CANCELED;
|
||||||
|
|
||||||
|
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
||||||
|
isc_sockaddr_format(&query->addrinfo->sockaddr,
|
||||||
|
addrbuf, sizeof(addrbuf));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Should we update the RTT?
|
* Should we update the RTT?
|
||||||
*/
|
*/
|
||||||
@@ -844,14 +857,45 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
|
|||||||
inc_stats(fctx->res,
|
inc_stats(fctx->res,
|
||||||
dns_resstatscounter_queryrtt5);
|
dns_resstatscounter_queryrtt5);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
isc_uint32_t value;
|
||||||
|
isc_uint32_t mask;
|
||||||
/*
|
/*
|
||||||
* We don't have an RTT for this query. Maybe the
|
* We don't have an RTT for this query. Maybe the
|
||||||
* packet was lost, or maybe this server is very
|
* packet was lost, or maybe this server is very
|
||||||
* slow. We don't know. Increase the RTT.
|
* slow. We don't know. Increase the RTT.
|
||||||
*/
|
*/
|
||||||
INSIST(no_response);
|
INSIST(no_response);
|
||||||
rtt = query->addrinfo->srtt + 200000;
|
isc_random_get(&value);
|
||||||
|
if (query->addrinfo->srtt > 800000)
|
||||||
|
mask = 0x3fff;
|
||||||
|
else if (query->addrinfo->srtt > 400000)
|
||||||
|
mask = 0x7fff;
|
||||||
|
else if (query->addrinfo->srtt > 200000)
|
||||||
|
mask = 0xffff;
|
||||||
|
else if (query->addrinfo->srtt > 100000)
|
||||||
|
mask = 0x1ffff;
|
||||||
|
else if (query->addrinfo->srtt > 50000)
|
||||||
|
mask = 0x3ffff;
|
||||||
|
else if (query->addrinfo->srtt > 25000)
|
||||||
|
mask = 0x7ffff;
|
||||||
|
else
|
||||||
|
mask = 0xfffff;
|
||||||
|
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
|
||||||
|
dns_adb_ednsto(fctx->adb, query->addrinfo,
|
||||||
|
query->udpsize);
|
||||||
|
else
|
||||||
|
dns_adb_timeout(fctx->adb, query->addrinfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't adjust timeout on EDNS queries unless we have
|
||||||
|
* seen a EDNS response.
|
||||||
|
*/
|
||||||
|
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
|
||||||
|
(query->addrinfo->flags & FCTX_ADDRINFO_EDNSOK) == 0) {
|
||||||
|
mask >>= 2;
|
||||||
|
}
|
||||||
|
rtt = query->addrinfo->srtt + (value & mask);
|
||||||
if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US)
|
if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US)
|
||||||
rtt = MAX_SINGLE_QUERY_TIMEOUT_US;
|
rtt = MAX_SINGLE_QUERY_TIMEOUT_US;
|
||||||
/*
|
/*
|
||||||
@@ -1618,62 +1662,70 @@ add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
|||||||
ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link);
|
ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_boolean_t
|
static struct tried *
|
||||||
triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
||||||
isc_sockaddr_t *sa;
|
struct tried *tried;
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->edns);
|
for (tried = ISC_LIST_HEAD(fctx->edns);
|
||||||
sa != NULL;
|
tried != NULL;
|
||||||
sa = ISC_LIST_NEXT(sa, link)) {
|
tried = ISC_LIST_NEXT(tried, link)) {
|
||||||
if (isc_sockaddr_equal(sa, address))
|
if (isc_sockaddr_equal(&tried->addr, address))
|
||||||
return (ISC_TRUE);
|
return (tried);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ISC_FALSE);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
||||||
isc_sockaddr_t *sa;
|
struct tried *tried;
|
||||||
|
|
||||||
if (triededns(fctx, address))
|
tried = triededns(fctx, address);
|
||||||
|
if (tried != NULL) {
|
||||||
|
tried->count++;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sa = isc_mem_get(fctx->mctx, sizeof(*sa));
|
|
||||||
if (sa == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
*sa = *address;
|
|
||||||
ISC_LIST_INITANDAPPEND(fctx->edns, sa, link);
|
|
||||||
}
|
|
||||||
|
|
||||||
static isc_boolean_t
|
|
||||||
triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
|
||||||
isc_sockaddr_t *sa;
|
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->edns512);
|
|
||||||
sa != NULL;
|
|
||||||
sa = ISC_LIST_NEXT(sa, link)) {
|
|
||||||
if (isc_sockaddr_equal(sa, address))
|
|
||||||
return (ISC_TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ISC_FALSE);
|
tried = isc_mem_get(fctx->mctx, sizeof(*tried));
|
||||||
|
if (tried == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tried->addr = *address;
|
||||||
|
tried->count = 1;
|
||||||
|
ISC_LIST_INITANDAPPEND(fctx->edns, tried, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct tried *
|
||||||
|
triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
||||||
|
struct tried *tried;
|
||||||
|
|
||||||
|
for (tried = ISC_LIST_HEAD(fctx->edns512);
|
||||||
|
tried != NULL;
|
||||||
|
tried = ISC_LIST_NEXT(tried, link)) {
|
||||||
|
if (isc_sockaddr_equal(&tried->addr, address))
|
||||||
|
return (tried);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
|
||||||
isc_sockaddr_t *sa;
|
struct tried *tried;
|
||||||
|
|
||||||
if (triededns512(fctx, address))
|
tried = triededns512(fctx, address);
|
||||||
|
if (tried != NULL) {
|
||||||
|
tried->count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tried = isc_mem_get(fctx->mctx, sizeof(*tried));
|
||||||
|
if (tried == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sa = isc_mem_get(fctx->mctx, sizeof(*sa));
|
tried->addr = *address;
|
||||||
if (sa == NULL)
|
tried->count = 1;
|
||||||
return;
|
ISC_LIST_INITANDAPPEND(fctx->edns512, tried, link);
|
||||||
|
|
||||||
*sa = *address;
|
|
||||||
ISC_LIST_INITANDAPPEND(fctx->edns512, sa, link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@@ -1699,6 +1751,11 @@ resquery_send(resquery_t *query) {
|
|||||||
isc_boolean_t connecting = ISC_FALSE;
|
isc_boolean_t connecting = ISC_FALSE;
|
||||||
dns_ednsopt_t ednsopts[EDNSOPTS];
|
dns_ednsopt_t ednsopts[EDNSOPTS];
|
||||||
unsigned ednsopt = 0;
|
unsigned ednsopt = 0;
|
||||||
|
isc_uint16_t hint = 0, udpsize = 0; /* No EDNS */
|
||||||
|
|
||||||
|
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
||||||
|
isc_sockaddr_format(&query->addrinfo->sockaddr,
|
||||||
|
addrbuf, sizeof(addrbuf));
|
||||||
|
|
||||||
fctx = query->fctx;
|
fctx = query->fctx;
|
||||||
QTRACE("send");
|
QTRACE("send");
|
||||||
@@ -1766,11 +1823,12 @@ resquery_send(resquery_t *query) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Set CD if the client says don't validate or the question is
|
* Set CD if the client says don't validate or the question is
|
||||||
* under a secure entry point.
|
* under a secure entry point and it is not a recursive query.
|
||||||
*/
|
*/
|
||||||
if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
|
if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
|
||||||
fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
|
fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
|
||||||
} else if (res->view->enablevalidation) {
|
} else if (res->view->enablevalidation &&
|
||||||
|
(fctx->qmessage->flags & DNS_MESSAGEFLAG_RD) != 0) {
|
||||||
result = dns_view_issecuredomain(res->view, &fctx->name,
|
result = dns_view_issecuredomain(res->view, &fctx->name,
|
||||||
&secure_domain);
|
&secure_domain);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
@@ -1827,35 +1885,37 @@ resquery_send(resquery_t *query) {
|
|||||||
if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0)
|
if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0)
|
||||||
query->options |= DNS_FETCHOPT_NOEDNS0;
|
query->options |= DNS_FETCHOPT_NOEDNS0;
|
||||||
|
|
||||||
/*
|
/* See if response history indicates that EDNS is not supported. */
|
||||||
* Handle timeouts by reducing the UDP response size to 512 bytes
|
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
|
||||||
* then if that doesn't work disabling EDNS (includes DO) and CD.
|
dns_adb_noedns(fctx->adb, query->addrinfo))
|
||||||
*
|
query->options |= DNS_FETCHOPT_NOEDNS0;
|
||||||
* These timeout can be due to:
|
|
||||||
* * broken nameservers that don't respond to EDNS queries.
|
|
||||||
* * broken/misconfigured firewalls and NAT implementations
|
if (fctx->timeout && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
||||||
* that don't handle IP fragmentation.
|
isc_sockaddr_t *sockaddr = &query->addrinfo->sockaddr;
|
||||||
* * broken/misconfigured firewalls that don't handle responses
|
struct tried *tried;
|
||||||
* greater than 512 bytes.
|
|
||||||
* * broken/misconfigured firewalls that don't handle EDNS, DO
|
if (fctx->timeouts > (MAX_EDNS0_TIMEOUTS * 2) &&
|
||||||
* or CD.
|
(query->addrinfo->flags & FCTX_ADDRINFO_EDNSOK) == 0) {
|
||||||
* * packet loss / link outage.
|
|
||||||
*/
|
|
||||||
if (fctx->timeout) {
|
|
||||||
if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
|
|
||||||
fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
|
|
||||||
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
|
||||||
query->options |= DNS_FETCHOPT_NOEDNS0;
|
query->options |= DNS_FETCHOPT_NOEDNS0;
|
||||||
fctx->reason = "disabling EDNS";
|
fctx->reason = "disabling EDNS";
|
||||||
} else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
|
} else if ((tried = triededns512(fctx, sockaddr)) != NULL &&
|
||||||
fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
|
tried->count >= 2U &&
|
||||||
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
(query->addrinfo->flags & FCTX_ADDRINFO_EDNSOK) == 0) {
|
||||||
query->options |= DNS_FETCHOPT_EDNS512;
|
query->options |= DNS_FETCHOPT_NOEDNS0;
|
||||||
fctx->reason = "reducing the advertised EDNS UDP "
|
fctx->reason = "disabling EDNS";
|
||||||
"packet size to 512 octets";
|
} else if ((tried = triededns(fctx, sockaddr)) != NULL) {
|
||||||
|
if (tried->count == 1U) {
|
||||||
|
hint = dns_adb_getudpsize(fctx->adb,
|
||||||
|
query->addrinfo);
|
||||||
|
} else if (tried->count >= 2U) {
|
||||||
|
query->options |= DNS_FETCHOPT_EDNS512;
|
||||||
|
fctx->reason = "reducing the advertised EDNS "
|
||||||
|
"UDP packet size to 512 octets";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fctx->timeout = ISC_FALSE;
|
|
||||||
}
|
}
|
||||||
|
fctx->timeout = ISC_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use EDNS0, unless the caller doesn't want it, or we know that
|
* Use EDNS0, unless the caller doesn't want it, or we know that
|
||||||
@@ -1864,19 +1924,46 @@ resquery_send(resquery_t *query) {
|
|||||||
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
||||||
if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
|
if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
|
||||||
unsigned int version = 0; /* Default version. */
|
unsigned int version = 0; /* Default version. */
|
||||||
unsigned int flags;
|
unsigned int flags = query->addrinfo->flags;
|
||||||
isc_uint16_t udpsize = res->udpsize;
|
|
||||||
isc_boolean_t reqnsid = res->view->requestnsid;
|
isc_boolean_t reqnsid = res->view->requestnsid;
|
||||||
|
|
||||||
flags = query->addrinfo->flags;
|
if ((flags & FCTX_ADDRINFO_EDNSOK) != 0 &&
|
||||||
|
(query->options & DNS_FETCHOPT_EDNS512) == 0) {
|
||||||
|
udpsize = dns_adb_probesize(fctx->adb,
|
||||||
|
query->addrinfo);
|
||||||
|
if (udpsize > res->udpsize)
|
||||||
|
udpsize = res->udpsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer != NULL)
|
||||||
|
(void)dns_peer_getudpsize(peer, &udpsize);
|
||||||
|
|
||||||
|
if (udpsize == 0U && res->udpsize == 512U)
|
||||||
|
udpsize = 512;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Was the size forced to 512 in the configuration?
|
||||||
|
*/
|
||||||
|
if (udpsize == 512U)
|
||||||
|
query->options |= DNS_FETCHOPT_EDNS512;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have talked to this server before.
|
||||||
|
*/
|
||||||
|
if (hint != 0U)
|
||||||
|
udpsize = hint;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We know nothing about the peer's capabilities
|
||||||
|
* so start with minimal EDNS UDP size.
|
||||||
|
*/
|
||||||
|
if (udpsize == 0U)
|
||||||
|
udpsize = 512;
|
||||||
|
|
||||||
if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
|
if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
|
||||||
version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
|
version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
|
||||||
version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
|
version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
|
||||||
}
|
}
|
||||||
if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
|
|
||||||
udpsize = 512;
|
|
||||||
else if (peer != NULL)
|
|
||||||
(void)dns_peer_getudpsize(peer, &udpsize);
|
|
||||||
|
|
||||||
/* request NSID for current view or peer? */
|
/* request NSID for current view or peer? */
|
||||||
if (peer != NULL)
|
if (peer != NULL)
|
||||||
@@ -1899,6 +1986,7 @@ resquery_send(resquery_t *query) {
|
|||||||
* bit.
|
* bit.
|
||||||
*/
|
*/
|
||||||
query->options |= DNS_FETCHOPT_NOEDNS0;
|
query->options |= DNS_FETCHOPT_NOEDNS0;
|
||||||
|
udpsize = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -1910,6 +1998,11 @@ resquery_send(resquery_t *query) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record the UDP EDNS size choosen.
|
||||||
|
*/
|
||||||
|
query->udpsize = udpsize;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we need EDNS0 to do this query and aren't using it, we lose.
|
* If we need EDNS0 to do this query and aren't using it, we lose.
|
||||||
*/
|
*/
|
||||||
@@ -1918,10 +2011,10 @@ resquery_send(resquery_t *query) {
|
|||||||
goto cleanup_message;
|
goto cleanup_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
|
if (udpsize > 512U)
|
||||||
add_triededns(fctx, &query->addrinfo->sockaddr);
|
add_triededns(fctx, &query->addrinfo->sockaddr);
|
||||||
|
|
||||||
if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
|
if (udpsize == 512U)
|
||||||
add_triededns512(fctx, &query->addrinfo->sockaddr);
|
add_triededns512(fctx, &query->addrinfo->sockaddr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2612,7 +2705,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
|
|||||||
* Don't pound on remote servers. (Failsafe!)
|
* Don't pound on remote servers. (Failsafe!)
|
||||||
*/
|
*/
|
||||||
fctx->restarts++;
|
fctx->restarts++;
|
||||||
if (fctx->restarts > 10) {
|
if (fctx->restarts > 100) {
|
||||||
FCTXTRACE("too many restarts");
|
FCTXTRACE("too many restarts");
|
||||||
return (DNS_R_SERVFAIL);
|
return (DNS_R_SERVFAIL);
|
||||||
}
|
}
|
||||||
@@ -3142,6 +3235,7 @@ fctx_unlink(fetchctx_t *fctx) {
|
|||||||
static void
|
static void
|
||||||
fctx_destroy(fetchctx_t *fctx) {
|
fctx_destroy(fetchctx_t *fctx) {
|
||||||
isc_sockaddr_t *sa, *next_sa;
|
isc_sockaddr_t *sa, *next_sa;
|
||||||
|
struct tried *tried;
|
||||||
|
|
||||||
REQUIRE(VALID_FCTX(fctx));
|
REQUIRE(VALID_FCTX(fctx));
|
||||||
REQUIRE(fctx->state == fetchstate_done ||
|
REQUIRE(fctx->state == fetchstate_done ||
|
||||||
@@ -3168,20 +3262,18 @@ fctx_destroy(fetchctx_t *fctx) {
|
|||||||
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->edns);
|
for (tried = ISC_LIST_HEAD(fctx->edns);
|
||||||
sa != NULL;
|
tried != NULL;
|
||||||
sa = next_sa) {
|
tried = ISC_LIST_HEAD(fctx->edns)) {
|
||||||
next_sa = ISC_LIST_NEXT(sa, link);
|
ISC_LIST_UNLINK(fctx->edns, tried, link);
|
||||||
ISC_LIST_UNLINK(fctx->edns, sa, link);
|
isc_mem_put(fctx->mctx, tried, sizeof(*tried));
|
||||||
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->edns512);
|
for (tried = ISC_LIST_HEAD(fctx->edns512);
|
||||||
sa != NULL;
|
tried != NULL;
|
||||||
sa = next_sa) {
|
tried = ISC_LIST_HEAD(fctx->edns512)) {
|
||||||
next_sa = ISC_LIST_NEXT(sa, link);
|
ISC_LIST_UNLINK(fctx->edns512, tried, link);
|
||||||
ISC_LIST_UNLINK(fctx->edns512, sa, link);
|
isc_mem_put(fctx->mctx, tried, sizeof(*tried));
|
||||||
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sa = ISC_LIST_HEAD(fctx->bad_edns);
|
for (sa = ISC_LIST_HEAD(fctx->bad_edns);
|
||||||
@@ -6907,6 +6999,13 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((options & DNS_FETCHOPT_TCP) == 0) {
|
||||||
|
if ((options & DNS_FETCHOPT_NOEDNS0) == 0)
|
||||||
|
dns_adb_setudpsize(fctx->adb, query->addrinfo,
|
||||||
|
isc_buffer_usedlength(&devent->buffer));
|
||||||
|
else
|
||||||
|
dns_adb_plainresponse(fctx->adb, query->addrinfo);
|
||||||
|
}
|
||||||
result = dns_message_parse(message, &devent->buffer, 0);
|
result = dns_message_parse(message, &devent->buffer, 0);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
@@ -7019,12 +7118,66 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
message->rcode == dns_rcode_refused ||
|
message->rcode == dns_rcode_refused ||
|
||||||
message->rcode == dns_rcode_yxdomain) &&
|
message->rcode == dns_rcode_yxdomain) &&
|
||||||
bad_edns(fctx, &query->addrinfo->sockaddr)) {
|
bad_edns(fctx, &query->addrinfo->sockaddr)) {
|
||||||
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
/*
|
||||||
|
* XXXMPA We need to drop/remove the logging here when we have more
|
||||||
|
* experience.
|
||||||
|
*/
|
||||||
|
char buf[4096], addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
||||||
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
|
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
|
||||||
sizeof(addrbuf));
|
sizeof(addrbuf));
|
||||||
|
snprintf(buf, sizeof(buf), "received packet from %s "
|
||||||
|
"(bad edns):\n", addrbuf);
|
||||||
|
dns_message_logpacket(message, buf,
|
||||||
|
DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
|
||||||
|
ISC_LOG_NOTICE, fctx->res->mctx);
|
||||||
dns_adb_changeflags(fctx->adb, query->addrinfo,
|
dns_adb_changeflags(fctx->adb, query->addrinfo,
|
||||||
DNS_FETCHOPT_NOEDNS0,
|
DNS_FETCHOPT_NOEDNS0,
|
||||||
DNS_FETCHOPT_NOEDNS0);
|
DNS_FETCHOPT_NOEDNS0);
|
||||||
|
} else if (opt == NULL && (message->flags & DNS_MESSAGEFLAG_TC) == 0 &&
|
||||||
|
(message->rcode == dns_rcode_noerror ||
|
||||||
|
message->rcode == dns_rcode_nxdomain) &&
|
||||||
|
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
|
||||||
|
/*
|
||||||
|
* Old versions of named incorrectly drop the OPT record
|
||||||
|
* when there is a signed, truncated response so check that
|
||||||
|
* TC is not set.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* XXXMPA We need to drop/remove the logging here when we have more
|
||||||
|
* experience.
|
||||||
|
*/
|
||||||
|
char buf[4096], addrbuf[ISC_SOCKADDR_FORMATSIZE];
|
||||||
|
/*
|
||||||
|
* We didn't get a OPT record in response to a EDNS query.
|
||||||
|
* Record that the server is not talking EDNS. While this
|
||||||
|
* should be safe to do for any rcode we limit it to NOERROR
|
||||||
|
* and NXDOMAIN.
|
||||||
|
*/
|
||||||
|
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
|
||||||
|
sizeof(addrbuf));
|
||||||
|
snprintf(buf, sizeof(buf), "received packet from %s (no opt):\n",
|
||||||
|
addrbuf);
|
||||||
|
dns_message_logpacket(message, buf,
|
||||||
|
DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
|
||||||
|
ISC_LOG_NOTICE, fctx->res->mctx);
|
||||||
|
dns_adb_changeflags(fctx->adb, query->addrinfo,
|
||||||
|
DNS_FETCHOPT_NOEDNS0,
|
||||||
|
DNS_FETCHOPT_NOEDNS0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we get a non error response to a EDNS query record the fact
|
||||||
|
* so we won't fallback to plain DNS in the future for this server.
|
||||||
|
*/
|
||||||
|
if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
|
||||||
|
(query->addrinfo->flags & FCTX_ADDRINFO_EDNSOK) == 0 &&
|
||||||
|
(message->rcode == dns_rcode_noerror ||
|
||||||
|
message->rcode == dns_rcode_nxdomain ||
|
||||||
|
message->rcode == dns_rcode_refused ||
|
||||||
|
message->rcode == dns_rcode_yxdomain)) {
|
||||||
|
dns_adb_changeflags(fctx->adb, query->addrinfo,
|
||||||
|
FCTX_ADDRINFO_EDNSOK,
|
||||||
|
FCTX_ADDRINFO_EDNSOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7038,6 +7191,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
|||||||
if ((options & DNS_FETCHOPT_TCP) != 0) {
|
if ((options & DNS_FETCHOPT_TCP) != 0) {
|
||||||
broken_server = DNS_R_TRUNCATEDTCP;
|
broken_server = DNS_R_TRUNCATEDTCP;
|
||||||
keep_trying = ISC_TRUE;
|
keep_trying = ISC_TRUE;
|
||||||
|
} else if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
|
||||||
|
(query->options & DNS_FETCHOPT_EDNS512) == 0 &&
|
||||||
|
!triededns(fctx, &query->addrinfo->sockaddr)) {
|
||||||
|
resend = ISC_TRUE;
|
||||||
} else {
|
} else {
|
||||||
options |= DNS_FETCHOPT_TCP;
|
options |= DNS_FETCHOPT_TCP;
|
||||||
resend = ISC_TRUE;
|
resend = ISC_TRUE;
|
||||||
|
Reference in New Issue
Block a user