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:
@@ -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:
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
/*%
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user