]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Implement global limit for outgoing queries
authorMatthijs Mekking <matthijs@isc.org>
Mon, 11 Nov 2024 10:01:50 +0000 (11:01 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 5 Dec 2024 13:17:07 +0000 (14:17 +0100)
This global limit is not reset on query restarts and is a hard limit
for any client request.

15 files changed:
bin/named/server.c
lib/dns/adb.c
lib/dns/client.c
lib/dns/include/dns/adb.h
lib/dns/include/dns/resolver.h
lib/dns/include/dns/validator.h
lib/dns/include/dns/view.h
lib/dns/nta.c
lib/dns/resolver.c
lib/dns/validator.c
lib/dns/zone.c
lib/isc/counter.c
lib/isc/include/isc/counter.h
lib/ns/include/ns/query.h
lib/ns/query.c

index 085d0baea2c94f54317d96d73b9d8842f06949cb..38fe7ef64291ee1207e6f4e92e6b0ff8ef288c32 100644 (file)
@@ -7037,7 +7037,7 @@ tat_send(void *arg) {
        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->loop, tat_done, tat, &tat->rdataset,
                        &tat->sigrdataset, &tat->fetch);
        }
index 13e6bca9b8fa515c9622e9bd28c6e37beae90c4d..23017a759ade214d84a8f47ce1eb81b96e9bddad 100644 (file)
@@ -333,7 +333,7 @@ static isc_result_t
 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
 destroy(dns_adb_t *);
 static void
@@ -1923,7 +1923,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
                   const dns_name_t *name, const dns_name_t *qname,
                   dns_rdatatype_t qtype ISC_ATTR_UNUSED, 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) {
        isc_result_t result = ISC_R_UNEXPECTED;
        dns_adbfind_t *find = NULL;
@@ -2133,7 +2133,7 @@ fetch:
                 * 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,
@@ -2146,7 +2146,7 @@ fetch:
                 * 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,
@@ -2952,7 +2952,7 @@ out:
 
 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 = NULL;
@@ -3008,7 +3008,7 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
         */
        result = dns_resolver_createfetch(
                adb->res, adbname->name, type, name, nameservers, NULL, NULL, 0,
-               options, depth, qc, isc_loop(), fetch_callback, adbname,
+               options, depth, qc, gqc, isc_loop(), fetch_callback, adbname,
                &fetch->rdataset, NULL, &fetch->fetch);
        if (result != ISC_R_SUCCESS) {
                DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
index 96043e0266ea0adc2975756bc9cb5b1388fc70f0..26c7acf8d41cfe2504bef18537648ff33dfbf1ee 100644 (file)
@@ -456,7 +456,7 @@ start_fetch(resctx_t *rctx) {
 
        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->client->loop, fetch_done, rctx, rctx->rdataset,
                rctx->sigrdataset, &rctx->fetch);
 
index 7288cdd527940dd72502b64ba444c3f9373f84f4..585f0f6c9b5e74ffded6b291d88912142ea73848 100644 (file)
@@ -281,7 +281,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
                   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
index b65e2aa78c315814139eb67b5783971a4276740d..579bce623acf5d87d698ad19eb931bcda8ec2eb5 100644 (file)
@@ -272,9 +272,10 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                         dns_forwarders_t     *forwarders,
                         const isc_sockaddr_t *client, dns_messageid_t id,
                         unsigned int options, unsigned int depth,
-                        isc_counter_t *qc, isc_loop_t *loop, isc_job_cb cb,
-                        void *arg, dns_rdataset_t *rdataset,
-                        dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp);
+                        isc_counter_t *qc, isc_counter_t *gqc,
+                        isc_loop_t *loop, isc_job_cb cb, void *arg,
+                        dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+                        dns_fetch_t **fetchp);
 /*%<
  * Recurse to answer a question.
  *
index 249687d7569090b676b559457edef992139ac8ff..09dc3a13a305636132e880ca77bbb7b45d53e2e5 100644 (file)
@@ -154,6 +154,7 @@ struct dns_validator {
        uint32_t      *nvalidations;
        uint32_t      *nfails;
        isc_counter_t *qc;
+       isc_counter_t *gqc;
 };
 
 /*%
@@ -172,7 +173,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
                     dns_message_t *message, unsigned int options,
                     isc_loop_t *loop, isc_job_cb cb, void *arg,
                     uint32_t *nvalidations, uint32_t *nfails,
-                    isc_counter_t *qc, dns_validator_t **validatorp);
+                    isc_counter_t *qc, isc_counter_t *gqc,
+                    dns_validator_t **validatorp);
 /*%<
  * Start a DNSSEC validation.
  *
index a82d860d98a2c4392c7f7aa8894e6615b581f340..88c888c7dcb8db3a368a2dde5e768adee32bc2b5 100644 (file)
@@ -1348,5 +1348,4 @@ dns_view_setmaxqueries(dns_view_t *view, uint16_t max_queries);
  *\li  'max_queries' is greater than 0.
  */
 
-
 ISC_LANG_ENDDECLS
index acd788795faec1ec9d4642b96736e599419434ba..e428b5c7ef9310917d60bfdcb0f5cf93f0f1479f 100644 (file)
@@ -240,8 +240,9 @@ checkbogus(void *arg) {
        dns__nta_ref(nta); /* for dns_resolver_createfetch */
        result = dns_resolver_createfetch(
                resolver, &nta->name, dns_rdatatype_nsec, NULL, NULL, NULL,
-               NULL, 0, DNS_FETCHOPT_NONTA, 0, NULL, nta->loop, fetch_done,
-               nta, &nta->rdataset, &nta->sigrdataset, &nta->fetch);
+               NULL, 0, DNS_FETCHOPT_NONTA, 0, NULL, NULL, nta->loop,
+               fetch_done, nta, &nta->rdataset, &nta->sigrdataset,
+               &nta->fetch);
        if (result != ISC_R_SUCCESS) {
                dns__nta_detach(&nta); /* for dns_resolver_createfetch() */
        }
index 5d5b0947432f4b1a4ad9da593daa567d3b7815c9..af402c1b95b04baa2ee434bb53d0827e59a27d4c 100644 (file)
@@ -388,6 +388,7 @@ struct fetchctx {
        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;
@@ -707,7 +708,7 @@ get_attached_fctx(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
                  dns_rdatatype_t type, const dns_name_t *domain,
                  dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
                  unsigned int options, unsigned int depth, isc_counter_t *qc,
-                 fetchctx_t **fctxp, bool *new_fctx);
+                 isc_counter_t *gqc, fetchctx_t **fctxp, bool *new_fctx);
 static void
 release_fctx(fetchctx_t *fctx);
 
@@ -981,7 +982,7 @@ valcreate(fetchctx_t *fctx, dns_message_t *message, dns_adbaddrinfo_t *addrinfo,
        result = dns_validator_create(
                fctx->res->view, name, type, rdataset, sigrdataset, message,
                valoptions, fctx->loop, validated, valarg, &fctx->nvalidations,
-               &fctx->nfails, fctx->qc, &validator);
+               &fctx->nfails, fctx->qc, fctx->gqc, &validator);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
        inc_stats(fctx->res, dns_resstatscounter_val);
        if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
@@ -3279,7 +3280,7 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
        result = dns_adb_createfind(fctx->adb, fctx->loop, fctx_finddone, fctx,
                                    name, fctx->name, fctx->type, options, now,
                                    NULL, res->view->dstport, fctx->depth + 1,
-                                   fctx->qc, &find);
+                                   fctx->qc, fctx->gqc, &find);
 
        isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
                      ISC_LOG_DEBUG(3), "fctx %p(%s): createfind for %s - %s",
@@ -3989,6 +3990,9 @@ fctx_try(fetchctx_t *fctx, bool retrying) {
        dns_resolver_t *res = NULL;
 
        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));
        REQUIRE(fctx->tid == isc_tid());
@@ -3996,13 +4000,27 @@ fctx_try(fetchctx_t *fctx, bool retrying) {
        res = fctx->res;
 
        /* 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_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));
+               result = DNS_R_SERVFAIL;
+               goto done;
+       }
+
+       if (fctx->gqc != NULL &&
+           isc_counter_used(fctx->gqc) > isc_counter_getlimit(fctx->gqc))
+       {
                isc_log_write(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));
                result = DNS_R_SERVFAIL;
                goto done;
        }
@@ -4100,8 +4118,8 @@ fctx_try(fetchctx_t *fctx, bool retrying) {
                result = dns_resolver_createfetch(
                        fctx->res, fctx->qminname, fctx->qmintype, fctx->domain,
                        &fctx->nameservers, NULL, NULL, 0, options, 0, fctx->qc,
-                       fctx->loop, resume_qmin, fctx, &fctx->qminrrset, NULL,
-                       &fctx->qminfetch);
+                       fctx->gqc, fctx->loop, resume_qmin, fctx,
+                       &fctx->qminrrset, NULL, &fctx->qminfetch);
                if (result != ISC_R_SUCCESS) {
                        fetchctx_unref(fctx);
                        goto done;
@@ -4113,11 +4131,24 @@ fctx_try(fetchctx_t *fctx, bool retrying) {
        if (result != ISC_R_SUCCESS) {
                isc_log_write(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));
                goto done;
        }
 
+       if (fctx->gqc != NULL) {
+               result = isc_counter_increment(fctx->gqc);
+               if (result != ISC_R_SUCCESS) {
+                       isc_log_write(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));
+                       goto done;
+               }
+       }
+
        result = fctx_query(fctx, addrinfo, fctx->options);
        if (result != ISC_R_SUCCESS) {
                goto done;
@@ -4349,6 +4380,9 @@ fctx_destroy(fetchctx_t *fctx) {
        }
 
        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)) {
@@ -4506,7 +4540,7 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
            dns_rdatatype_t type, const dns_name_t *domain,
            dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
            unsigned int options, unsigned int depth, isc_counter_t *qc,
-           fetchctx_t **fctxp) {
+           isc_counter_t *gqc, fetchctx_t **fctxp) {
        fetchctx_t *fctx = NULL;
        isc_result_t result;
        isc_result_t iresult;
@@ -4574,6 +4608,15 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
                              fctx->info, fctx->qc);
        }
 
+       if (gqc != NULL) {
+               isc_counter_attach(gqc, &fctx->gqc);
+               isc_log_write(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));
+       }
+
 #if DNS_RESOLVER_TRACE
        fprintf(stderr, "fetchctx__init:%s:%s:%d:%p:%p->references = 1\n",
                __func__, __FILE__, __LINE__, fctx, fctx);
@@ -4783,6 +4826,9 @@ cleanup_nameservers:
        }
        isc_mem_free(fctx->mctx, fctx->info);
        isc_counter_detach(&fctx->qc);
+       if (fctx->gqc != NULL) {
+               isc_counter_detach(&fctx->gqc);
+       }
 
 cleanup_fetch:
        dns_resolver_detach(&fctx->res);
@@ -7147,8 +7193,8 @@ resume_dslookup(void *arg) {
                fetchctx_ref(fctx);
                result = dns_resolver_createfetch(
                        res, fctx->nsname, dns_rdatatype_ns, domain, nsrdataset,
-                       NULL, NULL, 0, fctx->options, 0, fctx->qc, loop,
-                       resume_dslookup, fctx, &fctx->nsrrset, NULL,
+                       NULL, NULL, 0, fctx->options, 0, fctx->qc, fctx->gqc,
+                       loop, resume_dslookup, fctx, &fctx->nsrrset, NULL,
                        &fctx->nsfetch);
                if (result != ISC_R_SUCCESS) {
                        fetchctx_unref(fctx);
@@ -9571,7 +9617,7 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message,
        fetchctx_ref(fctx);
        result = dns_resolver_createfetch(
                fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL,
-               NULL, 0, fctx->options, 0, fctx->qc, fctx->loop,
+               NULL, 0, fctx->options, 0, fctx->qc, fctx->gqc, fctx->loop,
                resume_dslookup, fctx, &fctx->nsrrset, NULL, &fctx->nsfetch);
        if (result != ISC_R_SUCCESS) {
                if (result == DNS_R_DUPLICATE) {
@@ -10145,8 +10191,9 @@ dns_resolver_prime(dns_resolver_t *res) {
                LOCK(&res->primelock);
                result = dns_resolver_createfetch(
                        res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL,
-                       NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, isc_loop(),
-                       prime_done, res, rdataset, NULL, &res->primefetch);
+                       NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, NULL,
+                       isc_loop(), prime_done, res, rdataset, NULL,
+                       &res->primefetch);
                UNLOCK(&res->primelock);
 
                if (result != ISC_R_SUCCESS) {
@@ -10344,7 +10391,7 @@ get_attached_fctx(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
                  dns_rdatatype_t type, const dns_name_t *domain,
                  dns_rdataset_t *nameservers, const isc_sockaddr_t *client,
                  unsigned int options, unsigned int depth, isc_counter_t *qc,
-                 fetchctx_t **fctxp, bool *new_fctx) {
+                 isc_counter_t *gqc, fetchctx_t **fctxp, bool *new_fctx) {
        isc_result_t result;
        fetchctx_t key = {
                .name = UNCONST(name),
@@ -10364,7 +10411,7 @@ again:
                break;
        case ISC_R_NOTFOUND:
                result = fctx_create(res, loop, name, type, domain, nameservers,
-                                    client, options, depth, qc, &fctx);
+                                    client, options, depth, qc, gqc, &fctx);
                if (result != ISC_R_SUCCESS) {
                        goto unlock;
                }
@@ -10419,9 +10466,10 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                         dns_forwarders_t *forwarders,
                         const isc_sockaddr_t *client, dns_messageid_t id,
                         unsigned int options, unsigned int depth,
-                        isc_counter_t *qc, isc_loop_t *loop, isc_job_cb cb,
-                        void *arg, dns_rdataset_t *rdataset,
-                        dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) {
+                        isc_counter_t *qc, isc_counter_t *gqc,
+                        isc_loop_t *loop, isc_job_cb cb, void *arg,
+                        dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+                        dns_fetch_t **fetchp) {
        dns_fetch_t *fetch = NULL;
        fetchctx_t *fctx = NULL;
        isc_result_t result = ISC_R_SUCCESS;
@@ -10472,7 +10520,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
 
                result = get_attached_fctx(res, loop, name, type, domain,
                                           nameservers, client, options, depth,
-                                          qc, &fctx, &new_fctx);
+                                          qc, gqc, &fctx, &new_fctx);
                if (result != ISC_R_SUCCESS) {
                        goto fail;
                }
@@ -10508,7 +10556,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                }
        } else {
                result = fctx_create(res, loop, name, type, domain, nameservers,
-                                    client, options, depth, qc, &fctx);
+                                    client, options, depth, qc, gqc, &fctx);
                if (result != ISC_R_SUCCESS) {
                        goto unlock;
                }
index a210c773a9ab76bfc29ef5b2e61611c7fb4a2c1c..92ab963ffeb55e872e686fa30a525749e7c326c2 100644 (file)
@@ -939,7 +939,7 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
        dns_validator_ref(val);
        result = dns_resolver_createfetch(
                val->view->resolver, name, type, NULL, NULL, NULL, NULL, 0,
-               fopts, 0, NULL, val->loop, callback, val, &val->frdataset,
+               fopts, 0, NULL, NULL, val->loop, callback, val, &val->frdataset,
                &val->fsigrdataset, &val->fetch);
        if (result != ISC_R_SUCCESS) {
                dns_validator_detach(&val);
@@ -977,7 +977,7 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
        result = dns_validator_create(val->view, name, type, rdataset, sig,
                                      NULL, vopts, val->loop, cb, val,
                                      val->nvalidations, val->nfails, val->qc,
-                                     &val->subvalidator);
+                                     val->gqc, &val->subvalidator);
        if (result == ISC_R_SUCCESS) {
                dns_validator_attach(val, &val->subvalidator->parent);
                val->subvalidator->depth = val->depth + 1;
@@ -3393,7 +3393,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
                     dns_message_t *message, unsigned int options,
                     isc_loop_t *loop, isc_job_cb cb, void *arg,
                     uint32_t *nvalidations, uint32_t *nfails,
-                    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 = NULL;
        dns_keytable_t *kt = NULL;
@@ -3436,6 +3437,9 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
        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);
@@ -3526,6 +3530,9 @@ destroy_validator(dns_validator_t *val) {
        if (val->qc != NULL) {
                isc_counter_detach(&val->qc);
        }
+       if (val->gqc != NULL) {
+               isc_counter_detach(&val->gqc);
+       }
        dns_view_detach(&val->view);
        isc_loop_detach(&val->loop);
        isc_mem_put(mctx, val, sizeof(*val));
index 01c670aa1614072b4f583f9a4318a22e4f5ac326..c1f639f941b4ab1d76deee3e4890211040139bd2 100644 (file)
@@ -10943,7 +10943,7 @@ do_keyfetch(void *arg) {
         */
        result = dns_resolver_createfetch(
                resolver, kname, dns_rdatatype_dnskey, NULL, NULL, NULL, NULL,
-               0, options, 0, NULL, zone->loop, keyfetch_done, kfetch,
+               0, options, 0, NULL, NULL, zone->loop, keyfetch_done, kfetch,
                &kfetch->dnskeyset, &kfetch->dnskeysigset, &kfetch->fetch);
 
        dns_resolver_detach(&resolver);
@@ -12461,7 +12461,7 @@ notify_find_address(dns_notify_t *notify) {
        result = dns_adb_createfind(
                adb, notify->zone->loop, process_notify_adb_event, notify,
                &notify->ns, dns_rootname, 0, options, 0, NULL,
-               notify->zone->view->dstport, 0, NULL, &notify->find);
+               notify->zone->view->dstport, 0, NULL, NULL, &notify->find);
        dns_adb_detach(&adb);
 
        /* Something failed? */
@@ -21228,7 +21228,7 @@ checkds_find_address(dns_checkds_t *checkds) {
        result = dns_adb_createfind(
                adb, checkds->zone->loop, process_checkds_adb_event, checkds,
                &checkds->ns, dns_rootname, 0, options, 0, NULL,
-               checkds->zone->view->dstport, 0, NULL, &checkds->find);
+               checkds->zone->view->dstport, 0, NULL, NULL, &checkds->find);
        dns_adb_detach(&adb);
 
        /* Something failed? */
@@ -21813,8 +21813,9 @@ do_nsfetch(void *arg) {
         */
        result = dns_resolver_createfetch(
                resolver, &nsfetch->pname, dns_rdatatype_ns, NULL, NULL, NULL,
-               NULL, 0, options, 0, NULL, zone->loop, nsfetch_done, nsfetch,
-               &nsfetch->nsrrset, &nsfetch->nssigset, &nsfetch->fetch);
+               NULL, 0, options, 0, NULL, NULL, zone->loop, nsfetch_done,
+               nsfetch, &nsfetch->nsrrset, &nsfetch->nssigset,
+               &nsfetch->fetch);
 
        dns_resolver_detach(&resolver);
 
index 5cfac452f7ac5de7b4c409037d6c3385438844f6..0c70c78d1a10d22bf89ee3f8cf5c0469e0f8d74f 100644 (file)
@@ -80,7 +80,7 @@ isc_counter_setlimit(isc_counter_t *counter, int limit) {
        atomic_store(&counter->limit, limit);
 }
 
-int
+unsigned int
 isc_counter_getlimit(isc_counter_t *counter) {
        REQUIRE(VALID_COUNTER(counter));
 
index 30ae273ae058fd319e12a94e6bf3b1ebe4de568f..385b08cd4f61692cae737010162433d0e3ec59a3 100644 (file)
@@ -68,7 +68,7 @@ isc_counter_setlimit(isc_counter_t *counter, int limit);
  * Set the counter limit.
  */
 
-int
+unsigned int
 isc_counter_getlimit(isc_counter_t *counter);
 /*%<
  * Get the counter limit.
index 572e5ad94e08e3c19632bd0eaa06b5547b09396b..b340c59e3a098afa32f3deb9077d267479e36c5b 100644 (file)
@@ -105,6 +105,7 @@ typedef struct ns_query_recparam {
 struct ns_query {
        unsigned int     attributes;
        unsigned int     restarts;
+       isc_counter_t   *qc;
        bool             timerset;
        dns_name_t      *qname;
        dns_name_t      *origqname;
index b7f6e53b375cc518dc3d36393e1897ff4569bfc1..36441dab5749b0d980114ffbcf91d9164a5f19db 100644 (file)
@@ -20,6 +20,7 @@
 #include <string.h>
 
 #include <isc/async.h>
+#include <isc/counter.h>
 #include <isc/hex.h>
 #include <isc/log.h>
 #include <isc/mem.h>
@@ -861,6 +862,9 @@ query_reset(ns_client_t *client, bool everything) {
                        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;
@@ -2799,7 +2803,8 @@ fetch_and_forget(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t qtype,
        result = dns_resolver_createfetch(
                client->view->resolver, qname, qtype, NULL, NULL, NULL,
                peeraddr, client->message->id, options, 0, NULL,
-               client->manager->loop, cb, client, tmprdataset, NULL, fetchp);
+               client->query.qc, client->manager->loop, cb, client,
+               tmprdataset, NULL, fetchp);
        if (result != ISC_R_SUCCESS) {
                ns_client_putrdataset(client, &tmprdataset);
                isc_nmhandle_detach(handlep);
@@ -6394,8 +6399,9 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
        result = dns_resolver_createfetch(
                client->view->resolver, qname, qtype, qdomain, nameservers,
                NULL, peeraddr, client->message->id, client->query.fetchoptions,
-               0, NULL, client->manager->loop, fetch_callback, client,
-               rdataset, sigrdataset, &FETCH_RECTYPE_NORMAL(client));
+               0, NULL, client->query.qc, client->manager->loop,
+               fetch_callback, client, rdataset, sigrdataset,
+               &FETCH_RECTYPE_NORMAL(client));
        if (result != ISC_R_SUCCESS) {
                release_recursionquota(client);
 
@@ -12058,5 +12064,16 @@ ns_query_start(ns_client_t *client, isc_nmhandle_t *handle) {
                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;
+       }
+
        query_setup(client, qtype);
 }