xref: /netbsd-src/external/mpl/bind/dist/lib/dns/include/dns/catz.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: catz.h,v 1.9 2025/01/26 16:25:26 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 #pragma once
17 
18 /* Add -DDNS_CATZ_TRACE=1 to CFLAGS for detailed reference tracing */
19 
20 #include <inttypes.h>
21 #include <stdbool.h>
22 
23 #include <isc/ht.h>
24 #include <isc/lang.h>
25 #include <isc/refcount.h>
26 #include <isc/rwlock.h>
27 #include <isc/time.h>
28 #include <isc/timer.h>
29 
30 #include <dns/db.h>
31 #include <dns/fixedname.h>
32 #include <dns/ipkeylist.h>
33 #include <dns/rdata.h>
34 #include <dns/types.h>
35 
36 ISC_LANG_BEGINDECLS
37 
38 #define DNS_CATZ_ERROR_LEVEL  ISC_LOG_WARNING
39 #define DNS_CATZ_INFO_LEVEL   ISC_LOG_INFO
40 #define DNS_CATZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
41 #define DNS_CATZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
42 #define DNS_CATZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
43 #define DNS_CATZ_DEBUG_QUIET  (DNS_CATZ_DEBUG_LEVEL3 + 1)
44 
45 /*
46  * Catalog Zones functions and structures.
47  */
48 
49 /*
50  * Options for a member zone in a catalog
51  */
52 struct dns_catz_entry_options {
53 	/*
54 	 * Options that can be overridden in catalog zone
55 	 */
56 	/* default-masters/default-primaries definition */
57 	dns_ipkeylist_t masters;
58 
59 	/* both as text in config format, NULL if none */
60 	isc_buffer_t *allow_query;
61 	isc_buffer_t *allow_transfer;
62 
63 	/*
64 	 * Options that are only set in named.conf
65 	 */
66 	/* zone-directory definition */
67 	char *zonedir;
68 
69 	/* zone should not be stored on disk (no 'file' statement in def */
70 	bool in_memory;
71 	/*
72 	 * Minimal interval between catalog zone updates, if a new version
73 	 * of catalog zone is received before this time the update will be
74 	 * postponed. This is a global option for the whole catalog zone.
75 	 */
76 	uint32_t min_update_interval;
77 };
78 
79 void
80 dns_catz_options_init(dns_catz_options_t *options);
81 /*%<
82  * Initialize 'options' to NULL values.
83  *
84  * Requires:
85  * \li	'options' to be non NULL.
86  */
87 
88 void
89 dns_catz_options_free(dns_catz_options_t *options, isc_mem_t *mctx);
90 /*%<
91  * Free 'options' contents into 'mctx'. ('options' itself is not freed.)
92  *
93  * Requires:
94  * \li	'options' to be non NULL.
95  * \li	'mctx' to be a valid memory context.
96  */
97 
98 void
99 dns_catz_options_copy(isc_mem_t *mctx, const dns_catz_options_t *opts,
100 		      dns_catz_options_t *nopts);
101 /*%<
102  * Duplicate 'opts' into 'nopts', allocating space from 'mctx'.
103  *
104  * Requires:
105  * \li	'mctx' to be a valid memory context.
106  * \li	'options' to be non NULL and valid options.
107  * \li	'nopts' to be non NULL.
108  */
109 
110 void
111 dns_catz_options_setdefault(isc_mem_t *mctx, const dns_catz_options_t *defaults,
112 			    dns_catz_options_t *opts);
113 /*%<
114  * Replace empty values in 'opts' with values from 'defaults'
115  *
116  * Requires:
117  * \li	'mctx' to be a valid memory context.
118  * \li	'defaults' to be non NULL and valid options.
119  * \li	'opts' to be non NULL.
120  */
121 
122 dns_name_t *
123 dns_catz_entry_getname(dns_catz_entry_t *entry);
124 /*%<
125  * Get domain name for 'entry'
126  *
127  * Requires:
128  * \li	'entry' to be non NULL.
129  *
130  * Returns:
131  * \li	domain name for entry.
132  */
133 
134 dns_catz_entry_t *
135 dns_catz_entry_new(isc_mem_t *mctx, const dns_name_t *domain);
136 /*%<
137  * Allocate a new catz_entry on 'mctx', with the name 'domain'
138  *
139  * Requires:
140  * \li	'mctx' to be a valid memory context.
141  * \li	'domain' to be valid dns_name or NULL.
142  *
143  * Returns:
144  * \li	ISC_R_SUCCESS on success
145  * \li	ISC_R_NOMEMORY on allocation failure
146  */
147 
148 dns_catz_entry_t *
149 dns_catz_entry_copy(dns_catz_zone_t *catz, const dns_catz_entry_t *entry);
150 /*%<
151  * Allocate a new catz_entry and deep copy 'entry' into 'nentryp'.
152  *
153  * Requires:
154  * \li	'mctx' to be a valid memory context.
155  * \li	'entry' to be non NULL.
156  *
157  * Returns:
158  * \li	ISC_R_SUCCESS on success
159  * \li	ISC_R_NOMEMORY on allocation failure
160  */
161 
162 void
163 dns_catz_entry_attach(dns_catz_entry_t *entry, dns_catz_entry_t **entryp);
164 /*%<
165  * Attach an entry
166  *
167  * Requires:
168  * \li	'entry' is a valid dns_catz_entry_t.
169  * \li	'entryp' is not NULL and '*entryp' is NULL.
170  */
171 
172 void
173 dns_catz_entry_detach(dns_catz_zone_t *catz, dns_catz_entry_t **entryp);
174 /*%<
175  * Detach an entry, free if no further references
176  *
177  * Requires:
178  * \li	'catz' is a valid dns_catz_zone_t.
179  * \li	'entryp' is not NULL and '*entryp' is not NULL.
180  */
181 
182 bool
183 dns_catz_entry_validate(const dns_catz_entry_t *entry);
184 /*%<
185  * Validate whether entry is correct.
186  * (NOT YET IMPLEMENTED: always returns true)
187  *
188  * Requires:
189  *\li	'entry' is a valid dns_catz_entry_t.
190  */
191 
192 bool
193 dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb);
194 /*%<
195  * Deep compare two entries
196  *
197  * Requires:
198  * \li	'ea' is a valid dns_catz_entry_t.
199  * \li	'eb' is a valid dns_catz_entry_t.
200  *
201  * Returns:
202  * \li 'true' if entries are the same.
203  * \li 'false' if the entries differ.
204  */
205 
206 dns_catz_zone_t *
207 dns_catz_zone_new(dns_catz_zones_t *catzs, const dns_name_t *name);
208 /*%<
209  * Allocate a new catz zone on catzs mctx
210  *
211  * Requires:
212  * \li	'catzs' is a valid dns_catz_zones_t.
213  * \li	'catzp' is not NULL and '*catzp' is NULL.
214  * \li	'name' is a valid dns_name_t.
215  *
216  */
217 
218 dns_name_t *
219 dns_catz_zone_getname(dns_catz_zone_t *catz);
220 /*%<
221  * Get catalog zone name
222  *
223  * Requires:
224  * \li	'catz' is a valid dns_catz_zone_t.
225  */
226 
227 dns_catz_options_t *
228 dns_catz_zone_getdefoptions(dns_catz_zone_t *catz);
229 /*%<
230  * Get default member zone options for catalog zone 'catz'
231  *
232  * Requires:
233  * \li	'catz' is a valid dns_catz_zone_t.
234  */
235 
236 void
237 dns_catz_zone_resetdefoptions(dns_catz_zone_t *catz);
238 /*%<
239  * Reset the default member zone options for catalog zone 'catz' to
240  * the default values.
241  *
242  * Requires:
243  * \li	'catz' is a valid dns_catz_zone_t.
244  */
245 
246 isc_result_t
247 dns_catz_generate_masterfilename(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
248 				 isc_buffer_t **buffer);
249 /*%<
250  * Generate master file name and put it into *buffer (might be reallocated).
251  * The general format of the file name is:
252  * __catz__catalog.zone.name__member_zone_name.db
253  * But if it's too long it's shortened to:
254  * __catz__unique_hash_generated_from_the_above.db
255  *
256  * Requires:
257  * \li	'catz' is a valid dns_catz_zone_t.
258  * \li	'entry' is a valid dns_catz_entry_t.
259  * \li	'buffer' is not NULL and '*buffer' is not NULL.
260  */
261 
262 isc_result_t
263 dns_catz_generate_zonecfg(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
264 			  isc_buffer_t **buf);
265 /*%<
266  * Generate a zone config entry (in text form) from dns_catz_entry and puts
267  * it into *buf. buf might be reallocated.
268  *
269  * Requires:
270  * \li	'catz' is a valid dns_catz_zone_t.
271  * \li	'entry' is a valid dns_catz_entry_t.
272  * \li	'buf' is not NULL and '*buf' is NULL.
273  *
274  */
275 
276 /* Methods provided by named to dynamically modify the member zones */
277 /* xxxwpk TODO config! */
278 typedef isc_result_t (*dns_catz_zoneop_fn_t)(dns_catz_entry_t *entry,
279 					     dns_catz_zone_t  *origin,
280 					     dns_view_t *view, void *udata);
281 struct dns_catz_zonemodmethods {
282 	dns_catz_zoneop_fn_t addzone;
283 	dns_catz_zoneop_fn_t modzone;
284 	dns_catz_zoneop_fn_t delzone;
285 	void		    *udata;
286 };
287 
288 dns_catz_zones_t *
289 dns_catz_zones_new(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
290 		   dns_catz_zonemodmethods_t *zmm);
291 /*%<
292  * Allocate a new catz_zones object, a collection storing all catalog zones
293  * for a view.
294  *
295  * Requires:
296  * \li 'mctx' is not NULL.
297  * \li 'loopmgr' is not NULL.
298  * \li 'catzsp' is not NULL and '*catzsp' is NULL.
299  * \li 'zmm' is not NULL.
300  *
301  */
302 
303 void *
304 dns_catz_zones_get_udata(dns_catz_zones_t *catzs);
305 /*%<
306  * Get the 'udata' member of the zone methods which was set when creating catzs.
307  *
308  * Requires:
309  * \li	'catzs' is a valid dns_catz_zones_t.
310  */
311 
312 isc_result_t
313 dns_catz_zone_add(dns_catz_zones_t *catzs, const dns_name_t *name,
314 		  dns_catz_zone_t **catzp);
315 /*%<
316  * Allocate a new catz named 'name' and put it in 'catzs' collection. This
317  * function is safe to call only during a (re)configuration.
318  *
319  * Requires:
320  * \li	'catzs' is a valid dns_catz_zones_t.
321  * \li	'name' is a valid dns_name_t.
322  * \li	'catzp' is not NULL and *catzp is NULL.
323  *
324  */
325 
326 dns_catz_zone_t *
327 dns_catz_zone_get(dns_catz_zones_t *catzs, const dns_name_t *name);
328 /*%<
329  * Returns a zone named 'name' from collection 'catzs'
330  *
331  * Requires:
332  * \li	'catzs' is a valid dns_catz_zones_t.
333  * \li	'name' is a valid dns_name_t.
334  */
335 
336 void
337 dns_catz_catzs_set_view(dns_catz_zones_t *catzs, dns_view_t *view);
338 /*%<
339  * Set a view for 'catzs'.
340  *
341  * Requires:
342  * \li	'catzs' is a valid dns_catz_zones_t.
343  * \li	'catzs->view' is NULL or 'catzs->view' == 'view'.
344  */
345 
346 isc_result_t
347 dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg);
348 /*%<
349  * Callback for update of catalog zone database.
350  * If there was no catalog zone update recently it launches an
351  * update action immediately.
352  * If there was an update recently it schedules update for some time
353  * in the future.
354  * If there is an update scheduled it replaces old db version with a new one.
355  *
356  * Requires:
357  * \li	'db' is a valid database.
358  * \li	'fn_arg' is not NULL (casted to dns_catz_zones_t*).
359  */
360 
361 void
362 dns_catz_dbupdate_register(dns_db_t *db, dns_catz_zones_t *catzs);
363 /*%<
364  * Register the catalog zone database update notify callback.
365  *
366  * Requires:
367  * \li	'db' is a valid database.
368  * \li	'catzs' is valid.
369  */
370 
371 void
372 dns_catz_dbupdate_unregister(dns_db_t *db, dns_catz_zones_t *catzs);
373 /*%<
374  * Unregister the catalog zone database update notify callback.
375  *
376  * Requires:
377  * \li	'db' is a valid database.
378  * \li	'catzs' is valid.
379  */
380 
381 void
382 dns_catz_prereconfig(dns_catz_zones_t *catzs);
383 /*%<
384  * Called before reconfig, clears 'active' flag on all the zones in set
385  *
386  * Requires:
387  * \li	'catzs' is a valid dns_catz_zones_t.
388  *
389  */
390 
391 void
392 dns_catz_postreconfig(dns_catz_zones_t *catzs);
393 /*%<
394  * Called after reconfig, walks through all zones in set, removes those
395  * inactive and force reload of those with changed configuration.
396  *
397  * Requires:
398  * \li	'catzs' is a valid dns_catz_zones_t.
399  */
400 
401 void
402 dns_catz_zones_shutdown(dns_catz_zones_t *catzs);
403 /*%<
404  * Shut down the catalog zones.
405  *
406  * Requires:
407  * \li	'catzs' is a valid dns_catz_zones_t.
408  *
409  */
410 
411 typedef void (*dns_catz_entry_cb2)(dns_catz_entry_t *entry, void *arg1,
412 				   void *arg2);
413 
414 void
415 dns_catz_zone_for_each_entry2(dns_catz_zone_t *catz, dns_catz_entry_cb2 cb,
416 			      void *arg1, void *arg2);
417 /*%<
418  * Iterate on the catalog zone members, call 'cb' on each 'entry'.
419  *
420  * Requires:
421  * \li	'catz' is a valid dns_catz_zones_t.
422  *
423  */
424 
425 #ifdef DNS_CATZ_TRACE
426 /* Compatibility macros */
427 #define dns_catz_zone_attach(catz, catzp) \
428 	dns_catz_zone__attach(catz, catzp, __func__, __FILE__, __LINE__)
429 #define dns_catz_zone_detach(catzp) \
430 	dns_catz_zone__detach(catzp, __func__, __FILE__, __LINE__)
431 #define dns_catz_zone_ref(ptr) \
432 	dns_catz_zone__ref(ptr, __func__, __FILE__, __LINE__)
433 #define dns_catz_zone_unref(ptr) \
434 	dns_catz_zone__unref(ptr, __func__, __FILE__, __LINE__)
435 
436 #define dns_catz_zones_attach(catzs, catzsp) \
437 	dns_catz_zones__attach(catzs, catzsp, __func__, __FILE__, __LINE__)
438 #define dns_catz_zones_detach(catzsp) \
439 	dns_catz_zones__detach(catzsp, __func__, __FILE__, __LINE__)
440 #define dns_catz_zones_ref(ptr) \
441 	dns_catz_zones__ref(ptr, __func__, __FILE__, __LINE__)
442 #define dns_catz_zones_unref(ptr) \
443 	dns_catz_zones__unref(ptr, __func__, __FILE__, __LINE__)
444 
445 ISC_REFCOUNT_TRACE_DECL(dns_catz_zone);
446 ISC_REFCOUNT_TRACE_DECL(dns_catz_zones);
447 #else
448 ISC_REFCOUNT_DECL(dns_catz_zone);
449 ISC_REFCOUNT_DECL(dns_catz_zones);
450 #endif /* DNS_CATZ_TRACE */
451 
452 ISC_LANG_ENDDECLS
453