From 80bc0ee0751073ffdea8e09a1f03fc3575cd5f51 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 23 May 2023 14:02:29 +1000 Subject: [PATCH] Skip some QNAME mininisation queries if possible If we know that the NS RRset for an intermediate label doesn't exist on cache contents don't query using that name when looking for a referral. --- lib/dns/resolver.c | 79 ++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index c747551881..d298141300 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -647,7 +647,7 @@ static void fctx_try(fetchctx_t *fctx, bool retrying, bool badcache); static void fctx_shutdown(fetchctx_t *fctx); -static isc_result_t +static void fctx_minimize_qname(fetchctx_t *fctx); static void fctx_destroy(fetchctx_t *fctx); @@ -4214,10 +4214,7 @@ resume_qmin(void *arg) { fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = true; - result = fctx_minimize_qname(fctx); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } + fctx_minimize_qname(fctx); if (!fctx->minimized) { /* @@ -4701,10 +4698,7 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, fctx->ip6arpaskip = (options & DNS_FETCHOPT_QMIN_SKIP_IP6A) != 0 && dns_name_issubdomain(fctx->name, &ip6_arpa); - result = fctx_minimize_qname(fctx); - if (result != ISC_R_SUCCESS) { - goto cleanup_mctx; - } + fctx_minimize_qname(fctx); } nfctx = atomic_fetch_add_relaxed(&res->nfctx, 1); @@ -4718,11 +4712,6 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, return (ISC_R_SUCCESS); -cleanup_mctx: - fctx->magic = 0; - dns_adb_detach(&fctx->adb); - dns_db_detach(&fctx->cache); - cleanup_timer: isc_timer_destroy(&fctx->timer); @@ -9256,11 +9245,7 @@ rctx_referral(respctx_t *rctx) { if ((fctx->options & DNS_FETCHOPT_QMINIMIZE) != 0) { dns_name_copy(rctx->ns_name, fctx->qmindcname); - result = fctx_minimize_qname(fctx); - if (result != ISC_R_SUCCESS) { - rctx->result = result; - return (ISC_R_COMPLETE); - } + fctx_minimize_qname(fctx); } result = fcount_incr(fctx, true); @@ -10145,13 +10130,16 @@ log_fetch(const dns_name_t *name, dns_rdatatype_t type) { typebuf); } -static isc_result_t +static void fctx_minimize_qname(fetchctx_t *fctx) { - isc_result_t result = ISC_R_SUCCESS; + isc_result_t result; unsigned int dlabels, nlabels; + dns_name_t name; REQUIRE(VALID_FCTX(fctx)); + dns_name_init(&name, NULL); + dlabels = dns_name_countlabels(fctx->qmindcname); nlabels = dns_name_countlabels(fctx->name); @@ -10190,19 +10178,50 @@ fctx_minimize_qname(fetchctx_t *fctx) { } if (fctx->qmin_labels < nlabels) { - /* - * We want to query for qmin_labels from fctx->name - */ - dns_fixedname_t fname; - dns_name_t *name = dns_fixedname_initname(&fname); - dns_name_split(fctx->name, fctx->qmin_labels, NULL, name); - dns_name_copy(name, fctx->qminname); + dns_rdataset_t rdataset; + dns_fixedname_t fixed; + dns_name_t *fname = dns_fixedname_initname(&fixed); + dns_rdataset_init(&rdataset); + do { + /* + * We want to query for qmin_labels from fctx->name. + */ + dns_name_split(fctx->name, fctx->qmin_labels, NULL, + &name); + /* + * Look to see if we have anything cached about NS + * RRsets at this name and if so skip this name and + * try with an additional label prepended. + */ + result = dns_db_find(fctx->cache, &name, NULL, + dns_rdatatype_ns, 0, 0, NULL, + fname, &rdataset, NULL); + if (dns_rdataset_isassociated(&rdataset)) { + dns_rdataset_disassociate(&rdataset); + } + switch (result) { + case ISC_R_SUCCESS: + case DNS_R_CNAME: + case DNS_R_DNAME: + case DNS_R_NCACHENXDOMAIN: + case DNS_R_NCACHENXRRSET: + fctx->qmin_labels++; + continue; + default: + break; + } + break; + } while (fctx->qmin_labels < nlabels); + } + + if (fctx->qmin_labels < nlabels) { + dns_name_copy(&name, fctx->qminname); fctx->qmintype = dns_rdatatype_ns; fctx->minimized = true; } else { /* Minimization is done, we'll ask for whole qname */ - fctx->qmintype = fctx->type; dns_name_copy(fctx->name, fctx->qminname); + fctx->qmintype = fctx->type; fctx->minimized = false; } @@ -10213,8 +10232,6 @@ fctx_minimize_qname(fetchctx_t *fctx) { "QNAME minimization - %s minimized, qmintype %d " "qminname %s", fctx->minimized ? "" : "not", fctx->qmintype, domainbuf); - - return (result); } static isc_result_t