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