]> 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>
Fri, 6 Dec 2024 15:17:53 +0000 (15:17 +0000)
This global limit is not reset on query restarts and is a hard limit
for any client request.

Note: This commit has been significantly modified because of many
merge conflicts due to the dns_resolver_createfetch api changes.

(cherry picked from commit 16b3bd1cc743d3519a91edae896f394a689b0f0f)

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/lookup.c
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 68b29d835f1f940b9390c9e71d0e7b782398d5df..a0a28c04a3705099c13ade9a2903a75203c1e1b5 100644 (file)
@@ -7410,7 +7410,7 @@ tat_send(isc_task_t *task, isc_event_t *event) {
        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);
        }
index 3a769af91be2abefc5f35c5795569b920f9f8032..8b6e1535664583796de6b579e5cbd7080ae37782 100644 (file)
@@ -343,7 +343,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
 check_exit(dns_adb_t *);
 static void
@@ -2903,7 +2903,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
                   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;
@@ -3162,7 +3162,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,
@@ -3175,7 +3175,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,
@@ -4055,7 +4055,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;
@@ -4105,8 +4105,8 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
         */
        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));
index a88eaa94124df94b34989246e1da165ff40eaa8e..636dca712f7f3290a2e4358da9c7f9a1b6068a29 100644 (file)
@@ -554,7 +554,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->task, fetch_done, rctx, rctx->rdataset, rctx->sigrdataset,
                &rctx->fetch);
 
index 4b81e5f2c1ff1826f67588ec70ca777436c2b76a..7817c137b13bece95fdc38010a1e2bb0cb8059af 100644 (file)
@@ -341,7 +341,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
                   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
index 4de314c90d693a6ff10b05968b80c08b0bca28c3..d22b897b6160d31221c832aa7a3f4e0851cae86b 100644 (file)
@@ -279,8 +279,8 @@ 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_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);
 /*%<
index 2c758833f0bf11dd3ac66946c7795703c21af6f4..0c717f37c5109519e2b350bb155ab3a1941099b5 100644 (file)
@@ -151,6 +151,7 @@ struct dns_validator {
        bool           failed;
        isc_stdtime_t  start;
        isc_counter_t *qc;
+       isc_counter_t *gqc;
 };
 
 /*%
@@ -168,7 +169,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
                     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.
  *
index 6ccea3adecf8078bc95c5541c72d2b306114131a..4f5356d51a2b3b947022d8f785400a0e78223260 100644 (file)
@@ -85,7 +85,7 @@ start_fetch(dns_lookup_t *lookup) {
 
        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);
 
index 60c08b4b6f3d4ec31e3b5a0821bca34c7a8f18fb..4e9a0c0ef79138a8c25656b175fe43414f4b30f7 100644 (file)
@@ -263,8 +263,8 @@ checkbogus(isc_task_t *task, isc_event_t *event) {
        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);
index b8907b420eeb2ee3a428f870b1933f138b3b0097..332a82118ff178026e534ef9b8d995df87da31c8 100644 (file)
@@ -380,6 +380,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;
@@ -976,7 +977,8 @@ 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, 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);
@@ -3427,7 +3429,8 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
        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),
@@ -4137,6 +4140,9 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
        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));
 
@@ -4144,13 +4150,27 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
        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;
        }
@@ -4256,8 +4276,8 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
                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);
@@ -4269,12 +4289,26 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
        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);
@@ -4513,6 +4547,9 @@ fctx_destroy(fetchctx_t *fctx, bool exiting) {
        }
 
        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)) {
@@ -4785,7 +4822,7 @@ fctx_create(dns_resolver_t *res, isc_task_t *task, 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 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;
@@ -4849,6 +4886,15 @@ fctx_create(dns_resolver_t *res, isc_task_t *task, const dns_name_t *name,
                              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);
@@ -5105,6 +5151,9 @@ cleanup_nameservers:
        }
        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);
@@ -7584,7 +7633,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
                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) {
@@ -9952,8 +10001,8 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message,
        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;
@@ -10656,7 +10705,7 @@ dns_resolver_prime(dns_resolver_t *res) {
                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);
@@ -10934,8 +10983,8 @@ 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_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;
@@ -11040,7 +11089,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
 
        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;
index 6123992a635efdb6e9f23492da2191ed5ccd6b65..5f2eb9542c41a814c9fb9bf3bb269371a70fc8da 100644 (file)
@@ -1060,7 +1060,7 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
        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);
 }
 
@@ -1092,7 +1092,7 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
        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;
@@ -3153,7 +3153,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
                     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;
@@ -3197,6 +3198,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);
@@ -3305,6 +3309,9 @@ destroy(dns_validator_t *val) {
        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));
index 49e03fea5dbf30475c601ad060f90f59cf9cc767..17faae738783181636d3083ab8e0df8854fe461e 100644 (file)
 /*%
  * 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)); \
        }
 
 /*
@@ -11091,8 +11091,8 @@ do_keyfetch(isc_task_t *task, isc_event_t *event) {
                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);
@@ -12542,7 +12542,7 @@ notify_find_address(dns_notify_t *notify) {
        result = dns_adb_createfind(
                notify->zone->view->adb, notify->zone->task, process_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);
 
        /* Something failed? */
        if (result != ISC_R_SUCCESS) {
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 37e55671c2560aa41ab5c4c654cec00752fd3bd6..c09075452686b1abf03654ccbbcdd5e9a781be45 100644 (file)
@@ -54,6 +54,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 43142b6c8a343d931473e0bc31d4fa1218b07f64..fd25dfb61e2709d27115ee7256c08d4c7e771445 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdbool.h>
 #include <string.h>
 
+#include <isc/counter.h>
 #include <isc/hex.h>
 #include <isc/mem.h>
 #include <isc/once.h>
@@ -764,6 +765,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;
@@ -2614,8 +2618,8 @@ query_prefetch(ns_client_t *client, dns_name_t *qname,
        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) {
@@ -2838,7 +2842,7 @@ query_rpzfetch(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t type) {
        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) {
@@ -6614,8 +6618,8 @@ 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->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);
@@ -12546,5 +12550,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;
+       }
+
        (void)query_setup(client, qtype);
 }