diff --git a/bin/named/server.c b/bin/named/server.c index 9b3f170025..006b90c33c 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -6461,8 +6461,8 @@ tat_done(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } dns_resolver_freefresp(&resp); diff --git a/lib/dns/adb.c b/lib/dns/adb.c index f5cfa7e58e..06256be588 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -2586,8 +2586,8 @@ fetch_callback(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } if (atomic_load(&adb->shuttingdown)) { diff --git a/lib/dns/client.c b/lib/dns/client.c index 0e2d12f1aa..2097fa3ec5 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -531,7 +531,7 @@ client_resfind(resctx_t *rctx, dns_fetchresponse_t *resp) { INSIST(resp != NULL); INSIST(resp->fetch == rctx->fetch); dns_resolver_destroyfetch(&rctx->fetch); - db = resp->db; + db = resp->cache; node = resp->node; result = resp->result; vresult = resp->vresult; diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index 406e7d47d7..5c56d5d86d 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -82,7 +82,7 @@ struct dns_fetchresponse { isc_result_t vresult; dns_edectx_t *edectx; dns_rdatatype_t qtype; - dns_db_t *db; + dns_db_t *cache; dns_dbnode_t *node; dns_rdataset_t *rdataset; dns_rdataset_t *sigrdataset; diff --git a/lib/dns/nta.c b/lib/dns/nta.c index 17345e2613..aba39e95c6 100644 --- a/lib/dns/nta.c +++ b/lib/dns/nta.c @@ -163,8 +163,8 @@ fetch_done(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } dns_resolver_freefresp(&resp); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 919e518ac9..f475af5ffd 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -350,7 +350,6 @@ struct fetchctx { /*% Locked by lock. */ isc_mutex_t lock; fetchstate_t state; - bool cloned; bool spilled; uint_fast32_t allowed; uint_fast32_t dropped; @@ -390,21 +389,49 @@ struct fetchctx { isc_counter_t *qc; isc_counter_t *gqc; bool minimized; + dns_fixedname_t fwdfname; + dns_name_t *fwdname; + bool forwarding; + + /*% + * These hold state information regarding QNAME minimization. + */ unsigned int qmin_labels; isc_result_t qmin_warning; bool force_qmin_warning; bool ip6arpaskip; - bool forwarding; - dns_fixedname_t qminfname; - dns_name_t *qminname; dns_rdatatype_t qmintype; dns_fetch_t *qminfetch; - dns_rdataset_t qminrrset; - dns_rdataset_t qminsigrrset; - dns_fixedname_t qmindcfname; - dns_name_t *qmindcname; - dns_fixedname_t fwdfname; - dns_name_t *fwdname; + + /*% + * These are results from the query that need to be copied to the + * response objects (dns_fetchresponse_t). + */ + isc_result_t resp_result; + dns_dbnode_t *resp_node; + + /*% + * These are used both during the QNAME minimization process, and + * also to store final query results to be copied into the fetch + * response. These uses never occur at the same time, so we can + * save space in the fetchctx object by making them a union. + */ + union { + struct { + dns_rdataset_t rdataset; + dns_rdataset_t sigrdataset; + dns_fixedname_t fname; + dns_name_t *name; + dns_fixedname_t dcfname; + dns_name_t *dcname; + } qmin; + struct { + dns_rdataset_t rdataset; + dns_rdataset_t sigrdataset; + dns_fixedname_t fname; + dns_name_t *foundname; + } resp; + }; /*% * Used to track started ADB finds with event. @@ -806,9 +833,6 @@ fctx__done(fetchctx_t *fctx, isc_result_t result, const char *func, static void resume_qmin(void *arg); -static void -clone_results(fetchctx_t *fctx); - static isc_result_t 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, @@ -1615,6 +1639,42 @@ fcount_decr(fetchctx_t *fctx) { static void spillattimer_countdown(void *arg); +static void +copy_to_resp(fetchctx_t *fctx, dns_fetchresponse_t *resp) { + resp->result = fctx->resp_result; + + dns_name_copy(fctx->resp.foundname, resp->foundname); + + dns_db_attach(fctx->cache, &resp->cache); + dns_db_attachnode(fctx->resp_node, &resp->node); + + if (dns_rdataset_isassociated(&fctx->resp.rdataset)) { + dns_rdataset_clone(&fctx->resp.rdataset, resp->rdataset); + } + if (resp->sigrdataset != NULL && + dns_rdataset_isassociated(&fctx->resp.sigrdataset)) + { + dns_rdataset_clone(&fctx->resp.sigrdataset, resp->sigrdataset); + } +} + +static void +pull_from_resp(dns_fetchresponse_t *resp, fetchctx_t *fctx) { + if (dns_rdataset_isassociated(resp->rdataset)) { + dns_rdataset_clone(resp->rdataset, &fctx->resp.rdataset); + } + if (dns_rdataset_isassociated(resp->sigrdataset)) { + dns_rdataset_clone(resp->sigrdataset, &fctx->resp.sigrdataset); + } + if (resp->cache != NULL) { + INSIST(resp->cache == fctx->cache); + } + if (resp->node != NULL) { + dns_db_attachnode(resp->node, &fctx->resp_node); + } + dns_name_copy(resp->foundname, fctx->resp.foundname); +} + static void fctx_sendevents(fetchctx_t *fctx, isc_result_t result) { unsigned int count = 0; @@ -1640,6 +1700,9 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result) { ISC_LIST_FOREACH(fctx->resps, resp, link) { ISC_LIST_UNLINK(fctx->resps, resp, link); + if (result == ISC_R_SUCCESS) { + copy_to_resp(fctx, resp); + } count++; resp->vresult = fctx->vresult; @@ -4200,7 +4263,7 @@ fctx_try(fetchctx_t *fctx, bool retrying) { char namebuf[DNS_NAME_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(fctx->qminname, namebuf, + dns_name_format(fctx->qmin.name, namebuf, sizeof(namebuf)); dns_rdatatype_format(fctx->qmintype, typebuf, sizeof(typebuf)); @@ -4231,12 +4294,12 @@ fctx_try(fetchctx_t *fctx, bool retrying) { fetchctx_ref(fctx); result = dns_resolver_createfetch( - fctx->res, fctx->qminname, fctx->qmintype, fctx->domain, - &fctx->nameservers, NULL, NULL, 0, + fctx->res, fctx->qmin.name, fctx->qmintype, + fctx->domain, &fctx->nameservers, NULL, NULL, 0, options | DNS_FETCHOPT_QMINFETCH, 0, fctx->qc, fctx->gqc, fctx, fctx->loop, resume_qmin, fctx, - &fctx->edectx, &fctx->qminrrset, &fctx->qminsigrrset, - &fctx->qminfetch); + &fctx->edectx, &fctx->qmin.rdataset, + &fctx->qmin.sigrdataset, &fctx->qminfetch); if (result != ISC_R_SUCCESS) { fetchctx_unref(fctx); goto done; @@ -4288,6 +4351,26 @@ done: } } +static void +clear_resp(dns_fetchresponse_t **respp) { + dns_fetchresponse_t *resp = *respp; + + if (resp == NULL) { + return; + } + + if (resp->node != NULL) { + dns_db_detachnode(&resp->node); + } + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); + } + dns_rdataset_cleanup(resp->rdataset); + dns_rdataset_cleanup(resp->sigrdataset); + + dns_resolver_freefresp(respp); +} + static void resume_qmin(void *arg) { dns_fetchresponse_t *resp = (dns_fetchresponse_t *)arg; @@ -4297,10 +4380,6 @@ resume_qmin(void *arg) { unsigned int findoptions = 0; dns_name_t *fname = NULL, *dcname = NULL; dns_fixedname_t ffixed, dcfixed; - dns_rdataset_t rdataset; - dns_rdataset_t sigrdataset; - dns_db_t *db = NULL; - dns_dbnode_t *node = NULL; REQUIRE(VALID_FCTX(fctx)); @@ -4313,32 +4392,8 @@ resume_qmin(void *arg) { fname = dns_fixedname_initname(&ffixed); dcname = dns_fixedname_initname(&dcfixed); - dns_rdataset_init(&rdataset); - dns_rdataset_init(&sigrdataset); - - if (resp->node != NULL) { - dns_db_attachnode(resp->node, &node); - dns_db_detachnode(&resp->node); - } - if (resp->db != NULL) { - dns_db_attach(resp->db, &db); - dns_db_detach(&resp->db); - } - - if (dns_rdataset_isassociated(resp->rdataset)) { - dns_rdataset_clone(resp->rdataset, &rdataset); - dns_rdataset_disassociate(resp->rdataset); - } - if (dns_rdataset_isassociated(resp->sigrdataset)) { - dns_rdataset_clone(resp->sigrdataset, &sigrdataset); - dns_rdataset_disassociate(resp->sigrdataset); - } - dns_name_copy(resp->foundname, fname); - result = resp->result; - dns_resolver_freefresp(&resp); - LOCK(&fctx->lock); if (SHUTTINGDOWN(fctx)) { result = ISC_R_SHUTTINGDOWN; @@ -4370,31 +4425,8 @@ resume_qmin(void *arg) { if (result == DNS_R_NXDOMAIN && fctx->qmin_labels == dns_name_countlabels(fctx->name)) { - LOCK(&fctx->lock); - resp = ISC_LIST_HEAD(fctx->resps); - if (resp != NULL) { - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_clone(&rdataset, - resp->rdataset); - } - if (dns_rdataset_isassociated(&sigrdataset) && - resp->sigrdataset != NULL) - { - dns_rdataset_clone(&sigrdataset, - resp->sigrdataset); - } - if (db != NULL) { - dns_db_attach(db, &resp->db); - } - if (node != NULL) { - dns_db_attachnode(node, &resp->node); - } - dns_name_copy(fname, resp->foundname); - clone_results(fctx); - UNLOCK(&fctx->lock); - goto cleanup; - } - UNLOCK(&fctx->lock); + pull_from_resp(resp, fctx); + goto cleanup; } /* ...or disable minimization in relaxed mode */ @@ -4437,39 +4469,23 @@ resume_qmin(void *arg) { fctx->type != dns_rdatatype_sig && fctx->type != dns_rdatatype_rrsig) { - LOCK(&fctx->lock); - resp = ISC_LIST_HEAD(fctx->resps); - if (resp != NULL) { - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_clone(&rdataset, - resp->rdataset); - } - if (dns_rdataset_isassociated(&sigrdataset) && - resp->sigrdataset != NULL) - { - dns_rdataset_clone(&sigrdataset, - resp->sigrdataset); - } - if (db != NULL) { - dns_db_attach(db, &resp->db); - } - if (node != NULL) { - dns_db_attachnode(node, &resp->node); - } - dns_name_copy(fname, resp->foundname); - clone_results(fctx); - if (result == DNS_R_CNAME && - dns_rdataset_isassociated(&rdataset) && - fctx->type == dns_rdatatype_cname) - { - fctx_success_unref(fctx); - result = ISC_R_SUCCESS; - } else { - UNLOCK(&fctx->lock); - } - goto cleanup; + pull_from_resp(resp, fctx); + + if (result == DNS_R_CNAME && + dns_rdataset_isassociated(resp->rdataset) && + fctx->type == dns_rdatatype_cname) + { + LOCK(&fctx->lock); + fctx_success_unref(fctx); + result = ISC_R_SUCCESS; + /* + * `fctx_success_unref()` directly goes into the + * `fctx__done()` flow which expect fctx to be + * locked in case of success. + */ } - UNLOCK(&fctx->lock); + + goto cleanup; } /* @@ -4491,6 +4507,7 @@ resume_qmin(void *arg) { break; } + clear_resp(&resp); dns_rdataset_cleanup(&fctx->nameservers); if (dns_rdatatype_atparent(fctx->type)) { @@ -4510,7 +4527,7 @@ resume_qmin(void *arg) { CHECK(fcount_incr(fctx, false)); - dns_name_copy(dcname, fctx->qmindcname); + dns_name_copy(dcname, fctx->qmin.dcname); fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = true; @@ -4530,14 +4547,8 @@ resume_qmin(void *arg) { fctx_try(fctx, true); cleanup: - if (node != NULL) { - dns_db_detachnode(&node); - } - if (db != NULL) { - dns_db_detach(&db); - } - dns_rdataset_cleanup(&rdataset); - dns_rdataset_cleanup(&sigrdataset); + clear_resp(&resp); + if (result != ISC_R_SUCCESS) { /* An error occurred, tear down whole fctx */ fctx_failure_unref(fctx, result); @@ -4623,6 +4634,12 @@ fctx__destroy(fetchctx_t *fctx, const char *func, const char *file, dns_ede_invalidate(&fctx->edectx); + if (fctx->resp_node != NULL) { + dns_db_detachnode(&fctx->resp_node); + } + dns_rdataset_cleanup(&fctx->resp.rdataset); + dns_rdataset_cleanup(&fctx->resp.sigrdataset); + isc_mem_free(fctx->mctx, fctx->info); call_rcu(&fctx->rcu_head, fctx_destroy_rcu); @@ -4719,16 +4736,7 @@ fctx_add_event(fetchctx_t *fctx, isc_loop_t *loop, const isc_sockaddr_t *client, isc_mem_attach(fctx->mctx, &resp->mctx); resp->foundname = dns_fixedname_initname(&resp->fname); - - /* - * Store the sigrdataset in the first resp in case it is needed - * by any of the events. - */ - if (resp->sigrdataset != NULL) { - ISC_LIST_PREPEND(fctx->resps, resp, link); - } else { - ISC_LIST_APPEND(fctx->resps, resp, link); - } + ISC_LIST_APPEND(fctx->resps, resp, link); } static void @@ -4789,31 +4797,30 @@ fctx__create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, REQUIRE(fctxp != NULL && *fctxp == NULL); fctx = isc_mem_get(mctx, sizeof(*fctx)); - *fctx = (fetchctx_t){ - .type = type, - .qmintype = type, - .options = options, - .tid = isc_tid(), - .state = fetchstate_active, - .depth = depth, - .qmin_labels = 1, - .fwdpolicy = dns_fwdpolicy_none, - .result = ISC_R_FAILURE, - .loop = loop, - .queries = ISC_LIST_INITIALIZER, - .finds = ISC_LIST_INITIALIZER, - .altfinds = ISC_LIST_INITIALIZER, - .forwaddrs = ISC_LIST_INITIALIZER, - .altaddrs = ISC_LIST_INITIALIZER, - .forwarders = ISC_LIST_INITIALIZER, - .bad = ISC_LIST_INITIALIZER, - .edns = ISC_LIST_INITIALIZER, - .validators = ISC_LIST_INITIALIZER, - .nameservers = DNS_RDATASET_INIT, - .qminrrset = DNS_RDATASET_INIT, - .qminsigrrset = DNS_RDATASET_INIT, - .nsrrset = DNS_RDATASET_INIT, - }; + *fctx = (fetchctx_t){ .type = type, + .qmintype = type, + .options = options, + .tid = isc_tid(), + .state = fetchstate_active, + .depth = depth, + .qmin_labels = 1, + .fwdpolicy = dns_fwdpolicy_none, + .result = ISC_R_FAILURE, + .loop = loop, + .queries = ISC_LIST_INITIALIZER, + .finds = ISC_LIST_INITIALIZER, + .altfinds = ISC_LIST_INITIALIZER, + .forwaddrs = ISC_LIST_INITIALIZER, + .altaddrs = ISC_LIST_INITIALIZER, + .forwarders = ISC_LIST_INITIALIZER, + .bad = ISC_LIST_INITIALIZER, + .edns = ISC_LIST_INITIALIZER, + .validators = ISC_LIST_INITIALIZER, + .nameservers = DNS_RDATASET_INIT, + .nsrrset = DNS_RDATASET_INIT, + .resp_result = DNS_R_SERVFAIL, + .qmin.rdataset = DNS_RDATASET_INIT, + .qmin.sigrdataset = DNS_RDATASET_INIT }; isc_mem_attach(mctx, &fctx->mctx); dns_resolver_attach(res, &fctx->res); @@ -4825,12 +4832,12 @@ fctx__create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, fctx->name = dns_fixedname_initname(&fctx->fname); fctx->nsname = dns_fixedname_initname(&fctx->nsfname); fctx->domain = dns_fixedname_initname(&fctx->dfname); - fctx->qminname = dns_fixedname_initname(&fctx->qminfname); - fctx->qmindcname = dns_fixedname_initname(&fctx->qmindcfname); + fctx->qmin.name = dns_fixedname_initname(&fctx->qmin.fname); + fctx->qmin.dcname = dns_fixedname_initname(&fctx->qmin.dcfname); fctx->fwdname = dns_fixedname_initname(&fctx->fwdfname); dns_name_copy(name, fctx->name); - dns_name_copy(name, fctx->qminname); + dns_name_copy(name, fctx->qmin.name); fctx->start = isc_time_now(); fctx->now = (isc_stdtime_t)fctx->start.seconds; @@ -4926,7 +4933,7 @@ fctx__create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, * domain. */ dns_name_copy(fctx->fwdname, fctx->domain); - dns_name_copy(fctx->fwdname, fctx->qmindcname); + dns_name_copy(fctx->fwdname, fctx->qmin.dcname); /* * Disable query minimization */ @@ -4952,14 +4959,14 @@ fctx__create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, } dns_name_copy(fctx->fwdname, fctx->domain); - dns_name_copy(dcname, fctx->qmindcname); + dns_name_copy(dcname, fctx->qmin.dcname); fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = true; } } else { dns_rdataset_clone(nameservers, &fctx->nameservers); dns_name_copy(domain, fctx->domain); - dns_name_copy(domain, fctx->qmindcname); + dns_name_copy(domain, fctx->qmin.dcname); fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = true; } @@ -5243,50 +5250,6 @@ same_question(fetchctx_t *fctx, dns_message_t *message) { return ISC_R_SUCCESS; } -static void -clone_results(fetchctx_t *fctx) { - dns_fetchresponse_t *hresp = NULL; - - REQUIRE(!ISC_LIST_EMPTY(fctx->resps)); - - /* - * Set up any other resps to have the same data as the first. - * Caller must be holding the appropriate lock. - */ - - FCTXTRACE("clone_results"); - - ISC_LIST_FOREACH(fctx->resps, resp, link) { - /* This is the head resp; keep a pointer and move on */ - if (hresp == NULL) { - hresp = ISC_LIST_HEAD(fctx->resps); - FCTXTRACEN("clone_results", hresp->foundname, - hresp->result); - continue; - } - - resp->result = hresp->result; - dns_name_copy(hresp->foundname, resp->foundname); - dns_db_attach(hresp->db, &resp->db); - dns_db_attachnode(hresp->node, &resp->node); - - INSIST(hresp->rdataset != NULL && resp->rdataset != NULL); - if (dns_rdataset_isassociated(hresp->rdataset)) { - dns_rdataset_clone(hresp->rdataset, resp->rdataset); - } - - INSIST(hresp->sigrdataset != NULL || resp->sigrdataset == NULL); - if (resp->sigrdataset != NULL && hresp->sigrdataset != NULL && - dns_rdataset_isassociated(hresp->sigrdataset)) - { - dns_rdataset_clone(hresp->sigrdataset, - resp->sigrdataset); - } - } - - fctx->cloned = true; -} - #define CACHE(r) (((r)->attributes.cache)) #define ANSWER(r) (((r)->attributes.answer)) #define ANSWERSIG(r) (((r)->attributes.answersig)) @@ -5382,27 +5345,28 @@ has_000_label(dns_rdataset_t *nsecset) { return false; } -static isc_result_t -fctx_setresult(fetchctx_t *fctx, dns_rdataset_t *rdataset) { - isc_result_t eresult = ISC_R_SUCCESS; +static void +fctx_setresult(fetchctx_t *fctx) { + isc_result_t result = ISC_R_SUCCESS; + dns_rdataset_t *rdataset = &fctx->resp.rdataset; if (NEGATIVE(rdataset)) { - eresult = NXDOMAIN(rdataset) ? DNS_R_NCACHENXDOMAIN - : DNS_R_NCACHENXRRSET; - } else if (eresult == ISC_R_SUCCESS && rdataset->type != fctx->type) { + result = NXDOMAIN(rdataset) ? DNS_R_NCACHENXDOMAIN + : DNS_R_NCACHENXRRSET; + } else if (result == ISC_R_SUCCESS && rdataset->type != fctx->type) { switch (rdataset->type) { case dns_rdatatype_cname: - eresult = DNS_R_CNAME; + result = DNS_R_CNAME; break; case dns_rdatatype_dname: - eresult = DNS_R_DNAME; + result = DNS_R_DNAME; break; default: break; } } - return eresult; + fctx->resp_result = result; } static inline dns_trust_t @@ -5617,7 +5581,6 @@ validated(void *arg) { dns_validator_t *nextval = NULL; dns_adbaddrinfo_t *addrinfo = NULL; dns_dbnode_t *node = NULL; - dns_fetchresponse_t *resp = NULL; dns_rdataset_t *ardataset = NULL, *asigrdataset = NULL; dns_message_t *message = NULL; fetchctx_t *fctx = NULL; @@ -5698,12 +5661,9 @@ validated(void *arg) { * we pass an rdataset back to the caller. Otherwise the caller * iterates the node. */ - resp = ISC_LIST_HEAD(fctx->resps); - if (resp != NULL && - (negative || chaining || !dns_rdatatype_ismulti(fctx->type))) - { - ardataset = resp->rdataset; - asigrdataset = resp->sigrdataset; + if (negative || chaining || !dns_rdatatype_ismulti(fctx->type)) { + ardataset = &fctx->resp.rdataset; + asigrdataset = &fctx->resp.sigrdataset; } /* @@ -5787,15 +5747,11 @@ answer_response: * We're responding with an answer, positive or negative, * not an error. */ - if (resp != NULL) { - FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); + FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); - resp->result = fctx_setresult(fctx, resp->rdataset); - dns_name_copy(val->name, resp->foundname); - dns_db_attach(fctx->cache, &resp->db); - dns_db_transfernode(fctx->cache, &node, &resp->node); - clone_results(fctx); - } + fctx_setresult(fctx); + dns_name_copy(val->name, fctx->resp.foundname); + dns_db_transfernode(fctx->cache, &node, &fctx->resp_node); done = true; @@ -6021,7 +5977,6 @@ rctx_cache_secure(respctx_t *rctx, dns_message_t *message, dns_name_t *name, fetchctx_t *fctx = rctx->fctx; resquery_t *query = rctx->query; dns_rdataset_t *ardataset = NULL, *asigset = NULL; - dns_fetchresponse_t *resp = ISC_LIST_HEAD(fctx->resps); /* * RRSIGs are validated as part of validating the type they cover. @@ -6086,12 +6041,11 @@ rctx_cache_secure(respctx_t *rctx, dns_message_t *message, dns_name_t *name, * but we got a CNAME/DNAME - then we need to * set up rdatasets to send back to the caller. */ - if (resp != NULL && - (!dns_rdatatype_ismulti(fctx->type) || - CHAINING(rdataset))) + if (!dns_rdatatype_ismulti(fctx->type) || + CHAINING(rdataset)) { - ardataset = resp->rdataset; - asigset = resp->sigrdataset; + ardataset = &fctx->resp.rdataset; + asigset = &fctx->resp.sigrdataset; } } @@ -6114,7 +6068,6 @@ rctx_cache_insecure(respctx_t *rctx, dns_message_t *message, dns_name_t *name, dns_rdataset_t *sigrdataset) { isc_result_t result; fetchctx_t *fctx = rctx->fctx; - dns_fetchresponse_t *resp = ISC_LIST_HEAD(fctx->resps); dns_rdataset_t *added = NULL; /* @@ -6122,13 +6075,11 @@ rctx_cache_insecure(respctx_t *rctx, dns_message_t *message, dns_name_t *name, * CNAME/DNAME - then we need to set up an rdataset to send * back to the caller. */ - if (resp != NULL && - (!dns_rdatatype_ismulti(fctx->type) || CHAINING(rdataset))) - { + if (!dns_rdatatype_ismulti(fctx->type) || CHAINING(rdataset)) { if (ANSWER(rdataset)) { - added = resp->rdataset; + added = &fctx->resp.rdataset; } else if (ANSWERSIG(rdataset)) { - added = resp->sigrdataset; + added = &fctx->resp.sigrdataset; } } @@ -6238,22 +6189,14 @@ rctx_cachename(respctx_t *rctx, dns_message_t *message, dns_name_t *name) { * it back to the caller. */ if (!need_validation && name->attributes.answer && !HAVE_ANSWER(fctx)) { - dns_fetchresponse_t *resp = ISC_LIST_HEAD(fctx->resps); - if (resp != NULL) { - isc_result_t eresult = ISC_R_SUCCESS; + fctx->resp_result = ISC_R_SUCCESS; - if (dns_rdataset_isassociated(resp->rdataset)) { - eresult = fctx_setresult(fctx, resp->rdataset); - } - - resp->result = eresult; - dns_name_copy(name, resp->foundname); - dns_db_attach(fctx->cache, &resp->db); - dns_db_transfernode(fctx->cache, &node, &resp->node); - clone_results(fctx); - - FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); + if (dns_rdataset_isassociated(&fctx->resp.rdataset)) { + fctx_setresult(fctx); } + dns_name_copy(name, fctx->resp.foundname); + dns_db_transfernode(fctx->cache, &node, &fctx->resp_node); + FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); } cleanup: @@ -6372,7 +6315,6 @@ rctx_ncache(respctx_t *rctx) { dns_message_t *message = rctx->query->rmessage; dns_adbaddrinfo_t *addrinfo = rctx->query->addrinfo; dns_dbnode_t *node = NULL; - dns_fetchresponse_t *resp = NULL; dns_rdataset_t *added = NULL; FCTXTRACE("rctx_ncache"); @@ -6425,9 +6367,8 @@ rctx_ncache(respctx_t *rctx) { * Cache the negative answer, and copy it into the fetch response. */ LOCK(&fctx->lock); - resp = ISC_LIST_HEAD(fctx->resps); - if (!HAVE_ANSWER(fctx) && resp != NULL) { - added = resp->rdataset; + if (!HAVE_ANSWER(fctx)) { + added = &fctx->resp.rdataset; } result = negcache(message, fctx, name, rctx->now, false, false, added, @@ -6437,13 +6378,9 @@ rctx_ncache(respctx_t *rctx) { } FCTX_ATTR_SET(fctx, FCTX_ATTR_HAVEANSWER); - if (resp != NULL) { - resp->result = fctx_setresult(fctx, resp->rdataset); - dns_name_copy(name, resp->foundname); - dns_db_attach(fctx->cache, &resp->db); - dns_db_transfernode(fctx->cache, &node, &resp->node); - clone_results(fctx); - } + fctx_setresult(fctx); + dns_name_copy(name, fctx->resp.foundname); + dns_db_transfernode(fctx->cache, &node, &fctx->resp_node); unlock: UNLOCK(&fctx->lock); @@ -6890,8 +6827,8 @@ resume_dslookup(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } /* Preserve data from resp before freeing it. */ @@ -9103,7 +9040,7 @@ rctx_referral(respctx_t *rctx) { dns_name_copy(rctx->ns_name, fctx->domain); if ((fctx->options & DNS_FETCHOPT_QMINIMIZE) != 0) { - dns_name_copy(rctx->ns_name, fctx->qmindcname); + dns_name_copy(rctx->ns_name, fctx->qmin.dcname); fctx_minimize_qname(fctx); } @@ -9243,7 +9180,7 @@ rctx_nextserver(respctx_t *rctx, dns_message_t *message, fcount_decr(fctx); dns_name_copy(fname, fctx->domain); - dns_name_copy(dcname, fctx->qmindcname); + dns_name_copy(dcname, fctx->qmin.dcname); result = fcount_incr(fctx, true); if (result != ISC_R_SUCCESS) { @@ -9867,8 +9804,8 @@ prime_done(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } dns_rdataset_cleanup(resp->rdataset); INSIST(resp->sigrdataset == NULL); @@ -10000,7 +9937,7 @@ fctx_minimize_qname(fetchctx_t *fctx) { dns_name_init(&name); - dlabels = dns_name_countlabels(fctx->qmindcname); + dlabels = dns_name_countlabels(fctx->qmin.dcname); nlabels = dns_name_countlabels(fctx->name); if (dlabels > fctx->qmin_labels) { @@ -10073,18 +10010,18 @@ fctx_minimize_qname(fetchctx_t *fctx) { } if (fctx->qmin_labels < nlabels) { - dns_name_copy(&name, fctx->qminname); + dns_name_copy(&name, fctx->qmin.name); fctx->qmintype = dns_rdatatype_ns; fctx->minimized = true; } else { /* Minimization is done, we'll ask for whole qname */ - dns_name_copy(fctx->name, fctx->qminname); + dns_name_copy(fctx->name, fctx->qmin.name); fctx->qmintype = fctx->type; fctx->minimized = false; } char domainbuf[DNS_NAME_FORMATSIZE]; - dns_name_format(fctx->qminname, domainbuf, sizeof(domainbuf)); + dns_name_format(fctx->qmin.name, domainbuf, sizeof(domainbuf)); isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(5), "QNAME minimization - %s minimized, qmintype %d " @@ -10164,7 +10101,7 @@ get_attached_fctx(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, goto create; } - if (SHUTTINGDOWN(fctx) || fctx->cloned) { + if (SHUTTINGDOWN(fctx)) { /* The fctx will get deleted either here or in fctx__done() */ cds_lfht_del(res->fctxs_ht, &fctx->ht_node); @@ -10419,7 +10356,7 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) { * Sanity check: the caller should have gotten its event before * trying to destroy the fetch. */ - if (fctx->state != fetchstate_done) { + if (!SHUTTINGDOWN(fctx)) { ISC_LIST_FOREACH(fctx->resps, resp, link) { RUNTIME_CHECK(resp->fetch != fetch); } @@ -10731,9 +10668,7 @@ dns_resolver_dumpfetches(dns_resolver_t *res, isc_statsformat_t format, dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf)); fprintf(fp, "/%s (%s), 0x%x: started %s, ", typebuf, - fctx->state == fetchstate_done ? "done" - : fctx->cloned ? "cloned" - : "active", + fctx->state == fetchstate_done ? "done" : "active", fctx->options, timebuf); ISC_LIST_FOREACH(fctx->resps, resp, link) { @@ -10892,7 +10827,7 @@ dns_resolver_freefresp(dns_fetchresponse_t **frespp) { } dns_fetchresponse_t *fresp = *frespp; - *frespp = NULL; + isc_mem_putanddetach(&fresp->mctx, fresp, sizeof(*fresp)); } diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 5316e9a666..2e731a7576 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -427,8 +427,8 @@ fetch_callback_dnskey(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } dns_rdataset_cleanup(&val->fsigrdataset); @@ -520,8 +520,8 @@ fetch_callback_ds(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } dns_rdataset_cleanup(&val->fsigrdataset); diff --git a/lib/dns/zonefetch.c b/lib/dns/zonefetch.c index d8a5df9b18..d73c6df6ef 100644 --- a/lib/dns/zonefetch.c +++ b/lib/dns/zonefetch.c @@ -148,8 +148,8 @@ dns_zonefetch_done(void *arg) { if (resp->node != NULL) { dns_db_detachnode(&resp->node); } - if (resp->db != NULL) { - dns_db_detach(&resp->db); + if (resp->cache != NULL) { + dns_db_detach(&resp->cache); } dns_resolver_destroyfetch(&fetch->fetch); diff --git a/lib/ns/query.c b/lib/ns/query.c index b23db80903..59165a2537 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -2591,8 +2591,8 @@ free_fresp(ns_client_t *client, dns_fetchresponse_t **frespp) { if (fresp->node != NULL) { dns_db_detachnode(&fresp->node); } - if (fresp->db != NULL) { - dns_db_detach(&fresp->db); + if (fresp->cache != NULL) { + dns_db_detach(&fresp->cache); } if (fresp->rdataset != NULL) { ns_client_putrdataset(client, &fresp->rdataset); @@ -6385,7 +6385,7 @@ query_resume(query_ctx_t *qctx) { if (qctx->fresp->node != NULL) { dns_db_detachnode(&qctx->fresp->node); } - SAVE(qctx->rpz_st->r.db, qctx->fresp->db); + SAVE(qctx->rpz_st->r.db, qctx->fresp->cache); qctx->rpz_st->r.r_type = qctx->fresp->qtype; SAVE(qctx->rpz_st->r.r_rdataset, qctx->fresp->rdataset); ns_client_putrdataset(qctx->client, &qctx->fresp->sigrdataset); @@ -6423,15 +6423,15 @@ query_resume(query_ctx_t *qctx) { if (qctx->fresp->node != NULL) { dns_db_detachnode(&qctx->fresp->node); } - if (qctx->fresp->db != NULL) { - dns_db_detach(&qctx->fresp->db); + if (qctx->fresp->cache != NULL) { + dns_db_detach(&qctx->fresp->cache); } } else { CCTRACE(ISC_LOG_DEBUG(3), "resume from normal recursion"); qctx->authoritative = false; qctx->qtype = qctx->fresp->qtype; - SAVE(qctx->db, qctx->fresp->db); + SAVE(qctx->db, qctx->fresp->cache); SAVE(qctx->node, qctx->fresp->node); SAVE(qctx->rdataset, qctx->fresp->rdataset); SAVE(qctx->sigrdataset, qctx->fresp->sigrdataset);