Home | History | Annotate | Line # | Download | only in dns
      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