2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

"rndc fetchlimit" now also lists rate-limited domains

"rndc fetchlimit" now also prints a list of domain names that are
currently rate-limited by "fetches-per-zone".

The "fetchlimit" system test has been updated to use this feature
to check that domain limits are applied correctly.
This commit is contained in:
Evan Hunt
2022-05-26 14:43:23 -07:00
parent 6175897478
commit 549cf0f3e6
6 changed files with 98 additions and 7 deletions

View File

@@ -16622,7 +16622,7 @@ named_server_fetchlimit(named_server_t *server, isc_lex_t *lex,
for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
view = ISC_LIST_NEXT(view, link))
{
char tbuf[BUFSIZ];
char tbuf[100];
unsigned int used;
uint32_t val;
int s;
@@ -16658,6 +16658,21 @@ named_server_fetchlimit(named_server_t *server, isc_lex_t *lex,
if (used == isc_buffer_usedlength(*text)) {
putstr(text, "\n None.");
}
putstr(text, "\nRate limited servers, view ");
putstr(text, view->name);
val = dns_resolver_getfetchesperzone(view->resolver);
s = snprintf(tbuf, sizeof(tbuf),
" (fetches-per-zone %u):", val);
if (s < 0 || (unsigned)s > sizeof(tbuf)) {
return (ISC_R_NOSPACE);
}
putstr(text, tbuf);
used = isc_buffer_usedlength(*text);
CHECK(dns_resolver_dumpquota(view->resolver, text));
if (used == isc_buffer_usedlength(*text)) {
putstr(text, "\n None.");
}
}
cleanup:

View File

@@ -206,8 +206,10 @@ Currently supported commands are:
.. option:: fetchlimit [view]
This command dumps a list of servers which are currently being
rate-limited as a result of ``fetches-per-server`` settings.
This command dumps a list of servers that are currently being
rate-limited as a result of ``fetches-per-server`` settings, and
a list of domain names that are currently being rate-limited as
a result of ``fetches-per-zone`` settings.
.. option:: flush

View File

@@ -128,9 +128,10 @@ for try in 1 2 3 4 5; do
success=$((success+1))
grep "status: SERVFAIL" dig.out.ns3.$try > /dev/null 2>&1 && \
fail=$(($fail+1))
stat 30 50 || ret=1
stat 40 40 || ret=1
allowed=$($RNDCCMD fetchlimit | awk '/lamesub/ { print $6 }')
[ "${allowed:-0}" -eq 40 ] || 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"

View File

@@ -227,8 +227,10 @@ Manual.)
.INDENT 0.0
.TP
.B fetchlimit [view]
This command dumps a list of servers which are currently being
rate\-limited as a result of \fBfetches\-per\-server\fP settings.
This command dumps a list of servers that are currently being
rate\-limited as a result of \fBfetches\-per\-server\fP settings, and
a list of domain names that are currently being rate\-limited as
a result of \fBfetches\-per\-zone\fP settings.
.UNINDENT
.INDENT 0.0
.TP

View File

@@ -534,6 +534,9 @@ dns_resolver_setclientsperquery(dns_resolver_t *resolver, uint32_t min,
void
dns_resolver_setfetchesperzone(dns_resolver_t *resolver, uint32_t clients);
uint32_t
dns_resolver_getfetchesperzone(dns_resolver_t *resolver);
void
dns_resolver_getclientsperquery(dns_resolver_t *resolver, uint32_t *cur,
uint32_t *min, uint32_t *max);
@@ -703,6 +706,8 @@ dns_resolver_getquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which);
void
dns_resolver_dumpfetches(dns_resolver_t *resolver, isc_statsformat_t format,
FILE *fp);
isc_result_t
dns_resolver_dumpquota(dns_resolver_t *res, isc_buffer_t **buf);
#ifdef ENABLE_AFL
/*%

View File

@@ -10075,6 +10075,7 @@ destroy(dns_resolver_t *res) {
}
isc_mem_put(res->mctx, res->tasks, res->ntasks * sizeof(res->tasks[0]));
RWLOCK(&res->hash_lock, isc_rwlocktype_write);
isc_ht_iter_create(res->buckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_delcurrent_next(it))
@@ -10088,8 +10089,10 @@ destroy(dns_resolver_t *res) {
}
isc_ht_iter_destroy(&it);
isc_ht_destroy(&res->buckets);
RWUNLOCK(&res->hash_lock, isc_rwlocktype_write);
isc_rwlock_destroy(&res->hash_lock);
RWLOCK(&res->zonehash_lock, isc_rwlocktype_write);
isc_ht_iter_create(res->zonebuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_delcurrent_next(it))
@@ -10109,6 +10112,7 @@ destroy(dns_resolver_t *res) {
}
isc_ht_iter_destroy(&it);
isc_ht_destroy(&res->zonebuckets);
RWUNLOCK(&res->zonehash_lock, isc_rwlocktype_write);
isc_rwlock_destroy(&res->zonehash_lock);
if (res->dispatches4 != NULL) {
@@ -11352,6 +11356,13 @@ dns_resolver_setfetchesperzone(dns_resolver_t *resolver, uint32_t clients) {
atomic_store_release(&resolver->zspill, clients);
}
uint32_t
dns_resolver_getfetchesperzone(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));
return (atomic_load_relaxed(&resolver->zspill));
}
bool
dns_resolver_getzeronosoattl(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));
@@ -11486,6 +11497,61 @@ dns_resolver_dumpfetches(dns_resolver_t *res, isc_statsformat_t format,
isc_ht_iter_destroy(&it);
}
isc_result_t
dns_resolver_dumpquota(dns_resolver_t *res, isc_buffer_t **buf) {
isc_result_t result;
isc_ht_iter_t *it = NULL;
uint_fast32_t spill;
REQUIRE(VALID_RESOLVER(res));
spill = atomic_load_acquire(&res->zspill);
if (spill == 0) {
return (ISC_R_SUCCESS);
}
RWLOCK(&res->zonehash_lock, isc_rwlocktype_read);
isc_ht_iter_create(res->zonebuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(it))
{
zonebucket_t *bucket = NULL;
isc_ht_iter_current(it, (void **)&bucket);
LOCK(&bucket->lock);
for (fctxcount_t *fc = ISC_LIST_HEAD(bucket->list); fc != NULL;
fc = ISC_LIST_NEXT(fc, link))
{
char nb[DNS_NAME_FORMATSIZE], text[BUFSIZ];
if (fc->count < spill) {
continue;
}
dns_name_format(fc->domain, nb, sizeof(nb));
snprintf(text, sizeof(text),
"\n- %s: %u active (allowed %u spilled %u)",
nb, fc->count, fc->allowed, fc->dropped);
result = isc_buffer_reserve(buf, strlen(text));
if (result != ISC_R_SUCCESS) {
UNLOCK(&bucket->lock);
goto cleanup;
}
isc_buffer_putstr(*buf, text);
}
UNLOCK(&bucket->lock);
}
if (result == ISC_R_NOMORE) {
result = ISC_R_SUCCESS;
}
cleanup:
RWUNLOCK(&res->zonehash_lock, isc_rwlocktype_read);
isc_ht_iter_destroy(&it);
return (result);
}
void
dns_resolver_setquotaresponse(dns_resolver_t *resolver, dns_quotatype_t which,
isc_result_t resp) {