xref: /openbsd-src/usr.sbin/unbound/util/storage/dnstree.h (revision 458721875d1b45e3568fff7a629432f19ebbd2c3)
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