1 1.1 christos /* 2 1.1 christos * util/storage/dnstree.h - support for rbtree types suitable for DNS code. 3 1.1 christos * 4 1.1 christos * Copyright (c) 2008, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * This software is open source. 7 1.1 christos * 8 1.1 christos * Redistribution and use in source and binary forms, with or without 9 1.1 christos * modification, are permitted provided that the following conditions 10 1.1 christos * are met: 11 1.1 christos * 12 1.1 christos * Redistributions of source code must retain the above copyright notice, 13 1.1 christos * this list of conditions and the following disclaimer. 14 1.1 christos * 15 1.1 christos * Redistributions in binary form must reproduce the above copyright notice, 16 1.1 christos * this list of conditions and the following disclaimer in the documentation 17 1.1 christos * and/or other materials provided with the distribution. 18 1.1 christos * 19 1.1 christos * Neither the name of the NLNET LABS nor the names of its contributors may 20 1.1 christos * be used to endorse or promote products derived from this software without 21 1.1 christos * specific prior written permission. 22 1.1 christos * 23 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 1.1 christos * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 1.1 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 1.1 christos * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 1.1 christos * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 1.1 christos * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 1.1 christos * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 1.1 christos * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 1.1 christos */ 35 1.1 christos 36 1.1 christos /** 37 1.1 christos * \file 38 1.1 christos * 39 1.1 christos * This file contains structures combining types and functions to 40 1.1 christos * manipulate those structures that help building DNS lookup trees. 41 1.1 christos */ 42 1.1 christos 43 1.1 christos #ifndef UTIL_STORAGE_DNSTREE_H 44 1.1 christos #define UTIL_STORAGE_DNSTREE_H 45 1.1 christos #include "util/rbtree.h" 46 1.1 christos 47 1.1 christos /** 48 1.1 christos * Tree of domain names. Sorted first by class then by name. 49 1.1 christos * This is not sorted canonically, but fast. 50 1.1 christos * This can be looked up to obtain a closest encloser parent name. 51 1.1 christos * 52 1.1.1.2 christos * The tree itself is a rbtree_type. 53 1.1 christos * This is the element node put as first entry in the client structure. 54 1.1 christos */ 55 1.1 christos struct name_tree_node { 56 1.1 christos /** rbtree node, key is this struct : dclass and name */ 57 1.1.1.2 christos rbnode_type node; 58 1.1 christos /** parent in tree */ 59 1.1 christos struct name_tree_node* parent; 60 1.1 christos /** name in uncompressed wireformat */ 61 1.1 christos uint8_t* name; 62 1.1 christos /** length of name */ 63 1.1 christos size_t len; 64 1.1 christos /** labels in name */ 65 1.1 christos int labs; 66 1.1 christos /** the class of the name (host order) */ 67 1.1 christos uint16_t dclass; 68 1.1 christos }; 69 1.1 christos 70 1.1 christos /** 71 1.1 christos * Tree of IP addresses. Sorted first by protocol, then by bits. 72 1.1 christos * This can be looked up to obtain the enclosing subnet. 73 1.1 christos * 74 1.1.1.2 christos * The tree itself is a rbtree_type. 75 1.1 christos * This is the element node put as first entry in the client structure. 76 1.1 christos */ 77 1.1 christos struct addr_tree_node { 78 1.1 christos /** rbtree node, key is this struct : proto and subnet */ 79 1.1.1.2 christos rbnode_type node; 80 1.1 christos /** parent in tree */ 81 1.1 christos struct addr_tree_node* parent; 82 1.1 christos /** address */ 83 1.1 christos struct sockaddr_storage addr; 84 1.1 christos /** length of addr */ 85 1.1 christos socklen_t addrlen; 86 1.1 christos /** netblock size */ 87 1.1 christos int net; 88 1.1 christos }; 89 1.1 christos 90 1.1 christos /** 91 1.1 christos * Init a name tree to be empty 92 1.1 christos * @param tree: to init. 93 1.1 christos */ 94 1.1.1.2 christos void name_tree_init(rbtree_type* tree); 95 1.1 christos 96 1.1 christos /** 97 1.1 christos * insert element into name tree. 98 1.1 christos * @param tree: name tree 99 1.1 christos * @param node: node element (at start of a structure that caller 100 1.1 christos * has allocated). 101 1.1 christos * @param name: name to insert (wireformat) 102 1.1 christos * this node has been allocated by the caller and it itself inserted. 103 1.1 christos * @param len: length of name 104 1.1 christos * @param labs: labels in name 105 1.1 christos * @param dclass: class of name 106 1.1 christos * @return false on error (duplicate element). 107 1.1 christos */ 108 1.1.1.2 christos int name_tree_insert(rbtree_type* tree, struct name_tree_node* node, 109 1.1 christos uint8_t* name, size_t len, int labs, uint16_t dclass); 110 1.1 christos 111 1.1 christos /** 112 1.1 christos * Initialize parent pointers in name tree. 113 1.1 christos * Should be performed after insertions are done, before lookups 114 1.1 christos * @param tree: name tree 115 1.1 christos */ 116 1.1.1.2 christos void name_tree_init_parents(rbtree_type* tree); 117 1.1 christos 118 1.1 christos /** 119 1.1 christos * Lookup exact match in name tree 120 1.1 christos * @param tree: name tree 121 1.1 christos * @param name: wireformat name 122 1.1 christos * @param len: length of name 123 1.1 christos * @param labs: labels in name 124 1.1 christos * @param dclass: class of name 125 1.1 christos * @return node or NULL if not found. 126 1.1 christos */ 127 1.1.1.2 christos struct name_tree_node* name_tree_find(rbtree_type* tree, uint8_t* name, 128 1.1 christos size_t len, int labs, uint16_t dclass); 129 1.1 christos 130 1.1 christos /** 131 1.1 christos * Lookup closest encloser in name tree. 132 1.1 christos * @param tree: name tree 133 1.1 christos * @param name: wireformat name 134 1.1 christos * @param len: length of name 135 1.1 christos * @param labs: labels in name 136 1.1 christos * @param dclass: class of name 137 1.1 christos * @return closest enclosing node (could be equal) or NULL if not found. 138 1.1 christos */ 139 1.1.1.2 christos struct name_tree_node* name_tree_lookup(rbtree_type* tree, uint8_t* name, 140 1.1 christos size_t len, int labs, uint16_t dclass); 141 1.1 christos 142 1.1 christos /** 143 1.1 christos * Find next root item in name tree. 144 1.1 christos * @param tree: the nametree. 145 1.1 christos * @param dclass: the class to look for next (or higher). 146 1.1 christos * @return false if no classes found, true means class put into c. 147 1.1 christos */ 148 1.1.1.2 christos int name_tree_next_root(rbtree_type* tree, uint16_t* dclass); 149 1.1 christos 150 1.1 christos /** 151 1.1 christos * Init addr tree to be empty. 152 1.1 christos * @param tree: to init. 153 1.1 christos */ 154 1.1.1.2 christos void addr_tree_init(rbtree_type* tree); 155 1.1 christos 156 1.1 christos /** 157 1.1.1.4 christos * Init addr tree to be empty. 158 1.1.1.4 christos * The comparison function to be used is addr_tree_addrport_compare. 159 1.1.1.4 christos * @param tree: to init. 160 1.1.1.4 christos */ 161 1.1.1.4 christos void addr_tree_addrport_init(rbtree_type* tree); 162 1.1.1.4 christos 163 1.1.1.4 christos /** 164 1.1 christos * insert element into addr tree. 165 1.1 christos * @param tree: addr tree 166 1.1 christos * @param node: node element (at start of a structure that caller 167 1.1 christos * has allocated). 168 1.1 christos * @param addr: to insert (copied). 169 1.1 christos * @param addrlen: length of addr 170 1.1 christos * @param net: size of subnet. 171 1.1 christos * @return false on error (duplicate element). 172 1.1 christos */ 173 1.1.1.2 christos int addr_tree_insert(rbtree_type* tree, struct addr_tree_node* node, 174 1.1 christos struct sockaddr_storage* addr, socklen_t addrlen, int net); 175 1.1 christos 176 1.1 christos /** 177 1.1 christos * Initialize parent pointers in addr tree. 178 1.1 christos * Should be performed after insertions are done, before lookups 179 1.1 christos * @param tree: addr tree 180 1.1 christos */ 181 1.1.1.2 christos void addr_tree_init_parents(rbtree_type* tree); 182 1.1 christos 183 1.1 christos /** 184 1.1.1.3 christos * Initialize parent pointers in partial addr tree. 185 1.1.1.3 christos * Reinitialize pointer for part of tree, used after node deletion 186 1.1.1.3 christos * @param node: node to start parent pointer initialization for. 187 1.1.1.3 christos */ 188 1.1.1.3 christos void addr_tree_init_parents_node(struct addr_tree_node* node); 189 1.1.1.3 christos 190 1.1.1.3 christos /** 191 1.1 christos * Lookup closest encloser in addr tree. 192 1.1 christos * @param tree: addr tree 193 1.1 christos * @param addr: to lookup. 194 1.1 christos * @param addrlen: length of addr 195 1.1 christos * @return closest enclosing node (could be equal) or NULL if not found. 196 1.1 christos */ 197 1.1.1.2 christos struct addr_tree_node* addr_tree_lookup(rbtree_type* tree, 198 1.1 christos struct sockaddr_storage* addr, socklen_t addrlen); 199 1.1 christos 200 1.1.1.2 christos /** 201 1.1.1.2 christos * Find element in addr tree. (search a netblock, not a match for an address) 202 1.1.1.2 christos * @param tree: addr tree 203 1.1.1.2 christos * @param addr: netblock to lookup. 204 1.1.1.2 christos * @param addrlen: length of addr 205 1.1.1.2 christos * @param net: size of subnet 206 1.1.1.2 christos * @return addr tree element, or NULL if not found. 207 1.1.1.2 christos */ 208 1.1.1.2 christos struct addr_tree_node* addr_tree_find(rbtree_type* tree, 209 1.1.1.2 christos struct sockaddr_storage* addr, socklen_t addrlen, int net); 210 1.1.1.2 christos 211 1.1 christos /** compare name tree nodes */ 212 1.1 christos int name_tree_compare(const void* k1, const void* k2); 213 1.1 christos 214 1.1 christos /** compare addr tree nodes */ 215 1.1 christos int addr_tree_compare(const void* k1, const void* k2); 216 1.1 christos 217 1.1.1.4 christos /** compare addr tree nodes (address and port only) */ 218 1.1.1.4 christos int addr_tree_addrport_compare(const void* k1, const void* k2); 219 1.1.1.4 christos 220 1.1 christos #endif /* UTIL_STORAGE_DNSTREE_H */ 221