xref: /freebsd/contrib/unbound/iterator/iter_fwd.h (revision e63d20b70ee1dbee9b075f29de6f30cdcfe1abe1)
1 /*
2  * iterator/iter_fwd.h - iterative resolver module forward zones.
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /**
37  * \file
38  *
39  * This file contains functions to assist the iterator module.
40  * Keep track of forward zones, and read those from config.
41  */
42 
43 #ifndef ITERATOR_ITER_FWD_H
44 #define ITERATOR_ITER_FWD_H
45 #include "util/rbtree.h"
46 #include "util/locks.h"
47 struct config_file;
48 struct delegpt;
49 
50 /**
51  * Iterator forward zones structure
52  */
53 struct iter_forwards {
54 	/** lock on the forwards tree.
55 	 * When grabbing both this lock and the anchors.lock, this lock
56 	 * is grabbed first. When grabbing both this lock and the hints.lock
57 	 * this lock is grabbed first. */
58 	lock_rw_type lock;
59 	/**
60 	 * Zones are stored in this tree. Sort order is specially chosen.
61 	 * first sorted on qclass. Then on dname in nsec-like order, so that
62 	 * a lookup on class, name will return an exact match or the closest
63 	 * match which gives the ancestor needed.
64 	 * contents of type iter_forward_zone.
65 	 */
66 	rbtree_type* tree;
67 };
68 
69 /**
70  * Iterator forward servers for a particular zone.
71  */
72 struct iter_forward_zone {
73 	/** redblacktree node, key is this structure: class and name */
74 	rbnode_type node;
75 	/** name */
76 	uint8_t* name;
77 	/** length of name */
78 	size_t namelen;
79 	/** number of labels in name */
80 	int namelabs;
81 	/** delegation point with forward server information for this zone.
82 	 * If NULL then this forward entry is used to indicate that a
83 	 * stub-zone with the same name exists, and should be used.
84 	 * This delegation point is malloced.
85 	 */
86 	struct delegpt* dp;
87 	/** pointer to parent in tree (or NULL if none) */
88 	struct iter_forward_zone* parent;
89 	/** class. host order. */
90 	uint16_t dclass;
91 };
92 
93 /**
94  * Create forwards
95  * @return new forwards or NULL on error.
96  */
97 struct iter_forwards* forwards_create(void);
98 
99 /**
100  * Delete forwards.
101  * @param fwd: to delete.
102  */
103 void forwards_delete(struct iter_forwards* fwd);
104 
105 /**
106  * Process forwards config.
107  * @param fwd: where to store.
108  * @param cfg: config options.
109  * @return 0 on error.
110  */
111 int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
112 
113 /**
114  * Find forward zone exactly by name
115  * The return value is contents of the forwards structure.
116  * Caller should lock and unlock a readlock on the forwards structure if nolock
117  * is set.
118  * Otherwise caller should unlock the readlock on the forwards structure if a
119  * value was returned.
120  * @param fwd: forward storage.
121  * @param qname: The qname of the query.
122  * @param qclass: The qclass of the query.
123  * @param nolock: Skip locking, locking is handled by the caller.
124  * @return: A delegation point or null.
125  */
126 struct delegpt* forwards_find(struct iter_forwards* fwd, uint8_t* qname,
127 	uint16_t qclass, int nolock);
128 
129 /**
130  * Find forward zone information
131  * For this qname/qclass find forward zone information, returns delegation
132  * point with server names and addresses, or NULL if no forwarding is needed.
133  * The return value is contents of the forwards structure.
134  * Caller should lock and unlock a readlock on the forwards structure if nolock
135  * is set.
136  * Otherwise caller should unlock the readlock on the forwards structure if a
137  * value was returned.
138  *
139  * @param fwd: forward storage.
140  * @param qname: The qname of the query.
141  * @param qclass: The qclass of the query.
142  * @param nolock: Skip locking, locking is handled by the caller.
143  * @return: A delegation point if the query has to be forwarded to that list,
144  *         otherwise null.
145  */
146 struct delegpt* forwards_lookup(struct iter_forwards* fwd,
147 	uint8_t* qname, uint16_t qclass, int nolock);
148 
149 /**
150  * Same as forwards_lookup, but for the root only
151  * @param fwd: forward storage.
152  * @param qclass: The qclass of the query.
153  * @param nolock: Skip locking, locking is handled by the caller.
154  * @return: A delegation point if root forward exists, otherwise null.
155  */
156 struct delegpt* forwards_lookup_root(struct iter_forwards* fwd,
157 	uint16_t qclass, int nolock);
158 
159 /**
160  * Find next root item in forwards lookup tree.
161  * Handles its own locking unless nolock is set. In that case the caller
162  * should lock and unlock a readlock on the forwards structure.
163  * @param fwd: the forward storage
164  * @param qclass: class to look at next, or higher.
165  * @param nolock: Skip locking, locking is handled by the caller.
166  * @return false if none found, or if true stored in qclass.
167  */
168 int forwards_next_root(struct iter_forwards* fwd, uint16_t* qclass,
169 	int nolock);
170 
171 /**
172  * Get memory in use by forward storage
173  * Locks and unlocks the structure.
174  * @param fwd: forward storage.
175  * @return bytes in use
176  */
177 size_t forwards_get_mem(struct iter_forwards* fwd);
178 
179 /** compare two fwd entries */
180 int fwd_cmp(const void* k1, const void* k2);
181 
182 /**
183  * Add zone to forward structure. For external use since it recalcs
184  * the tree parents.
185  * Handles its own locking unless nolock is set. In that case the caller
186  * should lock and unlock a writelock on the forwards structure.
187  * @param fwd: the forward data structure
188  * @param c: class of zone
189  * @param dp: delegation point with name and target nameservers for new
190  *	forward zone. malloced.
191  * @param nolock: Skip locking, locking is handled by the caller.
192  * @return false on failure (out of memory);
193  */
194 int forwards_add_zone(struct iter_forwards* fwd, uint16_t c,
195 	struct delegpt* dp, int nolock);
196 
197 /**
198  * Remove zone from forward structure. For external use since it
199  * recalcs the tree parents.
200  * Handles its own locking unless nolock is set. In that case the caller
201  * should lock and unlock a writelock on the forwards structure.
202  * @param fwd: the forward data structure
203  * @param c: class of zone
204  * @param nm: name of zone (in uncompressed wireformat).
205  * @param nolock: Skip locking, locking is handled by the caller.
206  */
207 void forwards_delete_zone(struct iter_forwards* fwd, uint16_t c,
208 	uint8_t* nm, int nolock);
209 
210 /**
211  * Add stub hole (empty entry in forward table, that makes resolution skip
212  * a forward-zone because the stub zone should override the forward zone).
213  * Does not add one if not necessary.
214  * Handles its own locking unless nolock is set. In that case the caller
215  * should lock and unlock a writelock on the forwards structure.
216  * @param fwd: the forward data structure
217  * @param c: class of zone
218  * @param nm: name of zone (in uncompressed wireformat).
219  * @param nolock: Skip locking, locking is handled by the caller.
220  * @return false on failure (out of memory);
221  */
222 int forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c,
223 	uint8_t* nm, int nolock);
224 
225 /**
226  * Remove stub hole, if one exists.
227  * Handles its own locking unless nolock is set. In that case the caller
228  * should lock and unlock a writelock on the forwards structure.
229  * @param fwd: the forward data structure
230  * @param c: class of zone
231  * @param nm: name of zone (in uncompressed wireformat).
232  * @param nolock: Skip locking, locking is handled by the caller.
233  */
234 void forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c,
235 	uint8_t* nm, int nolock);
236 
237 #endif /* ITERATOR_ITER_FWD_H */
238