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