]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Detect resolution loops between fetches
authorOndřej Surý <ondrej@isc.org>
Wed, 22 Oct 2025 17:25:55 +0000 (19:25 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 27 Nov 2025 16:34:25 +0000 (17:34 +0100)
Maintain the relationship between the parent and child fetch and when
creating a new child fetch, properly check the resolution loops that
would lead to a new fetch would join one of the parent's fetch contexts.

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/notify.c
lib/dns/nta.c
lib/dns/resolver.c
lib/dns/validator.c
lib/dns/zone.c
lib/dns/zonefetch.c
lib/isc/include/isc/result.h
lib/isc/result.c
lib/ns/query.c

index 8cbc1087f6d397c2f35371151cc91d1c25306db7..8994022812bf83690cb9d3081d1de5e54296fcd1 100644 (file)
@@ -6745,7 +6745,7 @@ tat_send(void *arg) {
                result = dns_resolver_createfetch(
                        tat->view->resolver, tatname, dns_rdatatype_null,
                        domain, &nameservers, NULL, NULL, 0, 0, 0, NULL, NULL,
-                       tat->loop, tat_done, tat, NULL, &tat->rdataset,
+                       NULL, tat->loop, tat_done, tat, NULL, &tat->rdataset,
                        &tat->sigrdataset, &tat->fetch);
        }
 
index 2c2c7ba6777ce5a34a4a515682612d9aac0c785a..0f61de1b7ea3faa02c2ded28a1c9d7317e5e3190 100644 (file)
@@ -356,7 +356,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, bool, unsigned int, isc_counter_t *qc,
-          isc_counter_t *gqc, dns_rdatatype_t);
+          isc_counter_t *gqc, fetchctx_t *parent, dns_rdatatype_t);
 static void
 shutdown_names(dns_adb_t *);
 static void
@@ -1717,7 +1717,7 @@ isc_result_t
 dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
                   const dns_name_t *name, unsigned int options,
                   isc_stdtime_t now, in_port_t port, unsigned int depth,
-                  isc_counter_t *qc, isc_counter_t *gqc,
+                  isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
                   dns_adbfind_t **findp) {
        isc_result_t result = ISC_R_UNEXPECTED;
        dns_adbfind_t *find = NULL;
@@ -1922,7 +1922,7 @@ fetch:
                 */
                if (WANT_INET(wanted_fetches) &&
                    fetch_name(adbname, start_at_zone, no_validate, depth, qc,
-                              gqc, dns_rdatatype_a) == ISC_R_SUCCESS)
+                              gqc, parent, dns_rdatatype_a) == ISC_R_SUCCESS)
                {
                        DP(DEF_LEVEL,
                           "dns_adb_createfind: "
@@ -1935,7 +1935,8 @@ fetch:
                 */
                if (WANT_INET6(wanted_fetches) &&
                    fetch_name(adbname, start_at_zone, no_validate, depth, qc,
-                              gqc, dns_rdatatype_aaaa) == ISC_R_SUCCESS)
+                              gqc, parent,
+                              dns_rdatatype_aaaa) == ISC_R_SUCCESS)
                {
                        DP(DEF_LEVEL,
                           "dns_adb_createfind: "
@@ -2719,7 +2720,7 @@ out:
 static isc_result_t
 fetch_name(dns_adbname_t *adbname, bool start_at_zone, bool no_validation,
           unsigned int depth, isc_counter_t *qc, isc_counter_t *gqc,
-          dns_rdatatype_t type) {
+          fetchctx_t *parent, dns_rdatatype_t type) {
        isc_result_t result;
        dns_adbfetch_t *fetch = NULL;
        dns_adb_t *adb = NULL;
@@ -2774,8 +2775,8 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone, bool no_validation,
        dns_adbname_ref(adbname);
        result = dns_resolver_createfetch(
                adb->res, adbname->name, type, name, nameservers, NULL, NULL, 0,
-               options, depth, qc, gqc, isc_loop(), fetch_callback, adbname,
-               NULL, &fetch->rdataset, NULL, &fetch->fetch);
+               options, depth, qc, gqc, parent, isc_loop(), fetch_callback,
+               adbname, NULL, &fetch->rdataset, NULL, &fetch->fetch);
        if (result != ISC_R_SUCCESS) {
                DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
                   isc_result_totext(result));
index 4a2f4c5000feed2546b02123fc2465163d69ed4f..c4f32e7595f10e17c07f5b3b39103f4dde11e494 100644 (file)
@@ -455,8 +455,8 @@ 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->qc,
-               rctx->client->loop, fetch_done, rctx, NULL, rctx->rdataset,
-               rctx->sigrdataset, &rctx->fetch);
+               NULL, rctx->client->loop, fetch_done, rctx, NULL,
+               rctx->rdataset, rctx->sigrdataset, &rctx->fetch);
 
        return result;
 }
index 4c0207f8428e44ac2340a637c53d8ff85a1fa49d..13183e029bb9a35e72df426ed8d6c67ff8a74628 100644 (file)
@@ -278,7 +278,8 @@ isc_result_t
 dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
                   const dns_name_t *name, unsigned int options,
                   isc_stdtime_t now, in_port_t port, unsigned int depth,
-                  isc_counter_t *qc, isc_counter_t *gqc, dns_adbfind_t **find);
+                  isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
+                  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 14f510696e4d0a00e5c4546ea5f75b675fcb5189..a38d696668d3b6dba29fa4ea55406d86e79eadb7 100644 (file)
@@ -280,9 +280,10 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                         const isc_sockaddr_t *client, dns_messageid_t id,
                         unsigned int options, unsigned int depth,
                         isc_counter_t *qc, isc_counter_t *gqc,
-                        isc_loop_t *loop, isc_job_cb cb, void *arg,
-                        dns_edectx_t *edectx, dns_rdataset_t *rdataset,
-                        dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp);
+                        fetchctx_t *parent, isc_loop_t *loop, isc_job_cb cb,
+                        void *arg, dns_edectx_t *edectx,
+                        dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+                        dns_fetch_t **fetchp);
 /*%<
  * Recurse to answer a question.
  *
index ba50a827f2483abd793c9519b1245c0ea1305721..faa5ea15330fcefa2816f8c5375816057adbec2e 100644 (file)
@@ -156,6 +156,7 @@ struct dns_validator {
        isc_counter_t *nfails;
        isc_counter_t *qc;
        isc_counter_t *gqc;
+       fetchctx_t    *parent_fetch;
 
        dns_edectx_t edectx;
 
@@ -176,7 +177,7 @@ 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,
                     isc_counter_t *nvalidations, isc_counter_t *nfails,
-                    isc_counter_t *qc, isc_counter_t *gqc,
+                    isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
                     dns_edectx_t *edectx, dns_validator_t **validatorp);
 /*%<
  * Start a DNSSEC validation.
index f4d5cfb67033ea46701de01761cc17a7e9c84998..371b33482e836c25e757b13110b226916e2d6968 100644 (file)
@@ -730,7 +730,7 @@ dns_notify_find_address(dns_notify_t *notify) {
 
        result = dns_adb_createfind(adb, loop, process_notify_adb_event, notify,
                                    &notify->ns, options, 0, view->dstport, 0,
-                                   NULL, NULL, &notify->find);
+                                   NULL, NULL, NULL, &notify->find);
        dns_adb_detach(&adb);
 
        /* Something failed? */
index fa4c7f243f5df4af091894870967e081f5cb1876..ac0eabc8c0fe6a0b27a39d95a0ac841d922ab00d 100644 (file)
@@ -237,7 +237,7 @@ 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, NULL, nta->loop,
+               NULL, 0, DNS_FETCHOPT_NONTA, 0, NULL, NULL, NULL, nta->loop,
                fetch_done, nta, NULL, &nta->rdataset, &nta->sigrdataset,
                &nta->fetch);
        if (result != ISC_R_SUCCESS) {
index e4ae28bbfa184640529024252090a6b2ecd699b5..22dbce494c4d523ba41c02cb4ccc2fd731deba46 100644 (file)
@@ -473,6 +473,7 @@ struct fetchctx {
 
        isc_counter_t *nvalidations;
        isc_counter_t *nfails;
+       fetchctx_t *parent;
 
        struct cds_lfht_node ht_node;
        struct rcu_head rcu_head;
@@ -813,7 +814,8 @@ 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,
-                 isc_counter_t *gqc, fetchctx_t **fctxp, bool *new_fctx);
+                 isc_counter_t *gqc, fetchctx_t *parent, fetchctx_t **fctxp,
+                 bool *new_fctx);
 
 /*%
  * The structure and functions defined below implement the resolver
@@ -1093,7 +1095,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, fctx->loop, validated, valarg, fctx->nvalidations,
-               fctx->nfails, fctx->qc, fctx->gqc, &fctx->edectx, &validator);
+               fctx->nfails, fctx->qc, fctx->gqc, fctx, &fctx->edectx,
+               &validator);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
        inc_stats(fctx->res, dns_resstatscounter_val);
        ISC_LIST_APPEND(fctx->validators, validator, link);
@@ -3349,7 +3352,7 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
        fetchctx_ref(fctx);
        result = dns_adb_createfind(fctx->adb, fctx->loop, fctx_finddone, fctx,
                                    name, options, now, res->view->dstport,
-                                   fctx->depth + 1, fctx->qc, fctx->gqc,
+                                   fctx->depth + 1, fctx->qc, fctx->gqc, fctx,
                                    &find);
 
        isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
@@ -4231,8 +4234,8 @@ fctx_try(fetchctx_t *fctx, bool retrying) {
                        fctx->res, fctx->qminname, fctx->qmintype, fctx->domain,
                        &fctx->nameservers, NULL, NULL, 0,
                        options | DNS_FETCHOPT_QMINFETCH, 0, fctx->qc,
-                       fctx->gqc, fctx->loop, resume_qmin, fctx, &fctx->edectx,
-                       &fctx->qminrrset, &fctx->qminsigrrset,
+                       fctx->gqc, fctx, fctx->loop, resume_qmin, fctx,
+                       &fctx->edectx, &fctx->qminrrset, &fctx->qminsigrrset,
                        &fctx->qminfetch);
                if (result != ISC_R_SUCCESS) {
                        fetchctx_unref(fctx);
@@ -4629,6 +4632,9 @@ fctx__destroy(fetchctx_t *fctx, const char *func, const char *file,
        if (fctx->gqc != NULL) {
                isc_counter_detach(&fctx->gqc);
        }
+       if (fctx->parent != NULL) {
+               fetchctx_detach(&fctx->parent);
+       }
        fcount_decr(fctx);
        dns_message_detach(&fctx->qmessage);
        if (dns_rdataset_isassociated(&fctx->nameservers)) {
@@ -4780,17 +4786,17 @@ log_ns_ttl(fetchctx_t *fctx, const char *where) {
 }
 
 #define fctx_create(res, loop, name, type, domain, nameservers, client,  \
-                   options, depth, qc, gqp, fctxp)                      \
+                   options, depth, qc, gqp, parent, fctxp)              \
        fctx__create(res, loop, name, type, domain, nameservers, client, \
-                    options, depth, qc, gqp, fctxp, __func__, __FILE__, \
-                    __LINE__)
+                    options, depth, qc, gqp, parent, fctxp, __func__,   \
+                    __FILE__, __LINE__)
 static isc_result_t
 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,
-            isc_counter_t *gqc, fetchctx_t **fctxp, const char *func,
-            const char *file, const unsigned int line) {
+            isc_counter_t *gqc, fetchctx_t *parent, fetchctx_t **fctxp,
+            const char *func, const char *file, const unsigned int line) {
        fetchctx_t *fctx = NULL;
        isc_result_t result;
        isc_result_t iresult;
@@ -4897,6 +4903,10 @@ fctx__create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
                              isc_counter_used(fctx->gqc));
        }
 
+       if (parent != NULL) {
+               fetchctx_attach(parent, &fctx->parent);
+       }
+
        urcu_ref_set(&fctx->ref, 1);
 
        if (client != NULL) {
@@ -5104,6 +5114,9 @@ cleanup_nameservers:
        if (fctx->gqc != NULL) {
                isc_counter_detach(&fctx->gqc);
        }
+       if (fctx->parent != NULL) {
+               fetchctx_detach(&fctx->parent);
+       }
 
        dns_resolver_detach(&fctx->res);
        isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
@@ -7021,7 +7034,7 @@ resume_dslookup(void *arg) {
                result = dns_resolver_createfetch(
                        res, fctx->nsname, dns_rdatatype_ns, domain, nsrdataset,
                        NULL, NULL, 0, fctx->options, 0, fctx->qc, fctx->gqc,
-                       loop, resume_dslookup, fctx, &fctx->edectx,
+                       fctx, loop, resume_dslookup, fctx, &fctx->edectx,
                        &fctx->nsrrset, NULL, &fctx->nsfetch);
                if (result != ISC_R_SUCCESS) {
                        fetchctx_unref(fctx);
@@ -9370,9 +9383,9 @@ 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->gqc, fctx->loop,
-               resume_dslookup, fctx, &fctx->edectx, &fctx->nsrrset, NULL,
-               &fctx->nsfetch);
+               NULL, 0, fctx->options, 0, fctx->qc, fctx->gqc, fctx,
+               fctx->loop, resume_dslookup, fctx, &fctx->edectx,
+               &fctx->nsrrset, NULL, &fctx->nsfetch);
        if (result != ISC_R_SUCCESS) {
                if (result == DNS_R_DUPLICATE) {
                        result = DNS_R_SERVFAIL;
@@ -9953,7 +9966,7 @@ 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, NULL,
+                       NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, NULL, NULL,
                        isc_loop(), prime_done, res, NULL, rdataset, NULL,
                        &res->primefetch);
                UNLOCK(&res->primelock);
@@ -10140,7 +10153,8 @@ 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,
-                 isc_counter_t *gqc, fetchctx_t **fctxp, bool *new_fctx) {
+                 isc_counter_t *gqc, fetchctx_t *parent, fetchctx_t **fctxp,
+                 bool *new_fctx) {
        isc_result_t result;
        fetchctx_t key = {
                .name = UNCONST(name),
@@ -10161,7 +10175,8 @@ get_attached_fctx(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
        if (fctx == NULL) {
        create:
                result = fctx_create(res, loop, name, type, domain, nameservers,
-                                    client, options, depth, qc, gqc, &fctx);
+                                    client, options, depth, qc, gqc, parent,
+                                    &fctx);
                if (result != ISC_R_SUCCESS) {
                        rcu_read_unlock();
                        return result;
@@ -10230,6 +10245,18 @@ get_attached_fctx(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
        return ISC_R_SUCCESS;
 }
 
+static bool
+waiting_for_fetch(fetchctx_t *fctx, const dns_name_t *name,
+                 dns_rdatatype_t type) {
+       while (fctx != NULL) {
+               if (type == fctx->type && !dns_name_compare(name, fctx->name)) {
+                       return true;
+               }
+               fctx = fctx->parent;
+       }
+       return false;
+}
+
 isc_result_t
 dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                         dns_rdatatype_t type, const dns_name_t *domain,
@@ -10238,9 +10265,10 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
                         const isc_sockaddr_t *client, dns_messageid_t id,
                         unsigned int options, unsigned int depth,
                         isc_counter_t *qc, isc_counter_t *gqc,
-                        isc_loop_t *loop, isc_job_cb cb, void *arg,
-                        dns_edectx_t *edectx, dns_rdataset_t *rdataset,
-                        dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) {
+                        fetchctx_t *parent, isc_loop_t *loop, isc_job_cb cb,
+                        void *arg, dns_edectx_t *edectx,
+                        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;
@@ -10272,6 +10300,22 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
 
        log_fetch(name, type);
 
+       if (waiting_for_fetch(parent, name, type)) {
+               if (isc_log_wouldlog(ISC_LOG_INFO)) {
+                       char namebuf[DNS_NAME_FORMATSIZE + 1];
+                       char typebuf[DNS_RDATATYPE_FORMATSIZE];
+
+                       dns_name_format(name, namebuf, sizeof(namebuf));
+                       dns_rdatatype_format(type, typebuf, sizeof(typebuf));
+
+                       isc_log_write(DNS_LOGCATEGORY_RESOLVER,
+                                     DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(2),
+                                     "fetch loop detected resolving '%s/%s'",
+                                     namebuf, typebuf);
+               }
+               return DNS_R_LOOPDETECTED;
+       }
+
        fetch = isc_mem_get(mctx, sizeof(*fetch));
        *fetch = (dns_fetch_t){ 0 };
 
@@ -10291,7 +10335,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, gqc, &fctx, &new_fctx);
+                                          qc, gqc, parent, &fctx, &new_fctx);
                if (result != ISC_R_SUCCESS) {
                        goto fail;
                }
@@ -10325,7 +10369,8 @@ 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, gqc, &fctx);
+                                    client, options, depth, qc, gqc, parent,
+                                    &fctx);
                if (result != ISC_R_SUCCESS) {
                        goto fail;
                }
index 52677fbd80f1ad95b6baf4d20daa7733bae8954d..ba62d9a3444ffdbf8a75d133cda4843e61240ae2 100644 (file)
@@ -1001,8 +1001,9 @@ 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, val->qc, val->gqc, val->loop, callback, val,
-               &val->edectx, &val->frdataset, &val->fsigrdataset, &val->fetch);
+               fopts, 0, val->qc, val->gqc, val->parent_fetch, val->loop,
+               callback, val, &val->edectx, &val->frdataset,
+               &val->fsigrdataset, &val->fetch);
        if (result != ISC_R_SUCCESS) {
                dns_validator_detach(&val);
        }
@@ -1039,7 +1040,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->gqc,
-               &val->edectx, &val->subvalidator);
+               val->parent_fetch, &val->edectx, &val->subvalidator);
        if (result == ISC_R_SUCCESS) {
                dns_validator_attach(val, &val->subvalidator->parent);
                val->subvalidator->depth = val->depth + 1;
@@ -3677,7 +3678,7 @@ 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,
                     isc_counter_t *nvalidations, isc_counter_t *nfails,
-                    isc_counter_t *qc, isc_counter_t *gqc,
+                    isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
                     dns_edectx_t *edectx, dns_validator_t **validatorp) {
        isc_result_t result = ISC_R_FAILURE;
        dns_validator_t *val = NULL;
@@ -3710,6 +3711,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
                .arg = arg,
                .rdata = DNS_RDATA_INIT,
                .cb_edectx = edectx,
+               .parent_fetch = parent,
        };
 
        dns_ede_init(view->mctx, &val->edectx);
index 2b70bdc93a731d7477d9dfaa186b38c34e35a0d3..4ddeb709688c03f63e37695678f84c9a4c11e901 100644 (file)
@@ -20707,7 +20707,7 @@ checkds_find_address(dns_checkds_t *checkds) {
        result = dns_adb_createfind(
                adb, checkds->zone->loop, process_checkds_adb_event, checkds,
                &checkds->ns, options, 0, checkds->zone->view->dstport, 0, NULL,
-               NULL, &checkds->find);
+               NULL, NULL, &checkds->find);
        dns_adb_detach(&adb);
 
        /* Something failed? */
index c58cae518371c59d15494c4a70b7e6304a248fcc..6e9615f7a7769e0336073e93dcf11b7ebe7f8898 100644 (file)
@@ -72,8 +72,8 @@ dns_zonefetch_run(void *arg) {
 
        result = dns_resolver_createfetch(
                resolver, fetch->qname, fetch->qtype, NULL, NULL, NULL, NULL, 0,
-               fetch->options, 0, NULL, NULL, loop, dns_zonefetch_done, fetch,
-               NULL, &fetch->rrset, &fetch->sigset, &fetch->fetch);
+               fetch->options, 0, NULL, NULL, NULL, loop, dns_zonefetch_done,
+               fetch, NULL, &fetch->rrset, &fetch->sigset, &fetch->fetch);
 
        dns_resolver_detach(&resolver);
 
index 35959812de262b501382f58c2b1ec1c763d22382..34f08a7f7426c3f055a0481d8cb61766a2a5f099 100644 (file)
@@ -208,6 +208,7 @@ typedef enum isc_result {
        DNS_R_NODOHPATH,
        DNS_R_NOSKRFILE,
        DNS_R_NOSKRBUNDLE,
+       DNS_R_LOOPDETECTED,
 
        DST_R_UNSUPPORTEDALG,
        DST_R_CRYPTOFAILURE,
index a5f5de90628c3ae1cb960d99c3852af000e5ac56..de78e4422cec41632808c48111c4cbc1c0e90419 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdlib.h>
 
 #include <isc/once.h>
+#include <isc/result.h>
 #include <isc/util.h>
 
 static const char *description[ISC_R_NRESULTS] = {
@@ -210,6 +211,7 @@ static const char *description[ISC_R_NRESULTS] = {
        [DNS_R_NODOHPATH] = "no DOHPATH",
        [DNS_R_NOSKRFILE] = "no SKR file",
        [DNS_R_NOSKRBUNDLE] = "no available SKR bundle",
+       [DNS_R_LOOPDETECTED] = "fetch loop detected",
 
        [DST_R_UNSUPPORTEDALG] = "algorithm is unsupported",
        [DST_R_CRYPTOFAILURE] = "crypto failure",
@@ -442,6 +444,7 @@ static const char *identifier[ISC_R_NRESULTS] = {
        [DNS_R_NODOHPATH] = "DNS_R_NODOHPATH",
        [DNS_R_NOSKRFILE] = "DNS_R_NOSKRFILE",
        [DNS_R_NOSKRBUNDLE] = "DNS_R_NOSKRBUNDLE",
+       [DNS_R_LOOPDETECTED] = "DNS_R_LOOPDETECTED",
 
        [DST_R_UNSUPPORTEDALG] = "DST_R_UNSUPPORTEDALG",
        [DST_R_CRYPTOFAILURE] = "DST_R_CRYPTOFAILURE",
index 43448d332bb294413966ed5ebc6bfef73f7ec8e0..f0a5a50251d84b58059e8ebdc632d537933f018d 100644 (file)
@@ -2876,7 +2876,7 @@ fetch_and_forget(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t qtype,
        result = dns_resolver_createfetch(
                client->inner.view->resolver, qname, qtype, NULL, NULL, NULL,
                peeraddr, client->message->id, options, 0, NULL,
-               client->query.qc, client->manager->loop, cb, client, NULL,
+               client->query.qc, NULL, client->manager->loop, cb, client, NULL,
                tmprdataset, NULL, fetchp);
        if (result != ISC_R_SUCCESS) {
                ns_client_putrdataset(client, &tmprdataset);
@@ -6403,7 +6403,7 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
        result = dns_resolver_createfetch(
                client->inner.view->resolver, qname, qtype, qdomain,
                nameservers, NULL, peeraddr, client->message->id,
-               client->query.fetchoptions, 0, NULL, client->query.qc,
+               client->query.fetchoptions, 0, NULL, client->query.qc, NULL,
                client->manager->loop, fetch_callback, client, &client->edectx,
                rdataset, sigrdataset, &FETCH_RECTYPE_NORMAL(client));
        if (result != ISC_R_SUCCESS) {