xref: /netbsd-src/external/mpl/bind/dist/lib/dns/include/dns/catz.h (revision 345cf9fb81bd0411c53e25d62cd93bdcaa865312)
1 /*	$NetBSD: catz.h,v 1.7 2024/02/21 22:52:09 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 void
135 dns_catz_entry_new(isc_mem_t *mctx, const dns_name_t *domain,
136 		   dns_catz_entry_t **nentryp);
137 /*%<
138  * Allocate a new catz_entry on 'mctx', with the name 'domain'
139  *
140  * Requires:
141  * \li	'mctx' to be a valid memory context.
142  * \li	'domain' to be valid dns_name or NULL.
143  * \li	'nentryp' to be non NULL, *nentryp to be NULL.
144  *
145  * Returns:
146  * \li	ISC_R_SUCCESS on success
147  * \li	ISC_R_NOMEMORY on allocation failure
148  */
149 
150 void
151 dns_catz_entry_copy(dns_catz_zone_t *catz, const dns_catz_entry_t *entry,
152 		    dns_catz_entry_t **nentryp);
153 /*%<
154  * Allocate a new catz_entry and deep copy 'entry' into 'nentryp'.
155  *
156  * Requires:
157  * \li	'mctx' to be a valid memory context.
158  * \li	'entry' to be non NULL.
159  * \li	'nentryp' to be non NULL, *nentryp to be NULL.
160  *
161  * Returns:
162  * \li	ISC_R_SUCCESS on success
163  * \li	ISC_R_NOMEMORY on allocation failure
164  */
165 
166 void
167 dns_catz_entry_attach(dns_catz_entry_t *entry, dns_catz_entry_t **entryp);
168 /*%<
169  * Attach an entry
170  *
171  * Requires:
172  * \li	'entry' is a valid dns_catz_entry_t.
173  * \li	'entryp' is not NULL and '*entryp' is NULL.
174  */
175 
176 void
177 dns_catz_entry_detach(dns_catz_zone_t *catz, dns_catz_entry_t **entryp);
178 /*%<
179  * Detach an entry, free if no further references
180  *
181  * Requires:
182  * \li	'catz' is a valid dns_catz_zone_t.
183  * \li	'entryp' is not NULL and '*entryp' is not NULL.
184  */
185 
186 bool
187 dns_catz_entry_validate(const dns_catz_entry_t *entry);
188 /*%<
189  * Validate whether entry is correct.
190  * (NOT YET IMPLEMENTED: always returns true)
191  *
192  * Requires:
193  *\li	'entry' is a valid dns_catz_entry_t.
194  */
195 
196 bool
197 dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb);
198 /*%<
199  * Deep compare two entries
200  *
201  * Requires:
202  * \li	'ea' is a valid dns_catz_entry_t.
203  * \li	'eb' is a valid dns_catz_entry_t.
204  *
205  * Returns:
206  * \li 'true' if entries are the same.
207  * \li 'false' if the entries differ.
208  */
209 
210 isc_result_t
211 dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **catzp,
212 		  const dns_name_t *name);
213 /*%<
214  * Allocate a new catz zone on catzs mctx
215  *
216  * Requires:
217  * \li	'catzs' is a valid dns_catz_zones_t.
218  * \li	'catzp' is not NULL and '*zonep' is NULL.
219  * \li	'name' is a valid dns_name_t.
220  *
221  */
222 
223 dns_name_t *
224 dns_catz_zone_getname(dns_catz_zone_t *catz);
225 /*%<
226  * Get catalog zone name
227  *
228  * Requires:
229  * \li	'catz' is a valid dns_catz_zone_t.
230  */
231 
232 dns_catz_options_t *
233 dns_catz_zone_getdefoptions(dns_catz_zone_t *catz);
234 /*%<
235  * Get default member zone options for catalog zone 'catz'
236  *
237  * Requires:
238  * \li	'catz' is a valid dns_catz_zone_t.
239  */
240 
241 void
242 dns_catz_zone_resetdefoptions(dns_catz_zone_t *catz);
243 /*%<
244  * Reset the default member zone options for catalog zone 'catz' to
245  * the default values.
246  *
247  * Requires:
248  * \li	'catz' is a valid dns_catz_zone_t.
249  */
250 
251 isc_result_t
252 dns_catz_generate_masterfilename(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
253 				 isc_buffer_t **buffer);
254 /*%<
255  * Generate master file name and put it into *buffer (might be reallocated).
256  * The general format of the file name is:
257  * __catz__catalog.zone.name__member_zone_name.db
258  * But if it's too long it's shortened to:
259  * __catz__unique_hash_generated_from_the_above.db
260  *
261  * Requires:
262  * \li	'catz' is a valid dns_catz_zone_t.
263  * \li	'entry' is a valid dns_catz_entry_t.
264  * \li	'buffer' is not NULL and '*buffer' is not NULL.
265  */
266 
267 isc_result_t
268 dns_catz_generate_zonecfg(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
269 			  isc_buffer_t **buf);
270 /*%<
271  * Generate a zone config entry (in text form) from dns_catz_entry and puts
272  * it into *buf. buf might be reallocated.
273  *
274  * Requires:
275  * \li	'catz' is a valid dns_catz_zone_t.
276  * \li	'entry' is a valid dns_catz_entry_t.
277  * \li	'buf' is not NULL and '*buf' is NULL.
278  *
279  */
280 
281 /* Methods provided by named to dynamically modify the member zones */
282 /* xxxwpk TODO config! */
283 typedef isc_result_t (*dns_catz_zoneop_fn_t)(dns_catz_entry_t *entry,
284 					     dns_catz_zone_t  *origin,
285 					     dns_view_t	      *view,
286 					     isc_taskmgr_t    *taskmgr,
287 					     void	      *udata);
288 struct dns_catz_zonemodmethods {
289 	dns_catz_zoneop_fn_t addzone;
290 	dns_catz_zoneop_fn_t modzone;
291 	dns_catz_zoneop_fn_t delzone;
292 	void		    *udata;
293 };
294 
295 isc_result_t
296 dns_catz_new_zones(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
297 		   isc_timermgr_t *timermgr, dns_catz_zones_t **catzsp,
298 		   dns_catz_zonemodmethods_t *zmm);
299 /*%<
300  * Allocate a new catz_zones object, a collection storing all catalog zones
301  * for a view.
302  *
303  * Requires:
304  * \li 'mctx' is not NULL.
305  * \li 'taskmgr' is not NULL.
306  * \li 'timermgr' is not NULL.
307  * \li 'catzsp' is not NULL and '*catzsp' is NULL.
308  * \li 'zmm' is not NULL.
309  *
310  */
311 
312 isc_result_t
313 dns_catz_add_zone(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_get_zone(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_taskaction immediately.
352  * If there was an update recently it schedules update_taskaction 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_unregister(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_register(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_get_iterator(dns_catz_zone_t *catz, isc_ht_iter_t **itp);
403 /*%<
404  * Get the hashtable iterator on catalog zone members, point '*itp' to it.
405  *
406  * Requires:
407  * \li	'catzs' is a valid dns_catz_zones_t.
408  * \li	'itp' is not NULL and '*itp' is NULL.
409  *
410  */
411 
412 void
413 dns_catz_shutdown_catzs(dns_catz_zones_t *catzs);
414 /*%<
415  * Shut down the catalog zones.
416  *
417  * Requires:
418  * \li	'catzs' is a valid dns_catz_zones_t.
419  *
420  */
421 
422 #ifdef DNS_CATZ_TRACE
423 /* Compatibility macros */
424 #define dns_catz_attach_catz(catz, catzp) \
425 	dns_catz_zone__attach(catz, catzp, __func__, __FILE__, __LINE__)
426 #define dns_catz_detach_catz(catzp) \
427 	dns_catz_zone__detach(catzp, __func__, __FILE__, __LINE__)
428 #define dns_catz_ref_catz(ptr) \
429 	dns_catz_zone__ref(ptr, __func__, __FILE__, __LINE__)
430 #define dns_catz_unref_catz(ptr) \
431 	dns_catz_zone__unref(ptr, __func__, __FILE__, __LINE__)
432 
433 #define dns_catz_attach_catzs(catzs, catzsp) \
434 	dns_catz_zones__attach(catzs, catzsp, __func__, __FILE__, __LINE__)
435 #define dns_catz_detach_catzs(catzsp) \
436 	dns_catz_zones__detach(catzsp, __func__, __FILE__, __LINE__)
437 #define dns_catz_ref_catzs(ptr) \
438 	dns_catz_zones__ref(ptr, __func__, __FILE__, __LINE__)
439 #define dns_catz_unref_catzs(ptr) \
440 	dns_catz_zones__unref(ptr, __func__, __FILE__, __LINE__)
441 
442 ISC_REFCOUNT_TRACE_DECL(dns_catz_zone);
443 ISC_REFCOUNT_TRACE_DECL(dns_catz_zones);
444 #else
445 /* Compatibility macros */
446 #define dns_catz_attach_catz(catz, catzp) dns_catz_zone_attach(catz, catzp)
447 #define dns_catz_detach_catz(catzp)	  dns_catz_zone_detach(catzp)
448 #define dns_catz_ref_catz(ptr)		  dns_catz_zone_ref(ptr)
449 #define dns_catz_unref_catz(ptr)	  dns_catz_zone_unref(ptr)
450 
451 #define dns_catz_attach_catzs(catzs, catzsp) \
452 	dns_catz_zones_attach(catzs, catzsp)
453 #define dns_catz_detach_catzs(catzsp) dns_catz_zones_detach(catzsp)
454 #define dns_catz_ref_catzs(ptr)	      dns_catz_zones_ref(ptr)
455 #define dns_catz_unref_catzs(ptr)     dns_catz_zones_unref(ptr)
456 
457 ISC_REFCOUNT_DECL(dns_catz_zone);
458 ISC_REFCOUNT_DECL(dns_catz_zones);
459 #endif /* DNS_CATZ_TRACE */
460 
461 ISC_LANG_ENDDECLS
462