mirror of
https://github.com/isc-projects/bind9.git
synced 2026-02-23 01:40:23 -05:00
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:
parent
5768dd96ea
commit
dea79e7053
5 changed files with 202 additions and 127 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue