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;
* 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
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) {
}
cleanup_mutex:
+ isc_rwlock_destroy(&view->sfd_lock);
isc_mutex_destroy(&view->lock);
if (view->nta_file != NULL) {
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;
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);
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);
+ }
+}