[9.20] fix: usr: Fix the spurious timeouts while resolving names

Sometimes the loops in the resolving (e.g. to resolve or validate ns1.example.com we need to resolve ns1.example.com) were not properly detected leading to spurious 10 seconds delay.  This has been fixed and such loops are properly detected.

Closes #3033, #5578

Backport of MR !11138

Merge branch 'backport-5578-tracker-parent-fetch-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11298
This commit is contained in:
Ondřej Surý 2025-11-28 10:36:53 +01:00
commit d96cf874fb
13 changed files with 109 additions and 51 deletions

View file

@ -7458,7 +7458,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);
}

View file

@ -340,7 +340,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,
isc_counter_t *gqc, dns_rdatatype_t);
isc_counter_t *gqc, fetchctx_t *parent, dns_rdatatype_t);
static void
destroy(dns_adb_t *);
static void
@ -1876,7 +1876,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
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, isc_counter_t *gqc,
dns_adbfind_t **findp) {
fetchctx_t *parent, dns_adbfind_t **findp) {
isc_result_t result = ISC_R_UNEXPECTED;
dns_adbfind_t *find = NULL;
dns_adbname_t *adbname = NULL;
@ -2086,7 +2086,7 @@ fetch:
* Start V4.
*/
if (WANT_INET(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth, qc, gqc,
fetch_name(adbname, start_at_zone, depth, qc, gqc, parent,
dns_rdatatype_a) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
@ -2099,7 +2099,7 @@ fetch:
* Start V6.
*/
if (WANT_INET6(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth, qc, gqc,
fetch_name(adbname, start_at_zone, depth, qc, gqc, parent,
dns_rdatatype_aaaa) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
@ -2905,7 +2905,8 @@ out:
static isc_result_t
fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
isc_counter_t *qc, isc_counter_t *gqc, dns_rdatatype_t type) {
isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
dns_rdatatype_t type) {
isc_result_t result;
dns_adbfetch_t *fetch = NULL;
dns_adb_t *adb = NULL;
@ -2962,8 +2963,8 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
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));

View file

@ -470,8 +470,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;
}

View file

@ -282,7 +282,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
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, isc_counter_t *gqc,
dns_adbfind_t **find);
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

View file

@ -276,9 +276,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.
*

View file

@ -157,6 +157,7 @@ struct dns_validator {
isc_counter_t *nfails;
isc_counter_t *qc;
isc_counter_t *gqc;
fetchctx_t *parent_fetch;
dns_edectx_t edectx;
@ -179,7 +180,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.

View file

@ -241,7 +241,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) {

View file

@ -480,6 +480,8 @@ struct fetchctx {
isc_counter_t *nvalidations;
isc_counter_t *nfails;
fetchctx_t *parent;
};
#define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
@ -711,7 +713,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
@ -984,7 +987,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);
if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
@ -3309,7 +3313,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, fctx->gqc, &find);
fctx->qc, fctx->gqc, fctx, &find);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
@ -4174,8 +4178,9 @@ 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->gqc, fctx->loop, resume_qmin, fctx, &fctx->edectx,
&fctx->qminrrset, NULL, &fctx->qminfetch);
fctx->gqc, fctx, fctx->loop, resume_qmin, fctx,
&fctx->edectx, &fctx->qminrrset, NULL,
&fctx->qminfetch);
if (result != ISC_R_SUCCESS) {
fetchctx_unref(fctx);
goto done;
@ -4449,6 +4454,9 @@ fctx_destroy(fetchctx_t *fctx) {
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)) {
@ -4606,7 +4614,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,
isc_counter_t *gqc, fetchctx_t **fctxp) {
isc_counter_t *gqc, fetchctx_t *parent, fetchctx_t **fctxp) {
fetchctx_t *fctx = NULL;
isc_result_t result;
isc_result_t iresult;
@ -4727,6 +4735,10 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
fctx->start = isc_time_now();
fctx->now = (isc_stdtime_t)fctx->start.seconds;
if (parent != NULL) {
fetchctx_attach(parent, &fctx->parent);
}
if (client != NULL) {
isc_sockaddr_format(client, fctx->clientstr,
sizeof(fctx->clientstr));
@ -4918,6 +4930,9 @@ cleanup_nameservers:
if (fctx->gqc != NULL) {
isc_counter_detach(&fctx->gqc);
}
if (fctx->parent != NULL) {
fetchctx_detach(&fctx->parent);
}
cleanup_fetch:
dns_resolver_detach(&fctx->res);
@ -7278,7 +7293,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);
@ -9742,9 +9757,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;
@ -10318,7 +10333,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);
@ -10519,7 +10534,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),
@ -10539,7 +10555,8 @@ again:
break;
case ISC_R_NOTFOUND:
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) {
RWUNLOCK(&res->fctxs_lock, locktype);
return result;
@ -10606,6 +10623,18 @@ again:
return result;
}
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,
@ -10614,9 +10643,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;
@ -10648,6 +10678,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(dns_lctx, 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_lctx, 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 };
@ -10667,7 +10713,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;
}
@ -10704,7 +10750,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;
}

View file

@ -986,8 +986,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);
}
@ -1024,7 +1025,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;
@ -3472,7 +3473,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;
@ -3505,6 +3506,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);

View file

@ -11086,8 +11086,8 @@ do_keyfetch(void *arg) {
*/
result = dns_resolver_createfetch(
resolver, kname, dns_rdatatype_dnskey, NULL, NULL, NULL, NULL,
0, options, 0, NULL, NULL, zone->loop, keyfetch_done, kfetch,
NULL, &kfetch->dnskeyset, &kfetch->dnskeysigset,
0, options, 0, NULL, NULL, NULL, zone->loop, keyfetch_done,
kfetch, NULL, &kfetch->dnskeyset, &kfetch->dnskeysigset,
&kfetch->fetch);
dns_resolver_detach(&resolver);
@ -12615,10 +12615,11 @@ notify_find_address(dns_notify_t *notify) {
goto destroy;
}
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, NULL, &notify->find);
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,
NULL, NULL, &notify->find);
dns_adb_detach(&adb);
/* Something failed? */
@ -21518,10 +21519,11 @@ checkds_find_address(dns_checkds_t *checkds) {
goto destroy;
}
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, NULL, &checkds->find);
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,
NULL, NULL, &checkds->find);
dns_adb_detach(&adb);
/* Something failed? */
@ -22106,7 +22108,7 @@ do_nsfetch(void *arg) {
*/
result = dns_resolver_createfetch(
resolver, &nsfetch->pname, dns_rdatatype_ns, NULL, NULL, NULL,
NULL, 0, options, 0, NULL, NULL, zone->loop, nsfetch_done,
NULL, 0, options, 0, NULL, NULL, NULL, zone->loop, nsfetch_done,
nsfetch, NULL, &nsfetch->nsrrset, &nsfetch->nssigset,
&nsfetch->fetch);

View file

@ -228,6 +228,7 @@ typedef enum isc_result {
DNS_R_NODOHPATH,
DNS_R_NOSKRFILE,
DNS_R_NOSKRBUNDLE,
DNS_R_LOOPDETECTED,
DST_R_UNSUPPORTEDALG,
DST_R_CRYPTOFAILURE,

View 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] = {
@ -227,6 +228,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",
@ -481,6 +483,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",

View file

@ -2826,7 +2826,7 @@ 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->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);
@ -6600,7 +6600,7 @@ 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->query.qc, client->manager->loop,
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) {