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"
47struct config_file;
48struct delegpt;
49
50/**
51 * Iterator forward zones structure
52 */
53struct 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 */
72struct 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 */
97struct iter_forwards* forwards_create(void);
98
99/**
100 * Delete forwards.
101 * @param fwd: to delete.
102 */
103void 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 */
111int 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 */
126struct 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 */
146struct 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 */
156struct 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 */
168int 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 */
177size_t forwards_get_mem(struct iter_forwards* fwd);
178
179/** compare two fwd entries */
180int 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 */
194int 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 */
207void 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 */
222int 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 */
234void 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