use a qp-trie for the forwarders table

Instead of an RBT for the forwarders table, use a QP trie.

We now use reference counting for dns_forwarders_t. When a forwarders
object is retrieved by dns_fwdtable_find(), it must now be explicitly
detached by the caller afterward.

QP tries require stored objects to include their names, so the
the forwarders object now has that. This obviates the need to
pass back a separate 'foundname' value from dns_fwdtable_find().
This commit is contained in:
Evan Hunt 2023-04-05 23:08:12 -07:00 committed by Ondřej Surý
parent 5768dd96ea
commit dea79e7053
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
5 changed files with 202 additions and 127 deletions

View file

@ -2681,8 +2681,7 @@ catz_addmodzone_cb(void *arg) {
dns_name_totext(name, true, &namebuf);
isc_buffer_putuint8(&namebuf, 0);
result = dns_fwdtable_find(cz->view->fwdtable, name, NULL,
&dnsforwarders);
result = dns_fwdtable_find(cz->view->fwdtable, name, &dnsforwarders);
if (result == ISC_R_SUCCESS &&
dnsforwarders->fwdpolicy == dns_fwdpolicy_only)
{
@ -2858,6 +2857,9 @@ cleanup:
if (zoneconf != NULL) {
cfg_obj_destroy(cfg->add_parser, &zoneconf);
}
if (dnsforwarders != NULL) {
dns_forwarders_detach(&dnsforwarders);
}
dns_catz_entry_detach(cz->origin, &cz->entry);
dns_catz_zone_detach(&cz->origin);
dns_view_detach(&cz->view);
@ -5701,6 +5703,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
empty = empty_zones[++empty_zone])
{
dns_forwarders_t *dnsforwarders = NULL;
dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none;
/*
* Look for zone on drop list.
@ -5726,12 +5729,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
* If we would forward this name don't add a
* empty zone for it.
*/
result = dns_fwdtable_find(view->fwdtable, name, NULL,
result = dns_fwdtable_find(view->fwdtable, name,
&dnsforwarders);
if ((result == ISC_R_SUCCESS ||
result == DNS_R_PARTIALMATCH) &&
dnsforwarders->fwdpolicy == dns_fwdpolicy_only)
if (result == ISC_R_SUCCESS ||
result == DNS_R_PARTIALMATCH)
{
fwdpolicy = dnsforwarders->fwdpolicy;
dns_forwarders_detach(&dnsforwarders);
}
if (fwdpolicy == dns_fwdpolicy_only) {
continue;
}
@ -5803,6 +5809,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
ipv4only_zone++)
{
dns_forwarders_t *dnsforwarders = NULL;
dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none;
CHECK(dns_name_fromstring(
name, zones[ipv4only_zone].name, 0, NULL));
@ -5817,12 +5824,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
/*
* If we would forward this name don't add it.
*/
result = dns_fwdtable_find(view->fwdtable, name, NULL,
result = dns_fwdtable_find(view->fwdtable, name,
&dnsforwarders);
if ((result == ISC_R_SUCCESS ||
result == DNS_R_PARTIALMATCH) &&
dnsforwarders->fwdpolicy == dns_fwdpolicy_only)
if (result == ISC_R_SUCCESS ||
result == DNS_R_PARTIALMATCH)
{
fwdpolicy = dnsforwarders->fwdpolicy;
dns_forwarders_detach(&dnsforwarders);
}
if (fwdpolicy == dns_fwdpolicy_only) {
continue;
}

View file

@ -16,70 +16,88 @@
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/rwlock.h>
#include <isc/util.h>
#include <dns/fixedname.h>
#include <dns/forward.h>
#include <dns/name.h>
#include <dns/rbt.h>
#include <dns/qp.h>
#include <dns/types.h>
#include <dns/view.h>
struct dns_fwdtable {
/* Unlocked. */
unsigned int magic;
isc_mem_t *mctx;
isc_rwlock_t rwlock;
/* Locked by lock. */
dns_rbt_t *table;
dns_qpmulti_t *table;
};
#define FWDTABLEMAGIC ISC_MAGIC('F', 'w', 'd', 'T')
#define VALID_FWDTABLE(ft) ISC_MAGIC_VALID(ft, FWDTABLEMAGIC)
static void
auto_detach(void *, void *);
qp_attach(void *uctx, void *pval, uint32_t ival);
static void
qp_detach(void *uctx, void *pval, uint32_t ival);
static size_t
qp_makekey(dns_qpkey_t key, void *uctx, void *pval, uint32_t ival);
static void
qp_triename(void *uctx, char *buf, size_t size);
isc_result_t
dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) {
dns_fwdtable_t *fwdtable;
isc_result_t result;
static dns_qpmethods_t qpmethods = {
qp_attach,
qp_detach,
qp_makekey,
qp_triename,
};
void
dns_fwdtable_create(isc_mem_t *mctx, dns_view_t *view,
dns_fwdtable_t **fwdtablep) {
dns_fwdtable_t *fwdtable = NULL;
REQUIRE(fwdtablep != NULL && *fwdtablep == NULL);
fwdtable = isc_mem_get(mctx, sizeof(*fwdtable));
*fwdtable = (dns_fwdtable_t){ .magic = FWDTABLEMAGIC };
fwdtable->table = NULL;
result = dns_rbt_create(mctx, auto_detach, fwdtable, &fwdtable->table);
if (result != ISC_R_SUCCESS) {
goto cleanup_fwdtable;
}
dns_qpmulti_create(mctx, &qpmethods, view, &fwdtable->table);
isc_rwlock_init(&fwdtable->rwlock);
fwdtable->mctx = NULL;
isc_mem_attach(mctx, &fwdtable->mctx);
fwdtable->magic = FWDTABLEMAGIC;
*fwdtablep = fwdtable;
}
return (ISC_R_SUCCESS);
static dns_forwarders_t *
new_forwarders(isc_mem_t *mctx, const dns_name_t *name,
dns_fwdpolicy_t fwdpolicy) {
dns_forwarders_t *forwarders = NULL;
cleanup_fwdtable:
isc_mem_put(mctx, fwdtable, sizeof(*fwdtable));
forwarders = isc_mem_get(mctx, sizeof(*forwarders));
*forwarders = (dns_forwarders_t){
.fwdpolicy = fwdpolicy,
.fwdrs = ISC_LIST_INITIALIZER,
};
isc_mem_attach(mctx, &forwarders->mctx);
isc_refcount_init(&forwarders->references, 1);
return (result);
forwarders->name = dns_fixedname_initname(&forwarders->fn);
dns_name_copy(name, forwarders->name);
return (forwarders);
}
isc_result_t
dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, const dns_name_t *name,
dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t fwdpolicy) {
isc_result_t result;
dns_forwarders_t *forwarders;
dns_forwarder_t *fwd, *nfwd;
dns_forwarders_t *forwarders = NULL;
dns_forwarder_t *fwd = NULL, *nfwd = NULL;
dns_qp_t *qp = NULL;
REQUIRE(VALID_FWDTABLE(fwdtable));
forwarders = isc_mem_get(fwdtable->mctx, sizeof(*forwarders));
forwarders = new_forwarders(fwdtable->mctx, name, fwdpolicy);
ISC_LIST_INIT(forwarders->fwdrs);
for (fwd = ISC_LIST_HEAD(*fwdrs); fwd != NULL;
fwd = ISC_LIST_NEXT(fwd, link))
{
@ -97,13 +115,15 @@ dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, const dns_name_t *name,
ISC_LINK_INIT(nfwd, link);
ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
result = dns_rbt_addname(fwdtable->table, name, forwarders);
RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
dns_qpmulti_write(fwdtable->table, &qp);
result = dns_qp_insert(qp, forwarders, 0);
dns_qp_compact(qp, DNS_QPGC_MAYBE);
dns_qpmulti_commit(fwdtable->table, &qp);
if (result != ISC_R_SUCCESS) {
if (result == ISC_R_SUCCESS) {
dns_forwarders_detach(&forwarders);
} else {
goto cleanup;
}
@ -128,15 +148,15 @@ isc_result_t
dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name,
isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy) {
isc_result_t result;
dns_forwarders_t *forwarders;
dns_forwarder_t *fwd;
isc_sockaddr_t *sa;
dns_forwarders_t *forwarders = NULL;
dns_forwarder_t *fwd = NULL;
isc_sockaddr_t *sa = NULL;
dns_qp_t *qp = NULL;
REQUIRE(VALID_FWDTABLE(fwdtable));
forwarders = isc_mem_get(fwdtable->mctx, sizeof(*forwarders));
forwarders = new_forwarders(fwdtable->mctx, name, fwdpolicy);
ISC_LIST_INIT(forwarders->fwdrs);
for (sa = ISC_LIST_HEAD(*addrs); sa != NULL;
sa = ISC_LIST_NEXT(sa, link))
{
@ -145,13 +165,15 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name,
.link = ISC_LINK_INITIALIZER };
ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
result = dns_rbt_addname(fwdtable->table, name, forwarders);
RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
dns_qpmulti_write(fwdtable->table, &qp);
result = dns_qp_insert(qp, forwarders, 0);
dns_qp_compact(qp, DNS_QPGC_MAYBE);
dns_qpmulti_commit(fwdtable->table, &qp);
if (result != ISC_R_SUCCESS) {
if (result == ISC_R_SUCCESS) {
dns_forwarders_detach(&forwarders);
} else {
goto cleanup;
}
@ -169,30 +191,35 @@ cleanup:
isc_result_t
dns_fwdtable_find(dns_fwdtable_t *fwdtable, const dns_name_t *name,
dns_name_t *foundname, dns_forwarders_t **forwardersp) {
dns_forwarders_t **forwardersp) {
isc_result_t result;
dns_qpread_t qpr;
void *pval = NULL;
REQUIRE(VALID_FWDTABLE(fwdtable));
RWLOCK(&fwdtable->rwlock, isc_rwlocktype_read);
result = dns_rbt_findname(fwdtable->table, name, 0, foundname,
(void **)forwardersp);
RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_read);
dns_qpmulti_query(fwdtable->table, &qpr);
result = dns_qp_findname_ancestor(&qpr, name, 0, &pval, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
dns_forwarders_t *fwdrs = pval;
*forwardersp = fwdrs;
dns_forwarders_ref(fwdrs);
}
dns_qpread_destroy(fwdtable->table, &qpr);
return (result);
}
void
dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) {
dns_fwdtable_t *fwdtable;
dns_fwdtable_t *fwdtable = NULL;
REQUIRE(fwdtablep != NULL && VALID_FWDTABLE(*fwdtablep));
fwdtable = *fwdtablep;
*fwdtablep = NULL;
dns_rbt_destroy(&fwdtable->table);
isc_rwlock_destroy(&fwdtable->rwlock);
dns_qpmulti_destroy(&fwdtable->table);
fwdtable->magic = 0;
isc_mem_putanddetach(&fwdtable->mctx, fwdtable, sizeof(*fwdtable));
@ -203,22 +230,52 @@ dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep) {
***/
static void
auto_detach(void *data, void *arg) {
dns_forwarders_t *forwarders = data;
dns_fwdtable_t *fwdtable = arg;
dns_forwarder_t *fwd;
UNUSED(arg);
destroy_forwarders(dns_forwarders_t *forwarders) {
dns_forwarder_t *fwd = NULL;
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
if (fwd->tlsname != NULL) {
dns_name_free(fwd->tlsname, fwdtable->mctx);
isc_mem_put(fwdtable->mctx, fwd->tlsname,
dns_name_free(fwd->tlsname, forwarders->mctx);
isc_mem_put(forwarders->mctx, fwd->tlsname,
sizeof(*fwd->tlsname));
}
isc_mem_put(fwdtable->mctx, fwd, sizeof(*fwd));
isc_mem_put(forwarders->mctx, fwd, sizeof(*fwd));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(*forwarders));
isc_mem_putanddetach(&forwarders->mctx, forwarders,
sizeof(*forwarders));
}
#if DNS_FORWARD_TRACE
ISC_REFCOUNT_TRACE_IMPL(dns_forwarders, destroy_forwarders);
#else
ISC_REFCOUNT_IMPL(dns_forwarders, destroy_forwarders);
#endif
static void
qp_attach(void *uctx ISC_ATTR_UNUSED, void *pval,
uint32_t ival ISC_ATTR_UNUSED) {
dns_forwarders_t *forwarders = pval;
dns_forwarders_ref(forwarders);
}
static void
qp_detach(void *uctx ISC_ATTR_UNUSED, void *pval,
uint32_t ival ISC_ATTR_UNUSED) {
dns_forwarders_t *forwarders = pval;
dns_forwarders_detach(&forwarders);
}
static size_t
qp_makekey(dns_qpkey_t key, void *uctx ISC_ATTR_UNUSED, void *pval,
uint32_t ival ISC_ATTR_UNUSED) {
dns_forwarders_t *fwd = pval;
return (dns_qpkey_fromname(key, fwd->name));
}
static void
qp_triename(void *uctx, char *buf, size_t size) {
dns_view_t *view = uctx;
snprintf(buf, size, "view %s forwarder table", view->name);
}

View file

@ -16,11 +16,18 @@
/*! \file dns/forward.h */
#include <isc/lang.h>
#include <isc/mem.h>
#include <isc/refcount.h>
#include <isc/result.h>
#include <isc/sockaddr.h>
#include <dns/fixedname.h>
#include <dns/qp.h>
#include <dns/types.h>
/* Define to 1 for detailed reference tracing */
#undef DNS_FORWARD_TRACE
ISC_LANG_BEGINDECLS
struct dns_forwarder {
@ -34,20 +41,21 @@ typedef ISC_LIST(struct dns_forwarder) dns_forwarderlist_t;
struct dns_forwarders {
dns_forwarderlist_t fwdrs;
dns_fwdpolicy_t fwdpolicy;
isc_mem_t *mctx;
isc_refcount_t references;
dns_fixedname_t fn;
dns_name_t *name;
};
isc_result_t
dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep);
void
dns_fwdtable_create(isc_mem_t *mctx, dns_view_t *view,
dns_fwdtable_t **fwdtablep);
/*%<
* Creates a new forwarding table.
*
* Requires:
* \li mctx is a valid memory context.
* \li fwdtablep != NULL && *fwdtablep == NULL
*
* Returns:
* \li #ISC_R_SUCCESS
* \li #ISC_R_NOMEMORY
*/
isc_result_t
@ -75,7 +83,7 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name,
isc_result_t
dns_fwdtable_find(dns_fwdtable_t *fwdtable, const dns_name_t *name,
dns_name_t *foundname, dns_forwarders_t **forwardersp);
dns_forwarders_t **forwardersp);
/*%<
* Finds a domain in the forwarding table. The closest matching parent
* domain is returned.
@ -84,13 +92,11 @@ dns_fwdtable_find(dns_fwdtable_t *fwdtable, const dns_name_t *name,
* \li fwdtable is a valid forwarding table.
* \li name is a valid name
* \li forwardersp != NULL && *forwardersp == NULL
* \li foundname to be NULL or a valid name with buffer.
*
* Returns:
* \li #ISC_R_SUCCESS Success
* \li #DNS_R_PARTIALMATCH Superdomain found with data
* \li #ISC_R_NOTFOUND No match
* \li #ISC_R_NOSPACE Concatenating nodes to form foundname failed
*/
void
@ -105,4 +111,17 @@ dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep);
* \li all memory associated with the forwarding table is freed.
*/
#if DNS_FORWARD_TRACE
#define dns_forwarders_ref(ptr) \
dns_forwarders__ref(ptr, __func__, __FILE__, __LINE__)
#define dns_forwarders_unref(ptr) \
dns_forwarders__unref(ptr, __func__, __FILE__, __LINE__)
#define dns_forwarders_attach(ptr, ptrp) \
dns_forwarders__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
#define dns_forwarders_detach(ptrp) \
dns_forwarders__detach(ptrp, __func__, __FILE__, __LINE__)
ISC_REFCOUNT_TRACE_DECL(dns_forwarders);
#else
ISC_REFCOUNT_DECL(dns_forwarders);
#endif
ISC_LANG_ENDDECLS

View file

@ -3451,8 +3451,6 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
dns_forwarders_t *forwarders = NULL;
dns_name_t *name = fctx->name;
dns_name_t suffix;
dns_fixedname_t fixed;
dns_name_t *domain;
/*
* DS records are found in the parent server.
@ -3468,23 +3466,24 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
name = &suffix;
}
domain = dns_fixedname_initname(&fixed);
result = dns_fwdtable_find(res->view->fwdtable, name, domain,
result = dns_fwdtable_find(res->view->fwdtable, name,
&forwarders);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
fctx->fwdpolicy = forwarders->fwdpolicy;
dns_name_copy(domain, fctx->fwdname);
dns_name_copy(forwarders->name, fctx->fwdname);
if (fctx->fwdpolicy == dns_fwdpolicy_only &&
isstrictsubdomain(domain, fctx->domain))
isstrictsubdomain(forwarders->name, fctx->domain))
{
fcount_decr(fctx);
dns_name_copy(domain, fctx->domain);
dns_name_copy(forwarders->name, fctx->domain);
result = fcount_incr(fctx, true);
if (result != ISC_R_SUCCESS) {
dns_forwarders_detach(&forwarders);
return (result);
}
}
dns_forwarders_detach(&forwarders);
}
}
@ -4566,8 +4565,6 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
if (domain == NULL) {
dns_forwarders_t *forwarders = NULL;
dns_fixedname_t fixed;
dns_name_t *fname = dns_fixedname_initname(&fixed);
unsigned int labels;
const dns_name_t *fwdname = name;
dns_name_t suffix;
@ -4588,13 +4585,25 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
/* Find the forwarder for this name. */
result = dns_fwdtable_find(fctx->res->view->fwdtable, fwdname,
fname, &forwarders);
&forwarders);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
fctx->fwdpolicy = forwarders->fwdpolicy;
dns_name_copy(fname, fctx->fwdname);
dns_name_copy(forwarders->name, fctx->fwdname);
dns_forwarders_detach(&forwarders);
}
if (fctx->fwdpolicy != dns_fwdpolicy_only) {
if (fctx->fwdpolicy == dns_fwdpolicy_only) {
/*
* We're in forward-only mode. Set the query
* domain.
*/
dns_name_copy(fctx->fwdname, fctx->domain);
dns_name_copy(fctx->fwdname, fctx->qmindcname);
/*
* Disable query minimization
*/
options &= ~DNS_FETCHOPT_QMINIMIZE;
} else {
dns_fixedname_t dcfixed;
dns_name_t *dcname = dns_fixedname_initname(&dcfixed);
@ -4606,29 +4615,18 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name,
if (dns_rdatatype_atparent(fctx->type)) {
findoptions |= DNS_DBFIND_NOEXACT;
}
result = dns_view_findzonecut(res->view, name, fname,
dcname, fctx->now,
findoptions, true, true,
&fctx->nameservers, NULL);
result = dns_view_findzonecut(
res->view, name, fctx->fwdname, dcname,
fctx->now, findoptions, true, true,
&fctx->nameservers, NULL);
if (result != ISC_R_SUCCESS) {
goto cleanup_nameservers;
}
dns_name_copy(fname, fctx->domain);
dns_name_copy(fctx->fwdname, fctx->domain);
dns_name_copy(dcname, fctx->qmindcname);
fctx->ns_ttl = fctx->nameservers.ttl;
fctx->ns_ttl_ok = true;
} else {
/*
* We're in forward-only mode. Set the query
* domain.
*/
dns_name_copy(fname, fctx->domain);
dns_name_copy(fname, fctx->qmindcname);
/*
* Disable query minimization
*/
options &= ~DNS_FETCHOPT_QMINIMIZE;
}
} else {
dns_name_copy(domain, fctx->domain);
@ -6557,8 +6555,6 @@ static inline bool
name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
isc_result_t result;
dns_forwarders_t *forwarders = NULL;
dns_fixedname_t fixed;
dns_name_t *fname = dns_fixedname_initname(&fixed);
dns_name_t *apex = NULL;
dns_name_t suffix;
dns_zone_t *zone = NULL;
@ -6611,7 +6607,7 @@ name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
/*
* Look for a forward declaration below 'name'.
*/
result = dns_fwdtable_find(fctx->res->view->fwdtable, name, fname,
result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
&forwarders);
if (ISFORWARDER(fctx->addrinfo)) {
@ -6619,7 +6615,10 @@ name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
* See if the forwarder declaration is better.
*/
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
return (!dns_name_equal(fname, fctx->fwdname));
bool better = !dns_name_equal(forwarders->name,
fctx->fwdname);
dns_forwarders_detach(&forwarders);
return (better);
}
/*
@ -6627,15 +6626,15 @@ name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
* changed: play it safe and don't cache.
*/
return (true);
} else if ((result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) &&
forwarders->fwdpolicy == dns_fwdpolicy_only &&
!ISC_LIST_EMPTY(forwarders->fwdrs))
{
} else if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
/*
* If 'name' is covered by a 'forward only' clause then we
* can't cache this response.
*/
return (true);
bool nocache = (forwarders->fwdpolicy == dns_fwdpolicy_only &&
!ISC_LIST_EMPTY(forwarders->fwdrs));
dns_forwarders_detach(&forwarders);
return (nocache);
}
return (false);

View file

@ -135,13 +135,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
dns_zt_create(mctx, view, &view->zonetable);
result = dns_fwdtable_create(mctx, &view->fwdtable);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR("dns_fwdtable_create() failed: %s",
isc_result_totext(result));
result = ISC_R_UNEXPECTED;
goto cleanup_zt;
}
dns_fwdtable_create(mctx, view, &view->fwdtable);
dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
@ -193,11 +187,7 @@ cleanup_new_zone_lock:
isc_refcount_decrementz(&view->references);
isc_refcount_destroy(&view->references);
if (view->fwdtable != NULL) {
dns_fwdtable_destroy(&view->fwdtable);
}
cleanup_zt:
dns_fwdtable_destroy(&view->fwdtable);
dns_zt_detach(&view->zonetable);
isc_rwlock_destroy(&view->sfd_lock);