mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-04 16:12:04 -04:00
Add a mechanism to record namespaces for synth-from-dnssec
When namespace is grafted on, the DNSSEC proofs for non existance need to come from that namespace and not a higher namespace. We add 3 function dns_view_sfd_add, dns_view_sfd_del and dns_view_sfd_find to add, remove and find the namespace that should be used when checking NSEC records. dns_view_sfd_add adds a name to a tree, creating the tree if needed. If the name already existed in the tree the reference count is increased otherwise it is initalised to 1. dns_view_sfd_del removes a reference to a name in the tree, if the count goes to 0 the node is removed. dns_view_sfd_find returns the namespace to be used to entered name. If there isn't an enclosing name in the tree, or the tree does not yet exist, the root name is returned. Access to the tree is controlled by a read/write lock.
This commit is contained in:
parent
788aa4b12f
commit
3619cad141
2 changed files with 120 additions and 0 deletions
|
|
@ -144,6 +144,8 @@ struct dns_view {
|
|||
dns_rbt_t *denyanswernames;
|
||||
dns_rbt_t *answernames_exclude;
|
||||
dns_rrl_t *rrl;
|
||||
dns_rbt_t *sfd;
|
||||
isc_rwlock_t sfd_lock;
|
||||
bool provideixfr;
|
||||
bool requestnsid;
|
||||
bool sendcookie;
|
||||
|
|
@ -1282,4 +1284,41 @@ dns_view_flushonshutdown(dns_view_t *view, bool flush);
|
|||
* Requires:
|
||||
*\li 'view' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_sfd_add(dns_view_t *view, const dns_name_t *name);
|
||||
/*%<
|
||||
* Add 'name' to the synth-from-dnssec namespace tree for the
|
||||
* view. If the tree does not already exist create it.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'view' to be valid.
|
||||
*\li 'name' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_sfd_del(dns_view_t *view, const dns_name_t *name);
|
||||
/*%<
|
||||
* Delete 'name' to the synth-from-dnssec namespace tree for
|
||||
* the view when the count of previous adds and deletes becomes
|
||||
* zero.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'view' to be valid.
|
||||
*\li 'name' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_sfd_find(dns_view_t *view, const dns_name_t *name,
|
||||
dns_name_t *foundname);
|
||||
/*%<
|
||||
* Find the enclosing name to the synth-from-dnssec namespace tree for 'name'
|
||||
* in the specified view.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'view' to be valid.
|
||||
*\li 'name' to be valid.
|
||||
*\li 'foundname' to be valid with a buffer sufficient to hold the name.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name,
|
|||
|
||||
isc_mutex_init(&view->lock);
|
||||
|
||||
isc_rwlock_init(&view->sfd_lock, 0, 0);
|
||||
|
||||
view->zonetable = NULL;
|
||||
result = dns_zt_create(mctx, rdclass, &view->zonetable);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -215,6 +217,7 @@ cleanup_zt:
|
|||
}
|
||||
|
||||
cleanup_mutex:
|
||||
isc_rwlock_destroy(&view->sfd_lock);
|
||||
isc_mutex_destroy(&view->lock);
|
||||
|
||||
if (view->nta_file != NULL) {
|
||||
|
|
@ -381,6 +384,9 @@ destroy(dns_view_t *view) {
|
|||
if (view->answernames_exclude != NULL) {
|
||||
dns_rbt_destroy(&view->answernames_exclude);
|
||||
}
|
||||
if (view->sfd != NULL) {
|
||||
dns_rbt_destroy(&view->sfd);
|
||||
}
|
||||
if (view->delonly != NULL) {
|
||||
dns_name_t *name;
|
||||
int i;
|
||||
|
|
@ -464,6 +470,7 @@ destroy(dns_view_t *view) {
|
|||
dns_badcache_destroy(&view->failcache);
|
||||
}
|
||||
isc_mutex_destroy(&view->new_zone_lock);
|
||||
isc_rwlock_destroy(&view->sfd_lock);
|
||||
isc_mutex_destroy(&view->lock);
|
||||
isc_refcount_destroy(&view->references);
|
||||
isc_refcount_destroy(&view->weakrefs);
|
||||
|
|
@ -2334,3 +2341,77 @@ dns_view_flushonshutdown(dns_view_t *view, bool flush) {
|
|||
|
||||
view->flush = flush;
|
||||
}
|
||||
|
||||
static void
|
||||
free_sfd(void *data, void *arg) {
|
||||
isc_mem_put(arg, data, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_sfd_add(dns_view_t *view, const dns_name_t *name) {
|
||||
isc_result_t result;
|
||||
dns_rbtnode_t *node = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
RWLOCK(&view->sfd_lock, isc_rwlocktype_write);
|
||||
if (view->sfd == NULL) {
|
||||
result = dns_rbt_create(view->mctx, free_sfd, view->mctx,
|
||||
&view->sfd);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
result = dns_rbt_addnode(view->sfd, name, &node);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS || result == ISC_R_EXISTS);
|
||||
if (node->data != NULL) {
|
||||
unsigned int *count = node->data;
|
||||
(*count)++;
|
||||
} else {
|
||||
unsigned int *count = isc_mem_get(view->mctx,
|
||||
sizeof(unsigned int));
|
||||
*count = 1;
|
||||
node->data = count;
|
||||
}
|
||||
RWUNLOCK(&view->sfd_lock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_sfd_del(dns_view_t *view, const dns_name_t *name) {
|
||||
isc_result_t result;
|
||||
void *data = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
RWLOCK(&view->sfd_lock, isc_rwlocktype_write);
|
||||
INSIST(view->sfd != NULL);
|
||||
result = dns_rbt_findname(view->sfd, name, 0, NULL, &data);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
unsigned int *count = data;
|
||||
INSIST(count != NULL);
|
||||
if (--(*count) == 0U) {
|
||||
result = dns_rbt_deletename(view->sfd, name, false);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
RWUNLOCK(&view->sfd_lock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_sfd_find(dns_view_t *view, const dns_name_t *name,
|
||||
dns_name_t *foundname) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
if (view->sfd != NULL) {
|
||||
isc_result_t result;
|
||||
void *data = NULL;
|
||||
|
||||
RWLOCK(&view->sfd_lock, isc_rwlocktype_read);
|
||||
result = dns_rbt_findname(view->sfd, name, 0, foundname, &data);
|
||||
RWUNLOCK(&view->sfd_lock, isc_rwlocktype_read);
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) {
|
||||
dns_name_copy(dns_rootname, foundname);
|
||||
}
|
||||
} else {
|
||||
dns_name_copy(dns_rootname, foundname);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue