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