if (result == ISC_R_SUCCESS) {
result = dns_resolver_createfetch(
tat->view->resolver, tatname, dns_rdatatype_null,
- domain, &nameservers, NULL, NULL, 0, 0, 0, NULL,
+ domain, &nameservers, NULL, NULL, 0, 0, 0, NULL, NULL,
tat->task, tat_done, tat, &tat->rdataset,
&tat->sigrdataset, &tat->fetch);
}
dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t);
static isc_result_t
fetch_name(dns_adbname_t *, bool, unsigned int, isc_counter_t *qc,
- dns_rdatatype_t);
+ isc_counter_t *gqc, dns_rdatatype_t);
static void
check_exit(dns_adb_t *);
static void
void *arg, const dns_name_t *name, const dns_name_t *qname,
dns_rdatatype_t qtype, unsigned int options,
isc_stdtime_t now, dns_name_t *target, in_port_t port,
- unsigned int depth, isc_counter_t *qc,
+ unsigned int depth, isc_counter_t *qc, isc_counter_t *gqc,
dns_adbfind_t **findp) {
dns_adbfind_t *find = NULL;
dns_adbname_t *adbname = NULL;
* Start V4.
*/
if (WANT_INET(wanted_fetches) &&
- fetch_name(adbname, start_at_zone, depth, qc,
+ fetch_name(adbname, start_at_zone, depth, qc, gqc,
dns_rdatatype_a) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
* Start V6.
*/
if (WANT_INET6(wanted_fetches) &&
- fetch_name(adbname, start_at_zone, depth, qc,
+ fetch_name(adbname, start_at_zone, depth, qc, gqc,
dns_rdatatype_aaaa) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
static isc_result_t
fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
- isc_counter_t *qc, dns_rdatatype_t type) {
+ isc_counter_t *qc, isc_counter_t *gqc, dns_rdatatype_t type) {
isc_result_t result;
dns_adbfetch_t *fetch = NULL;
dns_adb_t *adb;
*/
result = dns_resolver_createfetch(
adb->view->resolver, &adbname->name, type, name, nameservers,
- NULL, NULL, 0, options, depth, qc, adb->task, fetch_callback,
- adbname, &fetch->rdataset, NULL, &fetch->fetch);
+ NULL, NULL, 0, options, depth, qc, gqc, adb->task,
+ fetch_callback, adbname, &fetch->rdataset, NULL, &fetch->fetch);
if (result != ISC_R_SUCCESS) {
DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
isc_result_totext(result));
result = dns_resolver_createfetch(
rctx->view->resolver, dns_fixedname_name(&rctx->name),
- rctx->type, NULL, NULL, NULL, NULL, 0, fopts, 0, NULL,
+ rctx->type, NULL, NULL, NULL, NULL, 0, fopts, 0, NULL, NULL,
rctx->task, fetch_done, rctx, rctx->rdataset, rctx->sigrdataset,
&rctx->fetch);
void *arg, const dns_name_t *name, const dns_name_t *qname,
dns_rdatatype_t qtype, unsigned int options,
isc_stdtime_t now, dns_name_t *target, in_port_t port,
- unsigned int depth, isc_counter_t *qc, dns_adbfind_t **find);
+ unsigned int depth, isc_counter_t *qc, isc_counter_t *gqc,
+ dns_adbfind_t **find);
/*%<
* Main interface for clients. The adb will look up the name given in
* "name" and will build up a list of found addresses, and perhaps start
dns_forwarders_t *forwarders,
const isc_sockaddr_t *client, dns_messageid_t id,
unsigned int options, unsigned int depth,
- isc_counter_t *qc, isc_task_t *task,
- isc_taskaction_t action, void *arg,
+ isc_counter_t *qc, isc_counter_t *gqc,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_fetch_t **fetchp);
/*%<
bool failed;
isc_stdtime_t start;
isc_counter_t *qc;
+ isc_counter_t *gqc;
};
/*%
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_message_t *message, unsigned int options,
isc_task_t *task, isc_taskaction_t action, void *arg,
- isc_counter_t *qc, dns_validator_t **validatorp);
+ isc_counter_t *qc, isc_counter_t *gqc,
+ dns_validator_t **validatorp);
/*%<
* Start a DNSSEC validation.
*
result = dns_resolver_createfetch(
lookup->view->resolver, dns_fixedname_name(&lookup->name),
- lookup->type, NULL, NULL, NULL, NULL, 0, 0, 0, NULL,
+ lookup->type, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, NULL,
lookup->task, fetch_done, lookup, &lookup->rdataset,
&lookup->sigrdataset, &lookup->fetch);
dns_view_weakattach(ntatable->view, &view);
result = dns_resolver_createfetch(
view->resolver, nta->name, dns_rdatatype_nsec, NULL, NULL, NULL,
- NULL, 0, DNS_FETCHOPT_NONTA, 0, NULL, task, fetch_done, nta,
- &nta->rdataset, &nta->sigrdataset, &nta->fetch);
+ NULL, 0, DNS_FETCHOPT_NONTA, 0, NULL, NULL, task, fetch_done,
+ nta, &nta->rdataset, &nta->sigrdataset, &nta->fetch);
if (result != ISC_R_SUCCESS) {
nta_detach(view->mctx, &nta);
dns_view_weakdetach(&view);
bool ns_ttl_ok;
uint32_t ns_ttl;
isc_counter_t *qc;
+ isc_counter_t *gqc;
bool minimized;
unsigned int qmin_labels;
isc_result_t qmin_warning;
result = dns_validator_create(fctx->res->view, name, type, rdataset,
sigrdataset, message, valoptions, task,
- validated, valarg, fctx->qc, &validator);
+ validated, valarg, fctx->qc, fctx->gqc,
+ &validator);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (result == ISC_R_SUCCESS) {
inc_stats(fctx->res, dns_resstatscounter_val);
result = dns_adb_createfind(
fctx->adb, res->buckets[fctx->bucketnum].task, fctx_finddone,
fctx, name, fctx->name, fctx->type, options, now, NULL,
- res->view->dstport, fctx->depth + 1, fctx->qc, &find);
+ res->view->dstport, fctx->depth + 1, fctx->qc, fctx->gqc,
+ &find);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
unsigned int bucketnum;
FCTXTRACE5("try", "fctx->qc=", isc_counter_used(fctx->qc));
+ if (fctx->gqc != NULL) {
+ FCTXTRACE5("try", "fctx->gqc=", isc_counter_used(fctx->gqc));
+ }
REQUIRE(!ADDRWAIT(fctx));
bucketnum = fctx->bucketnum;
/* We've already exceeded maximum query count */
- if (isc_counter_used(fctx->qc) > res->maxqueries) {
+ if (isc_counter_used(fctx->qc) > isc_counter_getlimit(fctx->qc)) {
+ isc_log_write(
+ dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+ "exceeded max queries resolving '%s' "
+ "(max-recursion-queries, querycount=%u, maxqueries=%u)",
+ fctx->info, isc_counter_used(fctx->qc),
+ isc_counter_getlimit(fctx->qc));
+ fctx_done_detach(&fctx, DNS_R_SERVFAIL);
+ return;
+ }
+
+ if (fctx->gqc != NULL &&
+ isc_counter_used(fctx->gqc) > isc_counter_getlimit(fctx->gqc))
+ {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
- "exceeded max queries resolving '%s' "
- "(querycount=%u, maxqueries=%u)",
- fctx->info, isc_counter_used(fctx->qc),
- res->maxqueries);
+ "exceeded global max queries resolving '%s' "
+ "(max-query-count, querycount=%u, maxqueries=%u)",
+ fctx->info, isc_counter_used(fctx->gqc),
+ isc_counter_getlimit(fctx->gqc));
fctx_done_detach(&fctx, DNS_R_SERVFAIL);
return;
}
result = dns_resolver_createfetch(
fctx->res, fctx->qminname, fctx->qmintype, fctx->domain,
&fctx->nameservers, NULL, NULL, 0, options, 0, fctx->qc,
- task, resume_qmin, fctx, &fctx->qminrrset, NULL,
- &fctx->qminfetch);
+ fctx->gqc, task, resume_qmin, fctx, &fctx->qminrrset,
+ NULL, &fctx->qminfetch);
if (result != ISC_R_SUCCESS) {
fctx_unref(fctx);
fctx_done_detach(&fctx, DNS_R_SERVFAIL);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
- "exceeded max queries resolving '%s'",
- fctx->info);
+ "exceeded max queries resolving '%s' "
+ "(max-recursion-queries, querycount=%u)",
+ fctx->info, isc_counter_used(fctx->qc));
fctx_done_detach(&fctx, DNS_R_SERVFAIL);
return;
}
+ if (fctx->gqc != NULL) {
+ result = isc_counter_increment(fctx->gqc);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+ "exceeded global max queries resolving "
+ "'%s' (max-query-count, querycount=%u)",
+ fctx->info, isc_counter_used(fctx->gqc));
+ fctx_done_detach(&fctx, DNS_R_SERVFAIL);
+ return;
+ }
+ }
+
result = fctx_query(fctx, addrinfo, fctx->options);
if (result != ISC_R_SUCCESS) {
fctx_done_detach(&fctx, result);
}
isc_counter_detach(&fctx->qc);
+ if (fctx->gqc != NULL) {
+ isc_counter_detach(&fctx->gqc);
+ }
fcount_decr(fctx);
dns_message_detach(&fctx->qmessage);
if (dns_rdataset_isassociated(&fctx->nameservers)) {
dns_rdatatype_t type, const dns_name_t *domain,
dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
unsigned int options, unsigned int bucketnum, unsigned int depth,
- isc_counter_t *qc, fetchctx_t **fctxp) {
+ isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t **fctxp) {
fetchctx_t *fctx = NULL;
isc_result_t result;
isc_result_t iresult;
fctx->info, fctx->qc);
}
+ if (gqc != NULL) {
+ isc_counter_attach(gqc, &fctx->gqc);
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(9),
+ "fctx %p(%s): attached to counter %p (%d)", fctx,
+ fctx->info, fctx->gqc,
+ isc_counter_used(fctx->gqc));
+ }
+
isc_refcount_init(&fctx->references, 1);
ISC_LIST_INIT(fctx->queries);
}
isc_mem_free(res->mctx, fctx->info);
isc_counter_detach(&fctx->qc);
+ if (fctx->gqc != NULL) {
+ isc_counter_detach(&fctx->gqc);
+ }
cleanup_fetch:
dns_resolver_detach(&fctx->res);
options = fctx->options & ~DNS_FETCHOPT_TRYSTALE_ONTIMEOUT;
result = dns_resolver_createfetch(
res, fctx->nsname, dns_rdatatype_ns, domain, nsrdataset,
- NULL, NULL, 0, options, 0, fctx->qc, task,
+ NULL, NULL, 0, options, 0, fctx->qc, fctx->gqc, task,
resume_dslookup, fctx, &fctx->nsrrset, NULL,
&fctx->nsfetch);
if (result != ISC_R_SUCCESS) {
options = fctx->options & ~DNS_FETCHOPT_TRYSTALE_ONTIMEOUT;
result = dns_resolver_createfetch(
fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL,
- NULL, 0, options, 0, fctx->qc, task, resume_dslookup, fctx,
- &fctx->nsrrset, NULL, &fctx->nsfetch);
+ NULL, 0, options, 0, fctx->qc, fctx->gqc, task, resume_dslookup,
+ fctx, &fctx->nsrrset, NULL, &fctx->nsfetch);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_DUPLICATE) {
result = DNS_R_SERVFAIL;
INSIST(res->primefetch == NULL);
result = dns_resolver_createfetch(
res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL,
- NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL,
+ NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, NULL,
res->buckets[0].task, prime_done, res, rdataset, NULL,
&res->primefetch);
UNLOCK(&res->primelock);
dns_forwarders_t *forwarders,
const isc_sockaddr_t *client, dns_messageid_t id,
unsigned int options, unsigned int depth,
- isc_counter_t *qc, isc_task_t *task,
- isc_taskaction_t action, void *arg,
+ isc_counter_t *qc, isc_counter_t *gqc,
+ isc_task_t *task, isc_taskaction_t action, void *arg,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_fetch_t **fetchp) {
dns_fetch_t *fetch;
if (fctx == NULL) {
result = fctx_create(res, task, name, type, domain, nameservers,
- client, options, bucketnum, depth, qc,
+ client, options, bucketnum, depth, qc, gqc,
&fctx);
if (result != ISC_R_SUCCESS) {
goto unlock;
validator_logcreate(val, name, type, caller, "fetch");
return dns_resolver_createfetch(
val->view->resolver, name, type, NULL, NULL, NULL, NULL, 0,
- fopts, 0, NULL, val->event->ev_sender, callback, val,
+ fopts, 0, NULL, NULL, val->event->ev_sender, callback, val,
&val->frdataset, &val->fsigrdataset, &val->fetch);
}
validator_logcreate(val, name, type, caller, "validator");
result = dns_validator_create(val->view, name, type, rdataset, sig,
NULL, vopts, val->task, action, val,
- val->qc, &val->subvalidator);
+ val->qc, val->gqc, &val->subvalidator);
if (result == ISC_R_SUCCESS) {
val->subvalidator->parent = val;
val->subvalidator->depth = val->depth + 1;
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_message_t *message, unsigned int options,
isc_task_t *task, isc_taskaction_t action, void *arg,
- isc_counter_t *qc, dns_validator_t **validatorp) {
+ isc_counter_t *qc, isc_counter_t *gqc,
+ dns_validator_t **validatorp) {
isc_result_t result = ISC_R_FAILURE;
dns_validator_t *val;
isc_task_t *tclone = NULL;
if (qc != NULL) {
isc_counter_attach(qc, &val->qc);
}
+ if (gqc != NULL) {
+ isc_counter_attach(gqc, &val->gqc);
+ }
val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
dns_rdataset_init(&val->fdsset);
if (val->qc != NULL) {
isc_counter_detach(&val->qc);
}
+ if (val->gqc != NULL) {
+ isc_counter_detach(&val->gqc);
+ }
isc_mutex_destroy(&val->lock);
dns_view_weakdetach(&val->view);
isc_mem_put(mctx, val, sizeof(*val));
/*%
* KASP flags
*/
-#define KASP_LOCK(k) \
- if ((k) != NULL) { \
- LOCK((&((k)->lock))); \
+#define KASP_LOCK(k) \
+ if ((k) != NULL) { \
+ LOCK(&((k)->lock)); \
}
-#define KASP_UNLOCK(k) \
- if ((k) != NULL) { \
- UNLOCK((&((k)->lock))); \
+#define KASP_UNLOCK(k) \
+ if ((k) != NULL) { \
+ UNLOCK(&((k)->lock)); \
}
/*
NULL, NULL, 0,
DNS_FETCHOPT_NOVALIDATE | DNS_FETCHOPT_UNSHARED |
DNS_FETCHOPT_NOCACHED,
- 0, NULL, zone->task, keyfetch_done, kfetch, &kfetch->dnskeyset,
- &kfetch->dnskeysigset, &kfetch->fetch);
+ 0, NULL, NULL, zone->task, keyfetch_done, kfetch,
+ &kfetch->dnskeyset, &kfetch->dnskeysigset, &kfetch->fetch);
if (result != ISC_R_SUCCESS) {
retry_keyfetch(kfetch, kname);
result = dns_adb_createfind(
notify->zone->view->adb, notify->zone->task, process_adb_event,
notify, ¬ify->ns, dns_rootname, 0, options, 0, NULL,
- notify->zone->view->dstport, 0, NULL, ¬ify->find);
+ notify->zone->view->dstport, 0, NULL, NULL, ¬ify->find);
/* Something failed? */
if (result != ISC_R_SUCCESS) {
atomic_store(&counter->limit, limit);
}
-int
+unsigned int
isc_counter_getlimit(isc_counter_t *counter) {
REQUIRE(VALID_COUNTER(counter));
* Set the counter limit.
*/
-int
+unsigned int
isc_counter_getlimit(isc_counter_t *counter);
/*%<
* Get the counter limit.
struct ns_query {
unsigned int attributes;
unsigned int restarts;
+ isc_counter_t *qc;
bool timerset;
dns_name_t *qname;
dns_name_t *origqname;
#include <stdbool.h>
#include <string.h>
+#include <isc/counter.h>
#include <isc/hex.h>
#include <isc/mem.h>
#include <isc/once.h>
client->query.rpz_st = NULL;
}
}
+ if (client->query.qc != NULL) {
+ isc_counter_detach(&client->query.qc);
+ }
client->query.origqname = NULL;
client->query.dboptions = 0;
client->query.fetchoptions = 0;
options = client->query.fetchoptions | DNS_FETCHOPT_PREFETCH;
result = dns_resolver_createfetch(
client->view->resolver, qname, rdataset->type, NULL, NULL, NULL,
- peeraddr, client->message->id, options, 0, NULL, client->task,
- prefetch_done, client, tmprdataset, NULL,
+ peeraddr, client->message->id, options, 0, NULL, NULL,
+ client->task, prefetch_done, client, tmprdataset, NULL,
&client->query.prefetch);
if (result != ISC_R_SUCCESS) {
if (client->recursionquota != NULL) {
isc_nmhandle_attach(client->handle, &client->prefetchhandle);
result = dns_resolver_createfetch(
client->view->resolver, qname, type, NULL, NULL, NULL, peeraddr,
- client->message->id, options, 0, NULL, client->task,
+ client->message->id, options, 0, NULL, NULL, client->task,
prefetch_done, client, tmprdataset, NULL,
&client->query.prefetch);
if (result != ISC_R_SUCCESS) {
result = dns_resolver_createfetch(
client->view->resolver, qname, qtype, qdomain, nameservers,
NULL, peeraddr, client->message->id, client->query.fetchoptions,
- 0, NULL, client->task, fetch_callback, client, rdataset,
- sigrdataset, &client->query.fetch);
+ 0, NULL, client->query.qc, client->task, fetch_callback, client,
+ rdataset, sigrdataset, &client->query.fetch);
if (result != ISC_R_SUCCESS) {
if (client->recursionquota != NULL) {
isc_quota_detach(&client->recursionquota);
message->flags |= DNS_MESSAGEFLAG_AD;
}
+ /*
+ * Start global outgoing query count.
+ */
+ result = isc_counter_create(client->manager->mctx,
+ client->view->max_queries,
+ &client->query.qc);
+ if (result != ISC_R_SUCCESS) {
+ query_next(client, result);
+ return;
+ }
+
(void)query_setup(client, qtype);
}