From: Colin Vidal Date: Thu, 15 Jan 2026 16:36:50 +0000 (+0100) Subject: resolver: copy fetch responses and send events in one go X-Git-Tag: v9.21.19~30^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5972ee2cd599036d09f171a94701a6187fc6e668;p=thirdparty%2Fbind9.git resolver: copy fetch responses and send events in one go Instead of first copying query response data into each fetch response and then iterating again to send the response to the caller, perform both operations in one go. Also removed some duplicate code. --- diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index aae71053f05..dbc3a3bb8df 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -1624,35 +1624,41 @@ static void spillattimer_countdown(void *arg); static void -clone_results(fetchctx_t *fctx) { - REQUIRE(!ISC_LIST_EMPTY(fctx->resps)); +copy_to_resp(fetchctx_t *fctx, dns_fetchresponse_t *resp) { + resp->result = fctx->resp_result; - /* - * Set up any other resps to have the same data as the first. - * Caller must be holding the appropriate lock. - */ + dns_name_copy(dns_fixedname_name(&fctx->resp_foundname), + resp->foundname); - FCTXTRACE("clone_results"); + dns_db_attach(fctx->resp_db, &resp->db); + dns_db_attachnode(fctx->resp_node, &resp->node); - ISC_LIST_FOREACH(fctx->resps, resp, link) { - resp->result = fctx->resp_result; - dns_name_copy(dns_fixedname_name(&fctx->resp_foundname), - resp->foundname); - dns_db_attach(fctx->resp_db, &resp->db); - dns_db_attachnode(fctx->resp_node, &resp->node); - - if (dns_rdataset_isassociated(&fctx->resp_rdataset)) { - dns_rdataset_clone(&fctx->resp_rdataset, - resp->rdataset); - } + 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); + } +} - 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->db != NULL) { + dns_db_attach(resp->db, &fctx->resp_db); } + if (resp->node != NULL) { + dns_db_attachnode(resp->node, &fctx->resp_node); + } + dns_name_copy(resp->foundname, + dns_fixedname_name(&fctx->resp_foundname)); } static void @@ -1668,9 +1674,6 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result) { REQUIRE(fctx->state == fetchstate_done); - if (result == ISC_R_SUCCESS) { - clone_results(fctx); - } FCTXTRACE("sendevents"); /* @@ -1683,6 +1686,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; @@ -4331,6 +4337,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->db != NULL) { + dns_db_detach(&resp->db); + } + 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; @@ -4340,10 +4366,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)); @@ -4356,32 +4378,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; @@ -4413,22 +4411,7 @@ resume_qmin(void *arg) { if (result == DNS_R_NXDOMAIN && fctx->qmin_labels == dns_name_countlabels(fctx->name)) { - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_clone(&rdataset, - &fctx->resp_rdataset); - } - if (dns_rdataset_isassociated(&sigrdataset)) { - dns_rdataset_clone(&sigrdataset, - &fctx->resp_sigrdataset); - } - if (db != NULL) { - dns_db_attach(db, &fctx->resp_db); - } - if (node != NULL) { - dns_db_attachnode(node, &fctx->resp_node); - } - dns_name_copy(fname, dns_fixedname_name( - &fctx->resp_foundname)); + pull_from_resp(resp, fctx); goto cleanup; } @@ -4472,25 +4455,10 @@ resume_qmin(void *arg) { fctx->type != dns_rdatatype_sig && fctx->type != dns_rdatatype_rrsig) { - if (dns_rdataset_isassociated(&rdataset)) { - dns_rdataset_clone(&rdataset, - &fctx->resp_rdataset); - } - if (dns_rdataset_isassociated(&sigrdataset)) { - dns_rdataset_clone(&sigrdataset, - &fctx->resp_sigrdataset); - } - if (db != NULL) { - dns_db_attach(db, &fctx->resp_db); - } - if (node != NULL) { - dns_db_attachnode(node, &fctx->resp_node); - } - dns_name_copy(fname, dns_fixedname_name( - &fctx->resp_foundname)); + pull_from_resp(resp, fctx); if (result == DNS_R_CNAME && - dns_rdataset_isassociated(&rdataset) && + dns_rdataset_isassociated(resp->rdataset) && fctx->type == dns_rdatatype_cname) { LOCK(&fctx->lock); @@ -4525,6 +4493,7 @@ resume_qmin(void *arg) { break; } + clear_resp(&resp); dns_rdataset_cleanup(&fctx->nameservers); if (dns_rdatatype_atparent(fctx->type)) { @@ -4564,14 +4533,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); @@ -10859,7 +10822,7 @@ dns_resolver_freefresp(dns_fetchresponse_t **frespp) { } dns_fetchresponse_t *fresp = *frespp; - *frespp = NULL; + isc_mem_putanddetach(&fresp->mctx, fresp, sizeof(*fresp)); }