1933707f3Ssthen /* 2933707f3Ssthen * util/storage/dnstree.h - support for rbtree types suitable for DNS code. 3933707f3Ssthen * 4933707f3Ssthen * Copyright (c) 2008, NLnet Labs. All rights reserved. 5933707f3Ssthen * 6933707f3Ssthen * This software is open source. 7933707f3Ssthen * 8933707f3Ssthen * Redistribution and use in source and binary forms, with or without 9933707f3Ssthen * modification, are permitted provided that the following conditions 10933707f3Ssthen * are met: 11933707f3Ssthen * 12933707f3Ssthen * Redistributions of source code must retain the above copyright notice, 13933707f3Ssthen * this list of conditions and the following disclaimer. 14933707f3Ssthen * 15933707f3Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16933707f3Ssthen * this list of conditions and the following disclaimer in the documentation 17933707f3Ssthen * and/or other materials provided with the distribution. 18933707f3Ssthen * 19933707f3Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20933707f3Ssthen * be used to endorse or promote products derived from this software without 21933707f3Ssthen * specific prior written permission. 22933707f3Ssthen * 23933707f3Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 245d76a658Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255d76a658Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 265d76a658Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 275d76a658Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 285d76a658Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 295d76a658Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 305d76a658Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 315d76a658Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 325d76a658Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 335d76a658Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34933707f3Ssthen */ 35933707f3Ssthen 36933707f3Ssthen /** 37933707f3Ssthen * \file 38933707f3Ssthen * 39933707f3Ssthen * This file contains structures combining types and functions to 40933707f3Ssthen * manipulate those structures that help building DNS lookup trees. 41933707f3Ssthen */ 42933707f3Ssthen 43933707f3Ssthen #ifndef UTIL_STORAGE_DNSTREE_H 44933707f3Ssthen #define UTIL_STORAGE_DNSTREE_H 45933707f3Ssthen #include "util/rbtree.h" 46933707f3Ssthen 47933707f3Ssthen /** 48933707f3Ssthen * Tree of domain names. Sorted first by class then by name. 49933707f3Ssthen * This is not sorted canonically, but fast. 50933707f3Ssthen * This can be looked up to obtain a closest encloser parent name. 51933707f3Ssthen * 5277079be7Ssthen * The tree itself is a rbtree_type. 53933707f3Ssthen * This is the element node put as first entry in the client structure. 54933707f3Ssthen */ 55933707f3Ssthen struct name_tree_node { 56933707f3Ssthen /** rbtree node, key is this struct : dclass and name */ 5777079be7Ssthen rbnode_type node; 58933707f3Ssthen /** parent in tree */ 59933707f3Ssthen struct name_tree_node* parent; 60933707f3Ssthen /** name in uncompressed wireformat */ 61933707f3Ssthen uint8_t* name; 62933707f3Ssthen /** length of name */ 63933707f3Ssthen size_t len; 64933707f3Ssthen /** labels in name */ 65933707f3Ssthen int labs; 66933707f3Ssthen /** the class of the name (host order) */ 67933707f3Ssthen uint16_t dclass; 68933707f3Ssthen }; 69933707f3Ssthen 70933707f3Ssthen /** 71933707f3Ssthen * Tree of IP addresses. Sorted first by protocol, then by bits. 72933707f3Ssthen * This can be looked up to obtain the enclosing subnet. 73933707f3Ssthen * 7477079be7Ssthen * The tree itself is a rbtree_type. 75933707f3Ssthen * This is the element node put as first entry in the client structure. 76933707f3Ssthen */ 77933707f3Ssthen struct addr_tree_node { 78933707f3Ssthen /** rbtree node, key is this struct : proto and subnet */ 7977079be7Ssthen rbnode_type node; 80933707f3Ssthen /** parent in tree */ 81933707f3Ssthen struct addr_tree_node* parent; 82933707f3Ssthen /** address */ 83933707f3Ssthen struct sockaddr_storage addr; 84933707f3Ssthen /** length of addr */ 85933707f3Ssthen socklen_t addrlen; 86933707f3Ssthen /** netblock size */ 87933707f3Ssthen int net; 88933707f3Ssthen }; 89933707f3Ssthen 90933707f3Ssthen /** 91933707f3Ssthen * Init a name tree to be empty 92933707f3Ssthen * @param tree: to init. 93933707f3Ssthen */ 9477079be7Ssthen void name_tree_init(rbtree_type* tree); 95933707f3Ssthen 96933707f3Ssthen /** 97933707f3Ssthen * insert element into name tree. 98933707f3Ssthen * @param tree: name tree 99933707f3Ssthen * @param node: node element (at start of a structure that caller 100933707f3Ssthen * has allocated). 101933707f3Ssthen * @param name: name to insert (wireformat) 102933707f3Ssthen * this node has been allocated by the caller and it itself inserted. 103933707f3Ssthen * @param len: length of name 104933707f3Ssthen * @param labs: labels in name 105933707f3Ssthen * @param dclass: class of name 106933707f3Ssthen * @return false on error (duplicate element). 107933707f3Ssthen */ 10877079be7Ssthen int name_tree_insert(rbtree_type* tree, struct name_tree_node* node, 109933707f3Ssthen uint8_t* name, size_t len, int labs, uint16_t dclass); 110933707f3Ssthen 111933707f3Ssthen /** 112933707f3Ssthen * Initialize parent pointers in name tree. 113933707f3Ssthen * Should be performed after insertions are done, before lookups 114933707f3Ssthen * @param tree: name tree 115933707f3Ssthen */ 11677079be7Ssthen void name_tree_init_parents(rbtree_type* tree); 117933707f3Ssthen 118933707f3Ssthen /** 119933707f3Ssthen * Lookup exact match in name tree 120933707f3Ssthen * @param tree: name tree 121933707f3Ssthen * @param name: wireformat name 122933707f3Ssthen * @param len: length of name 123933707f3Ssthen * @param labs: labels in name 124933707f3Ssthen * @param dclass: class of name 125933707f3Ssthen * @return node or NULL if not found. 126933707f3Ssthen */ 12777079be7Ssthen struct name_tree_node* name_tree_find(rbtree_type* tree, uint8_t* name, 128933707f3Ssthen size_t len, int labs, uint16_t dclass); 129933707f3Ssthen 130933707f3Ssthen /** 131933707f3Ssthen * Lookup closest encloser in name tree. 132933707f3Ssthen * @param tree: name tree 133933707f3Ssthen * @param name: wireformat name 134933707f3Ssthen * @param len: length of name 135933707f3Ssthen * @param labs: labels in name 136933707f3Ssthen * @param dclass: class of name 137933707f3Ssthen * @return closest enclosing node (could be equal) or NULL if not found. 138933707f3Ssthen */ 13977079be7Ssthen struct name_tree_node* name_tree_lookup(rbtree_type* tree, uint8_t* name, 140933707f3Ssthen size_t len, int labs, uint16_t dclass); 141933707f3Ssthen 142933707f3Ssthen /** 143933707f3Ssthen * Find next root item in name tree. 144933707f3Ssthen * @param tree: the nametree. 145933707f3Ssthen * @param dclass: the class to look for next (or higher). 146933707f3Ssthen * @return false if no classes found, true means class put into c. 147933707f3Ssthen */ 14877079be7Ssthen int name_tree_next_root(rbtree_type* tree, uint16_t* dclass); 149933707f3Ssthen 150933707f3Ssthen /** 151933707f3Ssthen * Init addr tree to be empty. 152933707f3Ssthen * @param tree: to init. 153933707f3Ssthen */ 15477079be7Ssthen void addr_tree_init(rbtree_type* tree); 155933707f3Ssthen 156933707f3Ssthen /** 157*45872187Ssthen * Init addr tree to be empty. 158*45872187Ssthen * The comparison function to be used is addr_tree_addrport_compare. 159*45872187Ssthen * @param tree: to init. 160*45872187Ssthen */ 161*45872187Ssthen void addr_tree_addrport_init(rbtree_type* tree); 162*45872187Ssthen 163*45872187Ssthen /** 164933707f3Ssthen * insert element into addr tree. 165933707f3Ssthen * @param tree: addr tree 166933707f3Ssthen * @param node: node element (at start of a structure that caller 167933707f3Ssthen * has allocated). 168933707f3Ssthen * @param addr: to insert (copied). 169933707f3Ssthen * @param addrlen: length of addr 170933707f3Ssthen * @param net: size of subnet. 171933707f3Ssthen * @return false on error (duplicate element). 172933707f3Ssthen */ 17377079be7Ssthen int addr_tree_insert(rbtree_type* tree, struct addr_tree_node* node, 174933707f3Ssthen struct sockaddr_storage* addr, socklen_t addrlen, int net); 175933707f3Ssthen 176933707f3Ssthen /** 177933707f3Ssthen * Initialize parent pointers in addr tree. 178933707f3Ssthen * Should be performed after insertions are done, before lookups 179933707f3Ssthen * @param tree: addr tree 180933707f3Ssthen */ 18177079be7Ssthen void addr_tree_init_parents(rbtree_type* tree); 182933707f3Ssthen 183933707f3Ssthen /** 184eaf2578eSsthen * Initialize parent pointers in partial addr tree. 185eaf2578eSsthen * Reinitialize pointer for part of tree, used after node deletion 186eaf2578eSsthen * @param node: node to start parent pointer initialization for. 187eaf2578eSsthen */ 188eaf2578eSsthen void addr_tree_init_parents_node(struct addr_tree_node* node); 189eaf2578eSsthen 190eaf2578eSsthen /** 191933707f3Ssthen * Lookup closest encloser in addr tree. 192933707f3Ssthen * @param tree: addr tree 193933707f3Ssthen * @param addr: to lookup. 194933707f3Ssthen * @param addrlen: length of addr 195933707f3Ssthen * @return closest enclosing node (could be equal) or NULL if not found. 196933707f3Ssthen */ 19777079be7Ssthen struct addr_tree_node* addr_tree_lookup(rbtree_type* tree, 198933707f3Ssthen struct sockaddr_storage* addr, socklen_t addrlen); 199933707f3Ssthen 20077079be7Ssthen /** 20177079be7Ssthen * Find element in addr tree. (search a netblock, not a match for an address) 20277079be7Ssthen * @param tree: addr tree 20377079be7Ssthen * @param addr: netblock to lookup. 20477079be7Ssthen * @param addrlen: length of addr 20577079be7Ssthen * @param net: size of subnet 20677079be7Ssthen * @return addr tree element, or NULL if not found. 20777079be7Ssthen */ 20877079be7Ssthen struct addr_tree_node* addr_tree_find(rbtree_type* tree, 20977079be7Ssthen struct sockaddr_storage* addr, socklen_t addrlen, int net); 21077079be7Ssthen 211933707f3Ssthen /** compare name tree nodes */ 212933707f3Ssthen int name_tree_compare(const void* k1, const void* k2); 213933707f3Ssthen 214933707f3Ssthen /** compare addr tree nodes */ 215933707f3Ssthen int addr_tree_compare(const void* k1, const void* k2); 216933707f3Ssthen 217*45872187Ssthen /** compare addr tree nodes (address and port only) */ 218*45872187Ssthen int addr_tree_addrport_compare(const void* k1, const void* k2); 219*45872187Ssthen 220933707f3Ssthen #endif /* UTIL_STORAGE_DNSTREE_H */ 221