diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index bc185a58af..cf1ba1b12c 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -3798,6 +3798,11 @@ system. is sent to that domain, it is recreated with the counters set to zero.) + .. note:: + + Fetches generated automatically in the result of :any:`prefetch` are + exempt from this quota. + .. namedconf:statement:: fetches-per-server :tags: server, query :short: Sets the maximum number of simultaneous iterative queries allowed to be sent by a server to an upstream name server before the server blocks additional queries. @@ -3829,6 +3834,11 @@ system. increased. The :any:`fetch-quota-params` options can be used to adjust the parameters for this calculation. + .. note:: + + Fetches generated automatically in the result of :any:`prefetch` are + exempt from this quota, but they are included in the quota calculations. + .. namedconf:statement:: fetch-quota-params :tags: server, query :short: Sets the parameters for dynamic resizing of the :any:`fetches-per-server` quota in response to detected congestion. diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 52568129f9..6e63965982 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -1478,7 +1478,9 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name) { dns_adbaddrinfo_t *addrinfo = NULL; entry = namehook->entry; - if (adbentry_overquota(entry)) { + if ((find->options & DNS_ADBFIND_QUOTAEXEMPT) == 0 && + adbentry_overquota(entry)) + { find->options |= DNS_ADBFIND_OVERQUOTA; goto nextv4; } @@ -1500,7 +1502,9 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name) { dns_adbaddrinfo_t *addrinfo = NULL; entry = namehook->entry; - if (adbentry_overquota(entry)) { + if ((find->options & DNS_ADBFIND_QUOTAEXEMPT) == 0 && + adbentry_overquota(entry)) + { find->options |= DNS_ADBFIND_OVERQUOTA; goto nextv6; } diff --git a/lib/dns/include/dns/adb.h b/lib/dns/include/dns/adb.h index cf725b62fc..65acb09ccf 100644 --- a/lib/dns/include/dns/adb.h +++ b/lib/dns/include/dns/adb.h @@ -179,6 +179,10 @@ struct dns_adbfind { * This is useful for reestablishing glue that has expired. */ #define DNS_ADBFIND_STARTATZONE 0x00000020 +/*% + * Fetches will be exempted from the quota. + */ +#define DNS_ADBFIND_QUOTAEXEMPT 0x00000040 /*% * The server's fetch quota is exceeded; it will be treated as * lame for this query. diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index ee0ca2ee2d..6a96aae5d9 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -3257,6 +3257,13 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port, options |= DNS_ADBFIND_STARTATZONE; } + /* + * Exempt prefetches from ADB quota. + */ + if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) { + options |= DNS_ADBFIND_QUOTAEXEMPT; + } + /* * See what we know about this address. */ @@ -4661,13 +4668,18 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, } /* - * Are there too many simultaneous queries for this domain? + * Exempt prefetch queries from the fetches-per-zone quota check */ - result = fcount_incr(fctx, false); - if (result != ISC_R_SUCCESS) { - result = fctx->res->quotaresp[dns_quotatype_zone]; - inc_stats(res, dns_resstatscounter_zonequota); - goto cleanup_nameservers; + if ((fctx->options & DNS_FETCHOPT_PREFETCH) == 0) { + /* + * Are there too many simultaneous queries for this domain? + */ + result = fcount_incr(fctx, false); + if (result != ISC_R_SUCCESS) { + result = fctx->res->quotaresp[dns_quotatype_zone]; + inc_stats(res, dns_resstatscounter_zonequota); + goto cleanup_nameservers; + } } log_ns_ttl(fctx, "fctx_create");