mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 14:47:09 +00:00
bab5ad623c
thread and total: num.queries_cookie_valid, num.queries_cookie_client, num.queries.cookie_invalid.
603 lines
14 KiB
Plaintext
603 lines
14 KiB
Plaintext
# #-- stat_values.test --#
|
|
# source the master var file when it's there
|
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
|
# use .tpkg.var.test for in test variable passing
|
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
|
# We need kill_pid for the serve-expired-client-timeout test
|
|
. ../common.sh
|
|
|
|
PRE="../.."
|
|
|
|
# Individual thread stats.
|
|
STATS_IGNORE_THREAD="\
|
|
^thread"
|
|
|
|
# Histogram stats.
|
|
STATS_IGNORE_HISTOGRAM="\
|
|
^histogram"
|
|
|
|
# Time dependent stats.
|
|
STATS_IGNORE_TIME_SPECIFIC="\
|
|
^total.recursion.time.avg=
|
|
^total.recursion.time.median=
|
|
^time.now=
|
|
^time.up=
|
|
^time.elapsed="
|
|
|
|
# Usage dependent stats.
|
|
STATS_IGNORE_USAGE_SPECIFIC="\
|
|
^total.requestlist.avg=
|
|
^total.requestlist.max=
|
|
^total.requestlist.overwritten=
|
|
^total.requestlist.exceeded=
|
|
^total.requestlist.current.all=
|
|
^total.requestlist.current.user=
|
|
^total.tcpusage=
|
|
^mem\."
|
|
|
|
# Stats to ignore by default.
|
|
STATS_IGNORE_DEFAULT="\
|
|
$STATS_IGNORE_THREAD
|
|
$STATS_IGNORE_HISTOGRAM
|
|
$STATS_IGNORE_TIME_SPECIFIC
|
|
$STATS_IGNORE_USAGE_SPECIFIC"
|
|
|
|
# Various files to be used while testing.
|
|
STATS_FILE=stats.$$
|
|
EXPECTED_STATS_FILE=expected_stats.$$
|
|
IGNORE_REGEX_FILE=ignore_regex.$$
|
|
FILTERED_STATS_FILE=filtered_stats.$$
|
|
FOUND_STATS_FILE=found_stats.$$
|
|
REST_STATS_FILE=rest_stats.$$
|
|
|
|
DEBUG=0
|
|
|
|
# Write stats to $STATS_FILE.
|
|
# Call this when you want to get stats from unbound.
|
|
get_stats () {
|
|
echo "> Getting stats"
|
|
echo "$PRE/unbound-control -c ub.conf stats"
|
|
$PRE/unbound-control -c ub.conf stats > $STATS_FILE
|
|
if test $? -ne 0; then
|
|
echo "wrong exit value after success"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Set the expected stat values by writing to $EXPECTED_STATS_FILE.
|
|
# sort is used for proper diff later.
|
|
set_expected_stats () {
|
|
echo "$1" | sort > $EXPECTED_STATS_FILE
|
|
}
|
|
|
|
# Set the regex to ignore stats by writing to $IGNORE_REGEX_FILE.
|
|
set_ignore_regex_stats () {
|
|
echo "$1" > $IGNORE_REGEX_FILE
|
|
}
|
|
|
|
# Filter the stats by removing any matched regex from $IGNORE_REGEX_FILE,
|
|
# sorts and writes the left over stats to $FILTERED_STATS_FILE.
|
|
filter_stats () {
|
|
grep -v -f $IGNORE_REGEX_FILE $STATS_FILE | sort > $FILTERED_STATS_FILE
|
|
}
|
|
|
|
# Check that the stats in $FILTERED_STATS_FILE include the expected stats in
|
|
# $EXPECTED_STATS_FILE.
|
|
check_expected_stats () {
|
|
echo "> Checking expected stats"
|
|
grep -F -x -f $EXPECTED_STATS_FILE $FILTERED_STATS_FILE > $FOUND_STATS_FILE
|
|
if test $DEBUG -ne 0; then
|
|
echo "Found:"
|
|
cat $FOUND_STATS_FILE
|
|
fi
|
|
if diff $EXPECTED_STATS_FILE $FOUND_STATS_FILE; then
|
|
echo "OK"
|
|
else
|
|
echo "! bad expected stats:"
|
|
cat $FILTERED_STATS_FILE
|
|
end 1
|
|
fi
|
|
}
|
|
|
|
# Check that the rest (unspecified) stats are all 0 (no surprises).
|
|
check_rest_stats () {
|
|
echo "> Checking rest stats"
|
|
grep -F -x -v -f $EXPECTED_STATS_FILE $FILTERED_STATS_FILE > $REST_STATS_FILE
|
|
if test $DEBUG -ne 0; then
|
|
echo "Rest:"
|
|
cat $REST_STATS_FILE
|
|
fi
|
|
if grep -v "=0$" $REST_STATS_FILE; then
|
|
echo "! bad rest stats"
|
|
end 1
|
|
else
|
|
echo "OK"
|
|
fi
|
|
}
|
|
|
|
# Main function to check stats by:
|
|
# - Getting stats from unbound
|
|
# - Filtering out the stats we are not interested in
|
|
# - Checking that the expected stats are part of the filtered stats
|
|
# - The rest of the stats have 0 values.
|
|
check_stats () {
|
|
set_expected_stats "$1"
|
|
if test $DEBUG -ne 0; then
|
|
echo "Expected:"
|
|
cat $EXPECTED_STATS_FILE
|
|
fi
|
|
get_stats
|
|
filter_stats
|
|
if test $DEBUG -ne 0; then
|
|
echo "Filtered:"
|
|
cat $FILTERED_STATS_FILE
|
|
fi
|
|
check_expected_stats
|
|
check_rest_stats
|
|
}
|
|
|
|
# Convenient function to set an option through unbound-control.
|
|
set_ub_option () {
|
|
name=$1
|
|
value=$2
|
|
echo "$PRE/unbound-control -c ub.conf set_option $name: $value"
|
|
$PRE/unbound-control -c ub.conf set_option $name: $value
|
|
if test $? -ne 0; then
|
|
echo "wrong exit value after success"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Convenient function to exit the test.
|
|
end () {
|
|
echo "> cat logfiles"
|
|
cat fwd.log
|
|
cat unbound.log
|
|
if test $1 -eq 1; then
|
|
echo "Not OK"
|
|
else
|
|
echo "> OK"
|
|
fi
|
|
exit $1
|
|
}
|
|
|
|
# Ignore all run specific stats.
|
|
set_ignore_regex_stats "$STATS_IGNORE_DEFAULT"
|
|
|
|
# Check if the server is up.
|
|
echo "> dig 1ttl.example.com."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT 1ttl.example.com. | tee outfile
|
|
echo "> check answer"
|
|
if grep "1.1.1.1" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
|
|
echo
|
|
echo "[ Check initial stats based on first query. ]"
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.cachemiss=1
|
|
total.num.recursivereplies=1
|
|
num.query.type.A=1
|
|
num.query.class.IN=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.flags.RD=1
|
|
num.query.flags.AD=1
|
|
num.query.edns.present=1
|
|
num.query.udpout=1
|
|
msg.cache.count=1
|
|
rrset.cache.count=1
|
|
infra.cache.count=1
|
|
num.answer.rcode.NOERROR=1"
|
|
|
|
echo
|
|
echo "[ Check stat reset. ]"
|
|
check_stats "\
|
|
msg.cache.count=1
|
|
rrset.cache.count=1
|
|
infra.cache.count=1"
|
|
|
|
|
|
echo
|
|
echo "[ Enable serve-expired and check. ]"
|
|
set_ub_option serve-expired yes
|
|
sleep 2 # make sure the TTL has expired.
|
|
echo "> dig 1ttl.example.com."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT 1ttl.example.com. | tee outfile
|
|
echo "> check answer"
|
|
if grep "1.1.1.1" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.expired=1
|
|
total.num.cachehits=1
|
|
total.num.prefetch=1
|
|
num.answer.rcode.NOERROR=1
|
|
num.query.class.IN=1
|
|
num.query.edns.present=1
|
|
num.query.flags.AD=1
|
|
num.query.flags.RD=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.type.A=1
|
|
num.query.udpout=1
|
|
msg.cache.count=1
|
|
rrset.cache.count=1
|
|
infra.cache.count=1"
|
|
|
|
|
|
echo
|
|
echo "[ Enable serve-expired-client-timeout and check. ]"
|
|
set_ub_option serve-expired-client-timeout 1
|
|
echo "> dig servfail.expired."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT servfail.expired. | tee outfile
|
|
echo "> check answer"
|
|
if grep "192.0.2.1" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.cachemiss=1
|
|
total.num.recursivereplies=1
|
|
num.query.type.A=1
|
|
num.query.class.IN=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.flags.RD=1
|
|
num.query.flags.AD=1
|
|
num.query.edns.present=1
|
|
num.query.udpout=1
|
|
msg.cache.count=2
|
|
rrset.cache.count=2
|
|
infra.cache.count=2
|
|
num.answer.rcode.NOERROR=1"
|
|
kill_pid $FWD_EXPIRED_PID # kill the expired forwarder to force a servfail from upstream.
|
|
sleep 2 # make sure the TTL has expired.
|
|
echo "> dig servfail.expired."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT servfail.expired. | tee outfile
|
|
echo "> check answer"
|
|
if grep "192.0.2.1" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
sleep 1 # make sure the outgoing UDP (and the edns1xx0 retry) are accounted for.
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.expired=1
|
|
total.num.recursivereplies=1
|
|
num.answer.rcode.NOERROR=1
|
|
num.query.class.IN=1
|
|
num.query.edns.present=1
|
|
num.query.flags.AD=1
|
|
num.query.flags.RD=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.type.A=1
|
|
num.query.udpout=2
|
|
total.num.cachemiss=1
|
|
msg.cache.count=2
|
|
rrset.cache.count=2
|
|
infra.cache.count=2"
|
|
|
|
|
|
# Disable serve-expired
|
|
set_ub_option serve-expired no
|
|
|
|
|
|
echo
|
|
echo "[ Check REFUSED; try without RD flag. ]"
|
|
echo "> dig somethingelse.example.com."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT +nordflag somethingelse.example.com. | tee outfile
|
|
echo "> check answer"
|
|
if grep "REFUSED" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
num.answer.rcode.REFUSED=1
|
|
total.num.cachehits=1
|
|
num.query.class.IN=1
|
|
num.query.edns.present=1
|
|
num.query.flags.AD=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.type.A=1
|
|
total.num.queries=1
|
|
msg.cache.count=2
|
|
rrset.cache.count=2
|
|
infra.cache.count=2"
|
|
|
|
|
|
echo
|
|
echo "[ Check the AD flag. ]"
|
|
echo "> dig www.example.com."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT +noadflag www.example.com. | tee outfile
|
|
echo "> check answer"
|
|
if grep "10.20.30.40" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
num.query.flags.AD=0
|
|
total.num.cachemiss=1
|
|
num.answer.rcode.NOERROR=1
|
|
num.query.class.IN=1
|
|
num.query.edns.present=1
|
|
num.query.flags.RD=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.type.A=1
|
|
num.query.udpout=1
|
|
total.num.queries=1
|
|
total.num.recursivereplies=1
|
|
msg.cache.count=3
|
|
rrset.cache.count=3
|
|
infra.cache.count=2"
|
|
|
|
echo
|
|
echo "[ Check local zone. ]"
|
|
echo "> dig www.local.zone."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT www.local.zone. | tee outfile
|
|
echo "> check answer"
|
|
if grep "192.0.2.1" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
num.answer.rcode.NOERROR=1
|
|
total.num.cachehits=1
|
|
num.query.class.IN=1
|
|
num.query.edns.present=1
|
|
num.query.flags.AD=1
|
|
num.query.flags.RD=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.type.A=1
|
|
total.num.queries=1
|
|
msg.cache.count=3
|
|
rrset.cache.count=3
|
|
infra.cache.count=2"
|
|
|
|
|
|
echo
|
|
echo "[ Check NXDOMAIN (with local data). ]"
|
|
echo "> dig mail.local.zone."
|
|
dig @127.0.0.1 -p $UNBOUND_PORT mail.local.zone. | tee outfile
|
|
echo "> check answer"
|
|
if grep "NXDOMAIN" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
num.answer.rcode.NXDOMAIN=1
|
|
total.num.cachehits=1
|
|
num.query.class.IN=1
|
|
num.query.edns.present=1
|
|
num.query.flags.AD=1
|
|
num.query.flags.RD=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.type.A=1
|
|
total.num.queries=1
|
|
msg.cache.count=3
|
|
rrset.cache.count=3
|
|
infra.cache.count=2"
|
|
|
|
|
|
echo
|
|
echo "[ Check CHAOS. ]"
|
|
echo "> dig id.server. ch txt"
|
|
dig @127.0.0.1 -p $UNBOUND_PORT id.server. ch txt | tee outfile
|
|
echo "> check answer"
|
|
if grep "stat_values" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
num.query.class.CH=1
|
|
total.num.cachehits=1
|
|
num.answer.rcode.NOERROR=1
|
|
num.query.edns.present=1
|
|
num.query.flags.AD=1
|
|
num.query.flags.RD=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.type.TXT=1
|
|
total.num.queries=1
|
|
msg.cache.count=3
|
|
rrset.cache.count=3
|
|
infra.cache.count=2"
|
|
|
|
|
|
# Bring the downstream DNS Cookies configured Unbound up
|
|
kill_pid $UNBOUND_PID # kill current Unbound
|
|
$PRE/unbound -d -c ub_downstream_cookies.conf >unbound.log 2>&1 &
|
|
UNBOUND_PID=$!
|
|
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
|
wait_unbound_up unbound.log
|
|
|
|
echo
|
|
echo "[ Get a DNS Cookie. ]"
|
|
echo "> dig www.local.zone +tcp +ednsopt=10:0102030405060708"
|
|
dig @127.0.0.1 -p $UNBOUND_PORT +tcp +ednsopt=10:0102030405060708 +retry=0 +time=1 www.local.zone. | tee outfile
|
|
echo "> check answer"
|
|
if grep "192.0.2.1" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
# Save valid cookie
|
|
valid_cookie=`grep "COOKIE: " outfile | cut -d ' ' -f 3`
|
|
invalid_cookie=`echo $valid_cookie | tr '0' '4'`
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.queries_cookie_client=1
|
|
total.num.cachehits=1
|
|
num.query.type.A=1
|
|
num.query.class.IN=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.flags.RD=1
|
|
num.query.flags.AD=1
|
|
num.query.edns.present=1
|
|
num.query.tcp=1
|
|
num.answer.rcode.NOERROR=1"
|
|
|
|
echo
|
|
echo "[ Present the valid DNS Cookie. ]"
|
|
echo "> dig www.local.zone +ednsopt=10:valid_cookie"
|
|
dig @127.0.0.1 -p $UNBOUND_PORT +ednsopt=10:$valid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
|
|
echo "> check answer"
|
|
if grep "192.0.2.1" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.queries_cookie_valid=1
|
|
total.num.cachehits=1
|
|
num.query.type.A=1
|
|
num.query.class.IN=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.flags.RD=1
|
|
num.query.flags.AD=1
|
|
num.query.edns.present=1
|
|
num.answer.rcode.NOERROR=1"
|
|
|
|
echo
|
|
echo "[ Present an invalid DNS Cookie. ]"
|
|
echo "> dig www.local.zone +ednsopt=10:invalid_cookie"
|
|
dig @127.0.0.1 -p $UNBOUND_PORT +ednsopt=10:$invalid_cookie +retry=0 +time=1 www.local.zone. | tee outfile
|
|
echo "> check answer"
|
|
if grep "192.0.2.1" outfile; then
|
|
end 1
|
|
else
|
|
echo "OK"
|
|
fi
|
|
# A lot of stats are missing since BADCOOKIE error response is before
|
|
# those stat calculations.
|
|
# BADCOOKIE is an extended error code; we record YXRRSET below.
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.queries_cookie_invalid=1
|
|
total.num.cachehits=1
|
|
num.answer.rcode.YXRRSET=1"
|
|
|
|
echo
|
|
echo "[ Present no DNS Cookie. ]"
|
|
echo "> dig www.local.zone +ignore"
|
|
dig @127.0.0.1 -p $UNBOUND_PORT +ignore +retry=0 +time=1 www.local.zone. | tee outfile
|
|
echo "> check answer"
|
|
if grep "192.0.2.1" outfile; then
|
|
end 1
|
|
else
|
|
echo "OK"
|
|
fi
|
|
# A lot of stats are missing since REFUSED error response because of no DNS
|
|
# Cookie is before those stat calculations.
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.cachehits=1
|
|
num.answer.rcode.REFUSED=1"
|
|
|
|
if test x$USE_CACHEDB = "x1"; then
|
|
|
|
# Bring the cachedb configured Unbound up
|
|
kill_pid $UNBOUND_PID # kill current Unbound
|
|
$PRE/unbound -d -c ub_cachedb.conf >unbound.log 2>&1 &
|
|
UNBOUND_PID=$!
|
|
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
|
wait_unbound_up unbound.log
|
|
|
|
echo
|
|
echo "[ Check cachedb cache miss. ]"
|
|
echo "> dig www.example.com."
|
|
dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
|
|
echo "> check answer"
|
|
if grep "10.20.30.40" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.cachemiss=1
|
|
total.num.cachehits=0
|
|
total.num.recursivereplies=1
|
|
num.query.type.A=1
|
|
num.query.class.IN=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.flags.RD=1
|
|
num.query.flags.AD=1
|
|
num.query.edns.present=1
|
|
num.query.udpout=1
|
|
num.query.cachedb=0
|
|
msg.cache.count=1
|
|
rrset.cache.count=1
|
|
infra.cache.count=1
|
|
num.answer.rcode.NOERROR=1"
|
|
|
|
echo
|
|
echo "[ Check cachedb cache hit. ]"
|
|
echo "> dig www.example.com."
|
|
dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
|
|
echo "> check answer"
|
|
if grep "10.20.30.40" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.cachemiss=1
|
|
total.num.cachehits=0
|
|
total.num.recursivereplies=1
|
|
num.query.type.A=1
|
|
num.query.class.IN=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.flags.RD=1
|
|
num.query.flags.AD=1
|
|
num.query.edns.present=1
|
|
num.query.udpout=0
|
|
num.query.cachedb=1
|
|
msg.cache.count=1
|
|
rrset.cache.count=1
|
|
infra.cache.count=1
|
|
num.answer.rcode.NOERROR=1"
|
|
|
|
echo
|
|
echo "[ Check cachedb cache hit with stat reset ]"
|
|
echo "> dig www.example.com."
|
|
dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile
|
|
echo "> check answer"
|
|
if grep "10.20.30.40" outfile; then
|
|
echo "OK"
|
|
else
|
|
end 1
|
|
fi
|
|
check_stats "\
|
|
total.num.queries=1
|
|
total.num.cachemiss=1
|
|
total.num.cachehits=0
|
|
total.num.recursivereplies=1
|
|
num.query.type.A=1
|
|
num.query.class.IN=1
|
|
num.query.opcode.QUERY=1
|
|
num.query.flags.RD=1
|
|
num.query.flags.AD=1
|
|
num.query.edns.present=1
|
|
num.query.cachedb=1
|
|
msg.cache.count=1
|
|
rrset.cache.count=1
|
|
infra.cache.count=1
|
|
num.answer.rcode.NOERROR=1"
|
|
|
|
fi # USE_CACHEDB
|
|
|
|
end 0
|