1 /*	$NetBSD: dbiterator.h,v 1.6 2022/09/23 12:15:30 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #ifndef DNS_DBITERATOR_H
17 #define DNS_DBITERATOR_H 1
18 
19 /*****
20 ***** Module Info
21 *****/
22 
23 /*! \file dns/dbiterator.h
24  * \brief
25  * The DNS DB Iterator interface allows iteration of all of the nodes in a
26  * database.
27  *
28  * The dns_dbiterator_t type is like a "virtual class".  To actually use
29  * it, an implementation of the class is required.  This implementation is
30  * supplied by the database.
31  *
32  * It is the client's responsibility to call dns_db_detachnode() on all
33  * nodes returned.
34  *
35  * XXX <more> XXX
36  *
37  * MP:
38  *\li	The iterator itself is not locked.  The caller must ensure
39  *	synchronization.
40  *
41  *\li	The iterator methods ensure appropriate database locking.
42  *
43  * Reliability:
44  *\li	No anticipated impact.
45  *
46  * Resources:
47  *\li	TBS
48  *
49  * Security:
50  *\li	No anticipated impact.
51  *
52  * Standards:
53  *\li	None.
54  */
55 
56 /*****
57 ***** Imports
58 *****/
59 
60 #include <stdbool.h>
61 
62 #include <isc/lang.h>
63 #include <isc/magic.h>
64 
65 #include <dns/types.h>
66 
67 ISC_LANG_BEGINDECLS
68 
69 /*****
70 ***** Types
71 *****/
72 
73 typedef struct dns_dbiteratormethods {
74 	void (*destroy)(dns_dbiterator_t **iteratorp);
75 	isc_result_t (*first)(dns_dbiterator_t *iterator);
76 	isc_result_t (*last)(dns_dbiterator_t *iterator);
77 	isc_result_t (*seek)(dns_dbiterator_t *iterator,
78 			     const dns_name_t *name);
79 	isc_result_t (*prev)(dns_dbiterator_t *iterator);
80 	isc_result_t (*next)(dns_dbiterator_t *iterator);
81 	isc_result_t (*current)(dns_dbiterator_t *iterator,
82 				dns_dbnode_t **nodep, dns_name_t *name);
83 	isc_result_t (*pause)(dns_dbiterator_t *iterator);
84 	isc_result_t (*origin)(dns_dbiterator_t *iterator, dns_name_t *name);
85 } dns_dbiteratormethods_t;
86 
87 #define DNS_DBITERATOR_MAGIC	  ISC_MAGIC('D', 'N', 'S', 'I')
88 #define DNS_DBITERATOR_VALID(dbi) ISC_MAGIC_VALID(dbi, DNS_DBITERATOR_MAGIC)
89 /*%
90  * This structure is actually just the common prefix of a DNS db
91  * implementation's version of a dns_dbiterator_t.
92  *
93  * Clients may use the 'db' field of this structure.  Except for that field,
94  * direct use of this structure by clients is forbidden.  DB implementations
95  * may change the structure.  'magic' must be DNS_DBITERATOR_MAGIC for any of
96  * the dns_dbiterator routines to work.  DB iterator implementations must
97  * maintain all DB iterator invariants.
98  */
99 struct dns_dbiterator {
100 	/* Unlocked. */
101 	unsigned int		 magic;
102 	dns_dbiteratormethods_t *methods;
103 	dns_db_t		*db;
104 	bool			 relative_names;
105 	bool			 cleaning;
106 };
107 
108 void
109 dns_dbiterator_destroy(dns_dbiterator_t **iteratorp);
110 /*%<
111  * Destroy '*iteratorp'.
112  *
113  * Requires:
114  *
115  *\li	'*iteratorp' is a valid iterator.
116  *
117  * Ensures:
118  *
119  *\li	All resources used by the iterator are freed.
120  *
121  *\li	*iteratorp == NULL.
122  */
123 
124 isc_result_t
125 dns_dbiterator_first(dns_dbiterator_t *iterator);
126 /*%<
127  * Move the node cursor to the first node in the database (if any).
128  *
129  * Requires:
130  *\li	'iterator' is a valid iterator.
131  *
132  * Returns:
133  *\li	#ISC_R_SUCCESS
134  *\li	#ISC_R_NOMORE			There are no nodes in the database.
135  *
136  *\li	Other results are possible, depending on the DB implementation.
137  */
138 
139 isc_result_t
140 dns_dbiterator_last(dns_dbiterator_t *iterator);
141 /*%<
142  * Move the node cursor to the last node in the database (if any).
143  *
144  * Requires:
145  *\li	'iterator' is a valid iterator.
146  *
147  * Returns:
148  *\li	#ISC_R_SUCCESS
149  *\li	#ISC_R_NOMORE			There are no nodes in the database.
150  *
151  *\li	Other results are possible, depending on the DB implementation.
152  */
153 
154 isc_result_t
155 dns_dbiterator_seek(dns_dbiterator_t *iterator, const dns_name_t *name);
156 /*%<
157  * Move the node cursor to the node with name 'name'.
158  *
159  * Requires:
160  *\li	'iterator' is a valid iterator.
161  *
162  *\li	'name' is a valid name.
163  *
164  * Returns:
165  *\li	#ISC_R_SUCCESS
166  *\li	#ISC_R_NOTFOUND
167  *\li	#DNS_R_PARTIALMATCH
168  *	(node is at name above requested named when name has children)
169  *
170  *\li	Other results are possible, depending on the DB implementation.
171  */
172 
173 isc_result_t
174 dns_dbiterator_prev(dns_dbiterator_t *iterator);
175 /*%<
176  * Move the node cursor to the previous node in the database (if any).
177  *
178  * Requires:
179  *\li	'iterator' is a valid iterator.
180  *
181  * Returns:
182  *\li	#ISC_R_SUCCESS
183  *\li	#ISC_R_NOMORE			There are no more nodes in the
184  *					database.
185  *
186  *\li	Other results are possible, depending on the DB implementation.
187  */
188 
189 isc_result_t
190 dns_dbiterator_next(dns_dbiterator_t *iterator);
191 /*%<
192  * Move the node cursor to the next node in the database (if any).
193  *
194  * Requires:
195  *\li	'iterator' is a valid iterator.
196  *
197  * Returns:
198  *\li	#ISC_R_SUCCESS
199  *\li	#ISC_R_NOMORE			There are no more nodes in the
200  *					database.
201  *
202  *\li	Other results are possible, depending on the DB implementation.
203  */
204 
205 isc_result_t
206 dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
207 		       dns_name_t *name);
208 /*%<
209  * Return the current node.
210  *
211  * Notes:
212  *\li	If 'name' is not NULL, it will be set to the name of the node.
213  *
214  * Requires:
215  *\li	'iterator' is a valid iterator.
216  *
217  *\li	nodep != NULL && *nodep == NULL
218  *
219  *\li	The node cursor of 'iterator' is at a valid location (i.e. the
220  *	result of last call to a cursor movement command was ISC_R_SUCCESS).
221  *
222  *\li	'name' is NULL, or is a valid name with a dedicated buffer.
223  *
224  * Returns:
225  *
226  *\li	#ISC_R_SUCCESS
227  *\li	#DNS_R_NEWORIGIN			If this iterator was created
228  * with 'relative_names' set to true, then #DNS_R_NEWORIGIN will be returned
229  *when
230  * the origin the names are relative to changes.  This result can occur only
231  *when
232  *'name' is not NULL.  This is also a successful result.
233  *
234  *\li	Other results are possible, depending on the DB implementation.
235  */
236 
237 isc_result_t
238 dns_dbiterator_pause(dns_dbiterator_t *iterator);
239 /*%<
240  * Pause iteration.
241  *
242  * Calling a cursor movement method or dns_dbiterator_current() may cause
243  * database locks to be acquired.  Rather than reacquire these locks every
244  * time one of these routines is called, the locks may simply be held.
245  * Calling dns_dbiterator_pause() releases any such locks.  Iterator clients
246  * should call this routine any time they are not going to execute another
247  * iterator method in the immediate future.
248  *
249  * Requires:
250  *\li	'iterator' is a valid iterator.
251  *
252  * Ensures:
253  *\li	Any database locks being held for efficiency of iterator access are
254  *	released.
255  *
256  * Returns:
257  *\li	#ISC_R_SUCCESS
258  *
259  *\li	Other results are possible, depending on the DB implementation.
260  */
261 
262 isc_result_t
263 dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name);
264 /*%<
265  * Return the origin to which returned node names are relative.
266  *
267  * Requires:
268  *
269  *\li	'iterator' is a valid relative_names iterator.
270  *
271  *\li	'name' is a valid name with a dedicated buffer.
272  *
273  * Returns:
274  *
275  *\li	#ISC_R_SUCCESS
276  *\li	#ISC_R_NOSPACE
277  *
278  *\li	Other results are possible, depending on the DB implementation.
279  */
280 
281 void
282 dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, bool mode);
283 /*%<
284  * Indicate that the given iterator is/is not cleaning the DB.
285  *
286  * Notes:
287  *\li	When 'mode' is true,
288  *
289  * Requires:
290  *\li	'iterator' is a valid iterator.
291  */
292 
293 ISC_LANG_ENDDECLS
294 
295 #endif /* DNS_DBITERATOR_H */
296