diff --git a/CHANGES b/CHANGES index ccec1b2cf5..279d26fac2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +5890. [bug] When the fetches-per-server quota was adjusted + because of an authoritative server timing out more + or less frequently, it was incorrectly set to 1 + rather than the intended value. This has been + fixed. [GL #3327] + 5885. [bug] RPZ NSIP and NSDNAME rule processing didn't handle stub and static-stub zones at or above the query name. This has now been addressed. [GL #3232] diff --git a/bin/tests/system/fetchlimit/ns3/named1.conf.in b/bin/tests/system/fetchlimit/ns3/named1.conf.in index ab7c25a0af..3adfe473eb 100644 --- a/bin/tests/system/fetchlimit/ns3/named1.conf.in +++ b/bin/tests/system/fetchlimit/ns3/named1.conf.in @@ -28,6 +28,10 @@ options { fetches-per-server 400; }; +server 10.53.0.4 { + edns no; +}; + key rndc_key { secret "1234abcd8765"; algorithm hmac-sha256; diff --git a/bin/tests/system/fetchlimit/ns3/named2.conf.in b/bin/tests/system/fetchlimit/ns3/named2.conf.in index 27c5f33e3b..74374b106f 100644 --- a/bin/tests/system/fetchlimit/ns3/named2.conf.in +++ b/bin/tests/system/fetchlimit/ns3/named2.conf.in @@ -26,6 +26,10 @@ options { fetches-per-zone 40; }; +server 10.53.0.4 { + edns no; +}; + key rndc_key { secret "1234abcd8765"; algorithm hmac-sha256; diff --git a/bin/tests/system/fetchlimit/ns3/named3.conf.in b/bin/tests/system/fetchlimit/ns3/named3.conf.in index a5d1c165fb..3df353b07d 100644 --- a/bin/tests/system/fetchlimit/ns3/named3.conf.in +++ b/bin/tests/system/fetchlimit/ns3/named3.conf.in @@ -26,6 +26,10 @@ options { recursive-clients 400; }; +server 10.53.0.4 { + edns no; +}; + key rndc_key { secret "1234abcd8765"; algorithm hmac-sha256; diff --git a/bin/tests/system/fetchlimit/tests.sh b/bin/tests/system/fetchlimit/tests.sh index 22235c1a3b..c10bee6677 100644 --- a/bin/tests/system/fetchlimit/tests.sh +++ b/bin/tests/system/fetchlimit/tests.sh @@ -20,7 +20,7 @@ burst() { num=${3:-20} rm -f burst.input.$$ while [ $num -gt 0 ]; do - num=`expr $num - 1` + num=$((num-1)) echo "${num}${1}${2}.lamesub.example A" >> burst.input.$$ done $PERL ../ditch.pl -p ${PORT} -s 10.53.0.3 burst.input.$$ @@ -32,7 +32,9 @@ stat() { sed 's;.*: \([^/][^/]*\)/.*;\1;'` echo_i "clients: $clients" [ "$clients" = "" ] && return 1 - [ "$clients" -le $1 ] + [ "$clients" -ge $1 ] || return 1 + [ "$clients" -le $2 ] || return 1 + return 0 } status=0 @@ -46,13 +48,14 @@ for try in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do burst a $try # fetches-per-server is at 400, but at 20qps against a lame server, # we'll reach 200 at the tenth second, and the quota should have been - # tuned to less than that by then - stat 200 || ret=1 + # tuned to less than that by then. + [ $try -le 5 ] && low=$((try*10)) + stat 20 200 || ret=1 [ $ret -eq 1 ] && break sleep 1 done if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` +status=$((status+ret)) echo_i "dumping ADB data" $RNDCCMD dumpdb -adb @@ -76,14 +79,14 @@ fails=`grep 'queries resulted in SERVFAIL' ns3/named.stats | sed 's/\([0-9][0-9] [ -z "$fails" ] && fails=0 [ "$fails" -ge "$sspill" ] || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` +status=$((status+ret)) echo_i "checking lame server recovery" ret=0 rm -f ans4/norespond for try in 1 2 3 4 5; do burst b $try - stat 200 || ret=1 + stat 0 200 || ret=1 [ $ret -eq 1 ] && break sleep 1 done @@ -98,7 +101,7 @@ quota=$5 for try in 1 2 3 4 5 6 7 8 9 10; do burst c $try - stat 20 || ret=1 + stat 0 20 || ret=1 [ $ret -eq 1 ] && break sleep 1 done @@ -111,7 +114,7 @@ set -- $info [ ${5:-${quota}} -gt $quota ] || ret=1 quota=$5 if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` +status=$((status+ret)) copy_setports ns3/named2.conf.in ns3/named.conf rndc_reconfig ns3 10.53.0.3 @@ -125,17 +128,17 @@ for try in 1 2 3 4 5; do burst b $try 300 $DIGCMD a ${try}.example > dig.out.ns3.$try grep "status: NOERROR" dig.out.ns3.$try > /dev/null 2>&1 && \ - success=`expr $success + 1` + success=$((success+1)) grep "status: SERVFAIL" dig.out.ns3.$try > /dev/null 2>&1 && \ - fail=`expr $fail + 1` - stat 50 || ret=1 + fail=$(($fail+1)) + stat 30 50 || ret=1 [ $ret -eq 1 ] && break $RNDCCMD recursing 2>&1 | sed 's/^/ns3 /' | cat_i sleep 1 done echo_i "$success successful valid queries, $fail SERVFAIL" if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` +status=$((status+ret)) echo_i "checking drop statistics" rm -f ns3/named.stats @@ -150,7 +153,7 @@ drops=`grep 'queries dropped' ns3/named.stats | sed 's/\([0-9][0-9]*\) queries.* [ -z "$drops" ] && drops=0 [ "$drops" -ge "$zspill" ] || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` +status=$((status+ret)) copy_setports ns3/named3.conf.in ns3/named.conf rndc_reconfig ns3 10.53.0.3 @@ -164,11 +167,11 @@ touch ans4/norespond for try in 1 2 3 4 5; do burst b $try 400 $DIGCMD +time=2 a ${try}.example > dig.out.ns3.$try - stat 400 || exceeded=`expr $exceeded + 1` + stat 100 400 || exceeded=$((exceeded + 1)) grep "status: NOERROR" dig.out.ns3.$try > /dev/null 2>&1 && \ - success=`expr $success + 1` + success=$((success+1)) grep "status: SERVFAIL" dig.out.ns3.$try > /dev/null 2>&1 && \ - fail=`expr $fail + 1` + fail=$(($fail+1)) sleep 1 done echo_i "$success successful valid queries (expected 5)" @@ -178,7 +181,7 @@ echo_i "$fail SERVFAIL responses (expected 0)" echo_i "clients count exceeded 400 on $exceeded trials (expected 0)" [ "$exceeded" -eq 0 ] || { echo_i "failed"; ret=1; } if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` +status=$((status+ret)) echo_i "checking drop statistics" rm -f ns3/named.stats @@ -190,7 +193,7 @@ done drops=`grep 'queries dropped due to recursive client limit' ns3/named.stats | sed 's/\([0-9][0-9]*\) queries.*/\1/'` [ "${drops:-0}" -ne 0 ] || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi -status=`expr $status + $ret` +status=$((status+ret)) echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/adb.c b/lib/dns/adb.c index a66cc2fe7d..2eef79bb47 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -4261,7 +4261,7 @@ maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, bool timeout) { uint_fast32_t new_quota = adb->quota * quota_adj[--addr->entry->mode] / 10000; atomic_store_release(&addr->entry->quota, - ISC_MIN(1, new_quota)); + ISC_MAX(1, new_quota)); log_quota(addr->entry, "atr %0.2f, quota increased to %" PRIuFAST32, addr->entry->atr, new_quota); @@ -4271,7 +4271,7 @@ maybe_adjust_quota(dns_adb_t *adb, dns_adbaddrinfo_t *addr, bool timeout) { uint_fast32_t new_quota = adb->quota * quota_adj[++addr->entry->mode] / 10000; atomic_store_release(&addr->entry->quota, - ISC_MIN(1, new_quota)); + ISC_MAX(1, new_quota)); log_quota(addr->entry, "atr %0.2f, quota decreased to %" PRIuFAST32, addr->entry->atr, new_quota); diff --git a/lib/ns/query.c b/lib/ns/query.c index 8362f56a2b..eb2b44b70c 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -2530,10 +2530,11 @@ prefetch_done(isc_task_t *task, isc_event_t *event) { */ if (client->recursionquota != NULL) { isc_quota_detach(&client->recursionquota); - ns_stats_decrement(client->sctx->nsstats, - ns_statscounter_recursclients); } + ns_stats_decrement(client->sctx->nsstats, + ns_statscounter_recursclients); + free_devent(client, &event, &devent); isc_nmhandle_detach(&client->prefetchhandle); } @@ -2561,8 +2562,6 @@ query_prefetch(ns_client_t *client, dns_name_t *qname, &client->recursionquota); switch (result) { case ISC_R_SUCCESS: - ns_stats_increment(client->sctx->nsstats, - ns_statscounter_recursclients); break; case ISC_R_SOFTQUOTA: isc_quota_detach(&client->recursionquota); @@ -2572,6 +2571,9 @@ query_prefetch(ns_client_t *client, dns_name_t *qname, } } + ns_stats_increment(client->sctx->nsstats, + ns_statscounter_recursclients); + tmprdataset = ns_client_newrdataset(client); if (tmprdataset == NULL) { return; @@ -2778,8 +2780,6 @@ query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) { &client->recursionquota); switch (result) { case ISC_R_SUCCESS: - ns_stats_increment(client->sctx->nsstats, - ns_statscounter_recursclients); break; case ISC_R_SOFTQUOTA: isc_quota_detach(&client->recursionquota); @@ -2789,6 +2789,9 @@ query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) { } } + ns_stats_increment(client->sctx->nsstats, + ns_statscounter_recursclients); + tmprdataset = ns_client_newrdataset(client); if (tmprdataset == NULL) { return; @@ -6249,10 +6252,11 @@ fetch_callback(isc_task_t *task, isc_event_t *event) { if (client->recursionquota != NULL) { isc_quota_detach(&client->recursionquota); - ns_stats_decrement(client->sctx->nsstats, - ns_statscounter_recursclients); } + ns_stats_decrement(client->sctx->nsstats, + ns_statscounter_recursclients); + LOCK(&client->manager->reclock); if (ISC_LINK_LINKED(client, rlink)) { ISC_LIST_UNLINK(client->manager->recursing, client, rlink); @@ -6386,11 +6390,6 @@ check_recursionquota(ns_client_t *client) { if (client->recursionquota == NULL) { result = isc_quota_attach(&client->sctx->recursionquota, &client->recursionquota); - if (result == ISC_R_SUCCESS || result == ISC_R_SOFTQUOTA) { - ns_stats_increment(client->sctx->nsstats, - ns_statscounter_recursclients); - } - if (result == ISC_R_SOFTQUOTA) { isc_stdtime_t now; isc_stdtime_get(&now); @@ -6473,6 +6472,9 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, return (result); } + ns_stats_increment(client->sctx->nsstats, + ns_statscounter_recursclients); + /* * Invoke the resolver. */ @@ -6763,10 +6765,11 @@ query_hookresume(isc_task_t *task, isc_event_t *event) { if (client->recursionquota != NULL) { isc_quota_detach(&client->recursionquota); - ns_stats_decrement(client->sctx->nsstats, - ns_statscounter_recursclients); } + ns_stats_decrement(client->sctx->nsstats, + ns_statscounter_recursclients); + LOCK(&client->manager->reclock); if (ISC_LINK_LINKED(client, rlink)) { ISC_LIST_UNLINK(client->manager->recursing, client, rlink); @@ -6902,6 +6905,9 @@ ns_query_hookasync(query_ctx_t *qctx, ns_query_starthookasync_t runasync, goto cleanup; } + ns_stats_increment(client->sctx->nsstats, + ns_statscounter_recursclients); + saved_qctx = isc_mem_get(client->mctx, sizeof(*saved_qctx)); qctx_save(qctx, saved_qctx); result = runasync(saved_qctx, client->mctx, arg, client->task,