1 /* $NetBSD: nametree.h,v 1.3 2026/06/19 20:10:01 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #pragma once 17 18 /***** 19 ***** Module Info 20 *****/ 21 22 /*! \file 23 * \brief 24 * A nametree module is a tree of DNS names containing boolean values 25 * or bitfields, allowing a quick lookup to see whether a name is included 26 * in or excluded from some policy. 27 */ 28 29 #include <stdbool.h> 30 31 #include <isc/lang.h> 32 #include <isc/magic.h> 33 #include <isc/refcount.h> 34 #include <isc/rwlock.h> 35 #include <isc/stdtime.h> 36 37 #include <dns/rdatastruct.h> 38 #include <dns/types.h> 39 40 #include <dst/dst.h> 41 42 /* Add -DDNS_NAMETREE_TRACE=1 to CFLAGS for detailed reference tracing */ 43 44 typedef enum { 45 DNS_NAMETREE_BOOL, 46 DNS_NAMETREE_BITS, 47 DNS_NAMETREE_COUNT 48 } dns_nametree_type_t; 49 50 ISC_LANG_BEGINDECLS 51 52 void 53 dns_nametree_create(isc_mem_t *mctx, dns_nametree_type_t type, const char *name, 54 dns_nametree_t **ntp); 55 /*%< 56 * Create a nametree. 57 * 58 * If 'name' is not NULL, it will be saved as the name of the QP trie 59 * for debugging purposes. 60 * 61 * 'type' indicates whether the tree will be used for storing boolean 62 * values (DNS_NAMETREE_BOOL), bitfields (DNS_NAMETREE_BITS), or counters 63 * (DNS_NAMETREE_COUNT). 64 * 65 * Requires: 66 * 67 *\li 'mctx' is a valid memory context. 68 *\li ntp != NULL && *ntp == NULL 69 */ 70 71 isc_result_t 72 dns_nametree_add(dns_nametree_t *nametree, const dns_name_t *name, 73 uint32_t value); 74 /*%< 75 * Add a node to 'nametree'. 76 * 77 * If the nametree type was set to DNS_NAMETREE_BOOL, then 'value' 78 * represents a single boolean value, true or false. If the name already 79 * exists within the tree, then return ISC_R_EXISTS. 80 * 81 * If the nametree type was set to DNS_NAMETREE_COUNT, then 'value' 82 * can only be true. Each time the same name is added to the tree, 83 * ISC_R_SUCCESS is returned and a counter is incremented. 84 * dns_nametree_delete() must be deleted the same number of times 85 * as dns_nametree_add() before the name is removed from the tree. 86 * 87 * If the nametree type was set to DNS_NAMETREE_BITS, then 'value' is 88 * a bit number within a bit field, which is sized to accommodate at least 89 * 'value' bits. If the name already exists, then that bit will be set 90 * in the bitfield, other bits will be retained, and ISC_R_SUCCESS will be 91 * returned. If 'value' exceeds the number of bits in the existing bit 92 * field, the field will be expanded. 93 * 94 * Requires: 95 * 96 *\li 'nametree' points to a valid nametree. 97 * 98 * Returns: 99 * 100 *\li ISC_R_SUCCESS 101 *\li ISC_R_EXISTS 102 * 103 *\li Any other result indicates failure. 104 */ 105 106 isc_result_t 107 dns_nametree_delete(dns_nametree_t *nametree, const dns_name_t *name); 108 /*%< 109 * Delete 'name' from 'nametree'. 110 * 111 * If the nametree type was set to DNS_NAMETREE_COUNT, then this must 112 * be called for each name the same number of times as dns_nametree_add() 113 * was called before the name is removed. 114 * 115 * Requires: 116 * 117 *\li 'nametree' points to a valid nametree. 118 *\li 'name' is not NULL 119 * 120 * Returns: 121 * 122 *\li ISC_R_SUCCESS 123 * 124 *\li Any other result indicates failure. 125 */ 126 127 isc_result_t 128 dns_nametree_find(dns_nametree_t *nametree, const dns_name_t *name, 129 dns_ntnode_t **ntp); 130 /*%< 131 * Retrieve the node that exactly matches 'name' from 'nametree'. 132 * 133 * Requires: 134 * 135 *\li 'nametree' is a valid nametree. 136 * 137 *\li 'name' is a valid name. 138 * 139 *\li ntp != NULL && *ntp == NULL 140 * 141 * Returns: 142 * 143 *\li ISC_R_SUCCESS 144 *\li ISC_R_NOTFOUND 145 * 146 *\li Any other result indicates an error. 147 */ 148 149 bool 150 dns_nametree_covered(dns_nametree_t *nametree, const dns_name_t *name, 151 dns_name_t *found, uint32_t bit); 152 /*%< 153 * Indicates whether a 'name' (with optional 'bit' value) is covered by 154 * 'nametree'. 155 * 156 * In DNS_NAMETREE_BOOL nametrees, this returns true if 'name' has a match 157 * or a closest ancestor in 'nametree' with its value set to 'true'. 158 * 'bit' is ignored. 159 * 160 * In DNS_NAMETREE_BITS trees, this returns true if 'name' has a match or 161 * a closest ancestor in 'nametree' with the 'bit' set in its bitfield. 162 * 163 * If a name is not found, the default return value is false. 164 * 165 * If 'found' is not NULL, the name or ancestor name that was found in 166 * the tree is copied into it. 167 * 168 * Requires: 169 * 170 *\li 'nametree' is a valid nametree, or is NULL. 171 */ 172 173 #if DNS_NAMETREE_TRACE 174 #define dns_nametree_ref(ptr) \ 175 dns_nametree__ref(ptr, __func__, __FILE__, __LINE__) 176 #define dns_nametree_unref(ptr) \ 177 dns_nametree__unref(ptr, __func__, __FILE__, __LINE__) 178 #define dns_nametree_attach(ptr, ptrp) \ 179 dns_nametree__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 180 #define dns_nametree_detach(ptrp) \ 181 dns_nametree__detach(ptrp, __func__, __FILE__, __LINE__) 182 #define dns_ntnode_ref(ptr) dns_ntnode__ref(ptr, __func__, __FILE__, __LINE__) 183 #define dns_ntnode_unref(ptr) \ 184 dns_ntnode__unref(ptr, __func__, __FILE__, __LINE__) 185 #define dns_ntnode_attach(ptr, ptrp) \ 186 dns_ntnode__attach(ptr, ptrp, __func__, __FILE__, __LINE__) 187 #define dns_ntnode_detach(ptrp) \ 188 dns_ntnode__detach(ptrp, __func__, __FILE__, __LINE__) 189 ISC_REFCOUNT_TRACE_DECL(dns_nametree); 190 ISC_REFCOUNT_TRACE_DECL(dns_ntnode); 191 #else 192 ISC_REFCOUNT_DECL(dns_nametree); 193 ISC_REFCOUNT_DECL(dns_ntnode); 194 #endif 195 ISC_LANG_ENDDECLS 196