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