12be9e038Ssthen /* 22be9e038Ssthen * edns-subnet/addrtree.h -- radix tree for edns subnet cache. 32be9e038Ssthen * 42be9e038Ssthen * Copyright (c) 2013, NLnet Labs. All rights reserved. 52be9e038Ssthen * 62be9e038Ssthen * This software is open source. 72be9e038Ssthen * 82be9e038Ssthen * Redistribution and use in source and binary forms, with or without 92be9e038Ssthen * modification, are permitted provided that the following conditions 102be9e038Ssthen * are met: 112be9e038Ssthen * 122be9e038Ssthen * Redistributions of source code must retain the above copyright notice, 132be9e038Ssthen * this list of conditions and the following disclaimer. 142be9e038Ssthen * 152be9e038Ssthen * Redistributions in binary form must reproduce the above copyright notice, 162be9e038Ssthen * this list of conditions and the following disclaimer in the documentation 172be9e038Ssthen * and/or other materials provided with the distribution. 182be9e038Ssthen * 192be9e038Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 202be9e038Ssthen * be used to endorse or promote products derived from this software without 212be9e038Ssthen * specific prior written permission. 222be9e038Ssthen * 232be9e038Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 242be9e038Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 252be9e038Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 262be9e038Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 272be9e038Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 282be9e038Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 292be9e038Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 302be9e038Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 312be9e038Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 322be9e038Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 332be9e038Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 342be9e038Ssthen */ 352be9e038Ssthen 362be9e038Ssthen /** 372be9e038Ssthen * \file 382be9e038Ssthen * The addrtree is a radix tree designed for edns subnet. Most notable 392be9e038Ssthen * is the addition of 'scope' to a node. Scope is only relevant for 402be9e038Ssthen * nodes with elem set, it indicates the number of bits the authority 412be9e038Ssthen * desires. 422be9e038Ssthen * 432be9e038Ssthen * For retrieving data one needs an address and address length 442be9e038Ssthen * (sourcemask). While traversing the tree the first matching node is 452be9e038Ssthen * returned. A node matches when 462be9e038Ssthen * node.scope<=sourcemask && node.elem!=NULL 472be9e038Ssthen * (This is the most specific answer the authority has.) 482be9e038Ssthen * or 492be9e038Ssthen * node.sourcemask==sourcemask && node.elem!=NULL 502be9e038Ssthen * (This is the most specific question the client can ask.) 512be9e038Ssthen * 522be9e038Ssthen * Insertion needs an address, sourcemask and scope. The length of the 532be9e038Ssthen * address is capped by min(sourcemask, scope). While traversing the 542be9e038Ssthen * tree the scope of all visited nodes is updated. This ensures we are 552be9e038Ssthen * always able to find the most specific answer available. 562be9e038Ssthen */ 572be9e038Ssthen 582be9e038Ssthen #ifndef ADDRTREE_H 592be9e038Ssthen #define ADDRTREE_H 602be9e038Ssthen 612be9e038Ssthen typedef uint8_t addrlen_t; 622be9e038Ssthen typedef uint8_t addrkey_t; 632be9e038Ssthen #define KEYWIDTH 8 642be9e038Ssthen 652be9e038Ssthen struct addrtree { 662be9e038Ssthen struct addrnode *root; 672be9e038Ssthen /** Number of elements in the tree (not always equal to number of 682be9e038Ssthen * nodes) */ 693150e5f6Ssthen uint32_t node_count; 702be9e038Ssthen /** Maximum number of allowed nodes, will be enforced by LRU list. 712be9e038Ssthen * Excluding the root node, 0 for unlimited */ 723150e5f6Ssthen uint32_t max_node_count; 732be9e038Ssthen /** Size of tree in bytes */ 742be9e038Ssthen size_t size_bytes; 752be9e038Ssthen /** Maximum prefix length we are willing to cache. */ 762be9e038Ssthen addrlen_t max_depth; 772be9e038Ssthen /** External function to delete elem. Called as 782be9e038Ssthen * delfunc(addrnode->elem, addrtree->env) */ 792be9e038Ssthen void (*delfunc)(void *, void *); 802be9e038Ssthen /** Environment for delfunc */ 812be9e038Ssthen void *env; 822be9e038Ssthen /** External function returning size of elem. Called as 832be9e038Ssthen * sizefunc(addrnode->elem) */ 842be9e038Ssthen size_t (*sizefunc)(void *); 852be9e038Ssthen /** first node in LRU list, first candidate to go */ 862be9e038Ssthen struct addrnode* first; 872be9e038Ssthen /** last node in LRU list, last candidate to go */ 882be9e038Ssthen struct addrnode *last; 892be9e038Ssthen }; 902be9e038Ssthen 912be9e038Ssthen struct addrnode { 922be9e038Ssthen /** Payload of node, may be NULL */ 932be9e038Ssthen void *elem; 942be9e038Ssthen /** Abs time in seconds in which elem is meaningful */ 952be9e038Ssthen time_t ttl; 962be9e038Ssthen /** Number of significant bits in address. */ 972be9e038Ssthen addrlen_t scope; 98*45872187Ssthen /** Only use the element for queries for subnet/0. Set if the query 99*45872187Ssthen * for /0 was answered with scope 0. For query /x answer scope 0, 100*45872187Ssthen * they can match anything and this is false. */ 101*45872187Ssthen int only_match_scope_zero; 1022be9e038Ssthen /** A node can have 0-2 edges, set to NULL for unused */ 1032be9e038Ssthen struct addredge *edge[2]; 1042be9e038Ssthen /** edge between this node and parent */ 1052be9e038Ssthen struct addredge *parent_edge; 1062be9e038Ssthen /** previous node in LRU list */ 1072be9e038Ssthen struct addrnode *prev; 1082be9e038Ssthen /** next node in LRU list */ 1092be9e038Ssthen struct addrnode *next; 1102be9e038Ssthen }; 1112be9e038Ssthen 1122be9e038Ssthen struct addredge { 1132be9e038Ssthen /** address of connected node */ 1142be9e038Ssthen addrkey_t *str; 115bdfc4d55Sflorian /** length in bits of str */ 1162be9e038Ssthen addrlen_t len; 1172be9e038Ssthen /** child node this edge is connected to */ 1182be9e038Ssthen struct addrnode *node; 1192be9e038Ssthen /** Parent node this ege is connected to */ 1202be9e038Ssthen struct addrnode *parent_node; 1212be9e038Ssthen /** Index of this edge in parent_node */ 1222be9e038Ssthen int parent_index; 1232be9e038Ssthen }; 1242be9e038Ssthen 1252be9e038Ssthen /** 1262be9e038Ssthen * Size of tree in bytes. 1272be9e038Ssthen * @param tree: Tree. 1282be9e038Ssthen * @return size of tree in bytes. 1292be9e038Ssthen */ 1302be9e038Ssthen size_t addrtree_size(const struct addrtree *tree); 1312be9e038Ssthen 1322be9e038Ssthen /** 1332be9e038Ssthen * Create a new tree. 1342be9e038Ssthen * @param max_depth: Tree will cap keys to this length. 1352be9e038Ssthen * @param delfunc: f(element, env) delete element. 1362be9e038Ssthen * @param sizefunc: f(element) returning the size of element. 1372be9e038Ssthen * @param env: Module environment for alloc information. 1382be9e038Ssthen * @param max_node_count: Maximum size of this data structure in nodes. 1392be9e038Ssthen * 0 for unlimited. 1402be9e038Ssthen * @return new addrtree or NULL on failure. 1412be9e038Ssthen */ 1422be9e038Ssthen struct addrtree * 1432be9e038Ssthen addrtree_create(addrlen_t max_depth, void (*delfunc)(void *, void *), 1443150e5f6Ssthen size_t (*sizefunc)(void *), void *env, uint32_t max_node_count); 1452be9e038Ssthen 1462be9e038Ssthen /** 1472be9e038Ssthen * Free tree and all nodes below. 1482be9e038Ssthen * @param tree: Tree to be freed. 1492be9e038Ssthen */ 1502be9e038Ssthen void addrtree_delete(struct addrtree *tree); 1512be9e038Ssthen 1522be9e038Ssthen /** 1532be9e038Ssthen * Insert an element in the tree. Failures are silent. Sourcemask and 1542be9e038Ssthen * scope might be changed according to local policy. Caller should no 1552be9e038Ssthen * longer access elem, it could be free'd now or later during future 1562be9e038Ssthen * inserts. 1572be9e038Ssthen * 1582be9e038Ssthen * @param tree: Tree insert elem in. 1592be9e038Ssthen * @param addr: key for element lookup. 1602be9e038Ssthen * @param sourcemask: Length of addr in bits. 1612be9e038Ssthen * @param scope: Number of significant bits in addr. 1622be9e038Ssthen * @param elem: data to store in the tree. 1632be9e038Ssthen * @param ttl: elem is valid up to this time, seconds. 164*45872187Ssthen * @param only_match_scope_zero: set for when query /0 has scope /0 answer. 1652be9e038Ssthen * @param now: Current time in seconds. 1662be9e038Ssthen */ 1672be9e038Ssthen void addrtree_insert(struct addrtree *tree, const addrkey_t *addr, 1682be9e038Ssthen addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl, 169*45872187Ssthen time_t now, int only_match_scope_zero); 1702be9e038Ssthen 1712be9e038Ssthen /** 1722be9e038Ssthen * Find a node containing an element in the tree. 1732be9e038Ssthen * 1742be9e038Ssthen * @param tree: Tree to search. 1752be9e038Ssthen * @param addr: key for element lookup. 1762be9e038Ssthen * @param sourcemask: Length of addr in bits. 1772be9e038Ssthen * @param now: Current time in seconds. 1782be9e038Ssthen * @return addrnode or NULL on miss. 1792be9e038Ssthen */ 1802be9e038Ssthen struct addrnode * addrtree_find(struct addrtree *tree, 1812be9e038Ssthen const addrkey_t *addr, addrlen_t sourcemask, time_t now); 1822be9e038Ssthen 1832be9e038Ssthen /** Wrappers for static functions to unit test */ 1842be9e038Ssthen int unittest_wrapper_addrtree_cmpbit(const addrkey_t *key1, 1852be9e038Ssthen const addrkey_t *key2, addrlen_t n); 1862be9e038Ssthen addrlen_t unittest_wrapper_addrtree_bits_common(const addrkey_t *s1, 1872be9e038Ssthen addrlen_t l1, const addrkey_t *s2, addrlen_t l2, addrlen_t skip); 1882be9e038Ssthen int unittest_wrapper_addrtree_getbit(const addrkey_t *addr, 1892be9e038Ssthen addrlen_t addrlen, addrlen_t n); 1902be9e038Ssthen int unittest_wrapper_addrtree_issub(const addrkey_t *s1, addrlen_t l1, 1912be9e038Ssthen const addrkey_t *s2, addrlen_t l2, addrlen_t skip); 1922be9e038Ssthen #endif /* ADDRTREE_H */ 193