use dns_nametree in place of RBTs

replace the use of RBTs for deny-answer-aliases, the exclude
lists for deny-answer-aliases and deny-answer-addresses, and
dnssec-must-be-secure, with name trees.
This commit is contained in:
Evan Hunt 2023-08-16 13:28:36 -07:00
parent 56114aaa0d
commit e83ac0ce65
4 changed files with 34 additions and 73 deletions

View file

@ -83,6 +83,7 @@
#include <dns/keyvalues.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/nametree.h>
#include <dns/nsec3.h>
#include <dns/nta.h>
#include <dns/order.h>
@ -602,20 +603,20 @@ configure_view_sortlist(const cfg_obj_t *vconfig, const cfg_obj_t *config,
static isc_result_t
configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
const char *confname, const char *conftuplename,
isc_mem_t *mctx, dns_rbt_t **rbtp) {
isc_result_t result;
isc_mem_t *mctx, dns_nametree_t **ntp) {
isc_result_t result = ISC_R_SUCCESS;
const cfg_obj_t *maps[3];
const cfg_obj_t *obj = NULL;
const cfg_listelt_t *element;
const cfg_listelt_t *element = NULL;
int i = 0;
dns_fixedname_t fixed;
dns_name_t *name;
dns_name_t *name = NULL;
isc_buffer_t b;
const char *str;
const cfg_obj_t *nameobj;
const char *str = NULL;
const cfg_obj_t *nameobj = NULL;
if (*rbtp != NULL) {
dns_rbt_destroy(rbtp);
if (*ntp != NULL) {
dns_nametree_detach(ntp);
}
if (vconfig != NULL) {
maps[i++] = cfg_tuple_get(vconfig, "options");
@ -632,7 +633,7 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
(void)named_config_get(maps, confname, &obj);
if (obj == NULL) {
/*
* No value available. *rbtp == NULL.
* No value available. *ntp == NULL.
*/
return (ISC_R_SUCCESS);
}
@ -644,10 +645,7 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
}
}
result = dns_rbt_create(mctx, NULL, NULL, rbtp);
if (result != ISC_R_SUCCESS) {
return (result);
}
dns_nametree_create(mctx, confname, ntp);
name = dns_fixedname_initname(&fixed);
for (element = cfg_list_first(obj); element != NULL;
@ -658,14 +656,7 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
/*
* We don't need the node data, but need to set dummy data to
* avoid a partial match with an empty node. For example, if
* we have foo.example.com and bar.example.com, we'd get a match
* for baz.example.com, which is not the expected result.
* We simply use (void *)1 as the dummy data.
*/
result = dns_rbt_addname(*rbtp, name, (void *)1);
result = dns_nametree_add(*ntp, name, true);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(nameobj, named_g_lctx, ISC_LOG_ERROR,
"failed to add %s for %s: %s", str,
@ -674,10 +665,10 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
}
}
return (result);
return (ISC_R_SUCCESS);
cleanup:
dns_rbt_destroy(rbtp);
dns_nametree_detach(ntp);
return (result);
}

View file

@ -140,9 +140,9 @@ struct dns_view {
dns_acl_t *denyansweracl;
dns_acl_t *nocasecompress;
bool msgcompression;
dns_rbt_t *answeracl_exclude;
dns_rbt_t *denyanswernames;
dns_rbt_t *answernames_exclude;
dns_nametree_t *answeracl_exclude;
dns_nametree_t *denyanswernames;
dns_nametree_t *answernames_exclude;
dns_rrl_t *rrl;
dns_rbt_t *sfd;
isc_rwlock_t sfd_lock;

View file

@ -52,6 +52,7 @@
#include <dns/log.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/nametree.h>
#include <dns/ncache.h>
#include <dns/nsec.h>
#include <dns/nsec3.h>
@ -563,7 +564,7 @@ struct dns_resolver {
ISC_LIST(alternate_t) alternates;
dns_rbt_t *algorithms;
dns_rbt_t *digests;
dns_rbt_t *mustbesecure;
dns_nametree_t *mustbesecure;
unsigned int spillatmax;
unsigned int spillatmin;
isc_timer_t *spillattimer;
@ -6751,15 +6752,8 @@ is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
* If the owner name matches one in the exclusion list, either
* exactly or partially, allow it.
*/
if (view->answeracl_exclude != NULL) {
dns_rbtnode_t *node = NULL;
result = dns_rbt_findnode(view->answeracl_exclude, name, NULL,
&node, NULL, 0, NULL, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
return (true);
}
if (dns_nametree_covered(view->answeracl_exclude, name)) {
return (true);
}
/*
@ -6806,7 +6800,6 @@ static bool
is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
dns_rdataset_t *rdataset, bool *chainingp) {
isc_result_t result;
dns_rbtnode_t *node = NULL;
dns_name_t *tname = NULL;
dns_rdata_cname_t cname;
dns_rdata_dname_t dname;
@ -6872,12 +6865,8 @@ is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
* If the owner name matches one in the exclusion list, either
* exactly or partially, allow it.
*/
if (view->answernames_exclude != NULL) {
result = dns_rbt_findnode(view->answernames_exclude, qname,
NULL, &node, NULL, 0, NULL, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
return (true);
}
if (dns_nametree_covered(view->answernames_exclude, qname)) {
return (true);
}
/*
@ -6896,9 +6885,7 @@ is_answertarget_allowed(fetchctx_t *fctx, dns_name_t *qname, dns_name_t *rname,
/*
* Otherwise, apply filters.
*/
result = dns_rbt_findnode(view->denyanswernames, tname, NULL, &node,
NULL, 0, NULL, NULL);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
if (dns_nametree_covered(view->denyanswernames, tname)) {
char qnamebuf[DNS_NAME_FORMATSIZE];
char tnamebuf[DNS_NAME_FORMATSIZE];
char classbuf[64];
@ -10957,12 +10944,10 @@ dns_resolver_resetmustbesecure(dns_resolver_t *resolver) {
REQUIRE(VALID_RESOLVER(resolver));
if (resolver->mustbesecure != NULL) {
dns_rbt_destroy(&resolver->mustbesecure);
dns_nametree_detach(&resolver->mustbesecure);
}
}
static bool yes = true, no = false;
isc_result_t
dns_resolver_setmustbesecure(dns_resolver_t *resolver, const dns_name_t *name,
bool value) {
@ -10971,35 +10956,19 @@ dns_resolver_setmustbesecure(dns_resolver_t *resolver, const dns_name_t *name,
REQUIRE(VALID_RESOLVER(resolver));
if (resolver->mustbesecure == NULL) {
result = dns_rbt_create(resolver->mctx, NULL, NULL,
&resolver->mustbesecure);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
dns_nametree_create(resolver->mctx, "dnssec-must-be-secure",
&resolver->mustbesecure);
}
result = dns_rbt_addname(resolver->mustbesecure, name,
value ? &yes : &no);
cleanup:
result = dns_nametree_add(resolver->mustbesecure, name, value);
return (result);
}
bool
dns_resolver_getmustbesecure(dns_resolver_t *resolver, const dns_name_t *name) {
void *data = NULL;
bool value = false;
isc_result_t result;
REQUIRE(VALID_RESOLVER(resolver));
if (resolver->mustbesecure == NULL) {
goto unlock;
}
result = dns_rbt_findname(resolver->mustbesecure, name, 0, NULL, &data);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
value = *(bool *)data;
}
unlock:
return (value);
return (dns_nametree_covered(resolver->mustbesecure, name));
}
void

View file

@ -47,6 +47,7 @@
#include <dns/keyvalues.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/nametree.h>
#include <dns/nta.h>
#include <dns/order.h>
#include <dns/peer.h>
@ -348,13 +349,13 @@ destroy(dns_view_t *view) {
dns_acl_detach(&view->pad_acl);
}
if (view->answeracl_exclude != NULL) {
dns_rbt_destroy(&view->answeracl_exclude);
dns_nametree_detach(&view->answeracl_exclude);
}
if (view->denyanswernames != NULL) {
dns_rbt_destroy(&view->denyanswernames);
dns_nametree_detach(&view->denyanswernames);
}
if (view->answernames_exclude != NULL) {
dns_rbt_destroy(&view->answernames_exclude);
dns_nametree_detach(&view->answernames_exclude);
}
if (view->sfd != NULL) {
dns_rbt_destroy(&view->sfd);