Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / dns / sdlz.c
blobc7156515466e03f459c2f0195eb1d91cdee3ba81
1 /* $NetBSD: sdlz.c,v 1.9 2015/07/08 17:28:59 christos Exp $ */
3 /*
4 * Portions Copyright (C) 2005-2014 Internet Systems Consortium, Inc. ("ISC")
5 * Portions Copyright (C) 1999-2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
21 * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
23 * Permission to use, copy, modify, and distribute this software for any
24 * purpose with or without fee is hereby granted, provided that the
25 * above copyright notice and this permission notice appear in all
26 * copies.
28 * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
29 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
31 * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
32 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
33 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
34 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
35 * USE OR PERFORMANCE OF THIS SOFTWARE.
37 * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
38 * conceived and contributed by Rob Butler.
40 * Permission to use, copy, modify, and distribute this software for any
41 * purpose with or without fee is hereby granted, provided that the
42 * above copyright notice and this permission notice appear in all
43 * copies.
45 * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
46 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
48 * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
49 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
50 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
51 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
52 * USE OR PERFORMANCE OF THIS SOFTWARE.
55 /* Id */
57 /*! \file */
59 #include <config.h>
60 #include <string.h>
62 #include <isc/buffer.h>
63 #include <isc/lex.h>
64 #include <isc/log.h>
65 #include <isc/rwlock.h>
66 #include <isc/string.h>
67 #include <isc/util.h>
68 #include <isc/magic.h>
69 #include <isc/mem.h>
70 #include <isc/once.h>
71 #include <isc/print.h>
72 #include <isc/region.h>
74 #include <dns/callbacks.h>
75 #include <dns/db.h>
76 #include <dns/dbiterator.h>
77 #include <dns/dlz.h>
78 #include <dns/fixedname.h>
79 #include <dns/log.h>
80 #include <dns/rdata.h>
81 #include <dns/rdatalist.h>
82 #include <dns/rdataset.h>
83 #include <dns/rdatasetiter.h>
84 #include <dns/rdatatype.h>
85 #include <dns/result.h>
86 #include <dns/master.h>
87 #include <dns/sdlz.h>
88 #include <dns/types.h>
90 #include "rdatalist_p.h"
93 * Private Types
96 struct dns_sdlzimplementation {
97 const dns_sdlzmethods_t *methods;
98 isc_mem_t *mctx;
99 void *driverarg;
100 unsigned int flags;
101 isc_mutex_t driverlock;
102 dns_dlzimplementation_t *dlz_imp;
105 struct dns_sdlz_db {
106 /* Unlocked */
107 dns_db_t common;
108 void *dbdata;
109 dns_sdlzimplementation_t *dlzimp;
110 isc_mutex_t refcnt_lock;
111 /* Locked */
112 unsigned int references;
113 dns_dbversion_t *future_version;
114 int dummy_version;
117 struct dns_sdlzlookup {
118 /* Unlocked */
119 unsigned int magic;
120 dns_sdlz_db_t *sdlz;
121 ISC_LIST(dns_rdatalist_t) lists;
122 ISC_LIST(isc_buffer_t) buffers;
123 dns_name_t *name;
124 ISC_LINK(dns_sdlzlookup_t) link;
125 isc_mutex_t lock;
126 dns_rdatacallbacks_t callbacks;
127 /* Locked */
128 unsigned int references;
131 typedef struct dns_sdlzlookup dns_sdlznode_t;
133 struct dns_sdlzallnodes {
134 dns_dbiterator_t common;
135 ISC_LIST(dns_sdlznode_t) nodelist;
136 dns_sdlznode_t *current;
137 dns_sdlznode_t *origin;
140 typedef dns_sdlzallnodes_t sdlz_dbiterator_t;
142 typedef struct sdlz_rdatasetiter {
143 dns_rdatasetiter_t common;
144 dns_rdatalist_t *current;
145 } sdlz_rdatasetiter_t;
148 #define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S')
151 * Note that "impmagic" is not the first four bytes of the struct, so
152 * ISC_MAGIC_VALID cannot be used.
155 #define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \
156 (sdlzdb)->common.impmagic == SDLZDB_MAGIC)
158 #define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L')
159 #define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC)
160 #define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn)
162 /* These values are taken from RFC 1537 */
163 #define SDLZ_DEFAULT_REFRESH (60 * 60 * 8)
164 #define SDLZ_DEFAULT_RETRY (60 * 60 * 2)
165 #define SDLZ_DEFAULT_EXPIRE (60 * 60 * 24 * 7)
166 #define SDLZ_DEFAULT_MINIMUM (60 * 60 * 24)
168 /* This is a reasonable value */
169 #define SDLZ_DEFAULT_TTL (60 * 60 * 24)
171 #ifdef __COVERITY__
172 #define MAYBE_LOCK(imp) LOCK(&imp->driverlock)
173 #define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock)
174 #else
175 #define MAYBE_LOCK(imp) \
176 do { \
177 unsigned int flags = imp->flags; \
178 if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
179 LOCK(&imp->driverlock); \
180 } while (/*CONSTCOND*/0)
182 #define MAYBE_UNLOCK(imp) \
183 do { \
184 unsigned int flags = imp->flags; \
185 if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
186 UNLOCK(&imp->driverlock); \
187 } while (/*CONSTCOND*/0)
188 #endif
191 * Forward references. Try to keep these to a minimum.
194 static void list_tordataset(dns_rdatalist_t *rdatalist,
195 dns_db_t *db, dns_dbnode_t *node,
196 dns_rdataset_t *rdataset);
198 static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
200 static void dbiterator_destroy(dns_dbiterator_t **iteratorp);
201 static isc_result_t dbiterator_first(dns_dbiterator_t *iterator);
202 static isc_result_t dbiterator_last(dns_dbiterator_t *iterator);
203 static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator,
204 dns_name_t *name);
205 static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator);
206 static isc_result_t dbiterator_next(dns_dbiterator_t *iterator);
207 static isc_result_t dbiterator_current(dns_dbiterator_t *iterator,
208 dns_dbnode_t **nodep,
209 dns_name_t *name);
210 static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator);
211 static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator,
212 dns_name_t *name);
214 static dns_dbiteratormethods_t dbiterator_methods = {
215 dbiterator_destroy,
216 dbiterator_first,
217 dbiterator_last,
218 dbiterator_seek,
219 dbiterator_prev,
220 dbiterator_next,
221 dbiterator_current,
222 dbiterator_pause,
223 dbiterator_origin
227 * Utility functions
231 * Log a message at the given level
233 static void
234 sdlz_log(int level, const char *fmt, ...) {
235 va_list ap;
236 va_start(ap, fmt);
237 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
238 DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(level),
239 fmt, ap);
240 va_end(ap);
243 /*% Converts the input string to lowercase, in place. */
244 static void
245 dns_sdlz_tolower(char *str) {
246 unsigned int len = strlen(str);
247 unsigned int i;
249 for (i = 0; i < len; i++) {
250 if (str[i] >= 'A' && str[i] <= 'Z')
251 str[i] += 32;
255 static inline unsigned int
256 initial_size(const char *data) {
257 unsigned int len = (strlen(data) / 64) + 1;
258 return (len * 64 + 64);
262 * Rdataset Iterator Methods. These methods were "borrowed" from the SDB
263 * driver interface. See the SDB driver interface documentation for more info.
266 static void
267 rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
268 sdlz_rdatasetiter_t *sdlziterator =
269 (sdlz_rdatasetiter_t *)(*iteratorp);
271 detachnode(sdlziterator->common.db, &sdlziterator->common.node);
272 isc_mem_put(sdlziterator->common.db->mctx, sdlziterator,
273 sizeof(sdlz_rdatasetiter_t));
274 *iteratorp = NULL;
277 static isc_result_t
278 rdatasetiter_first(dns_rdatasetiter_t *iterator) {
279 sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
280 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node;
282 if (ISC_LIST_EMPTY(sdlznode->lists))
283 return (ISC_R_NOMORE);
284 sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists);
285 return (ISC_R_SUCCESS);
288 static isc_result_t
289 rdatasetiter_next(dns_rdatasetiter_t *iterator) {
290 sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
292 sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link);
293 if (sdlziterator->current == NULL)
294 return (ISC_R_NOMORE);
295 else
296 return (ISC_R_SUCCESS);
299 static void
300 rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
301 sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator;
303 list_tordataset(sdlziterator->current, iterator->db, iterator->node,
304 rdataset);
307 static dns_rdatasetitermethods_t rdatasetiter_methods = {
308 rdatasetiter_destroy,
309 rdatasetiter_first,
310 rdatasetiter_next,
311 rdatasetiter_current
315 * DB routines. These methods were "borrowed" from the SDB driver interface.
316 * See the SDB driver interface documentation for more info.
319 static void
320 attach(dns_db_t *source, dns_db_t **targetp) {
321 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source;
323 REQUIRE(VALID_SDLZDB(sdlz));
325 LOCK(&sdlz->refcnt_lock);
326 REQUIRE(sdlz->references > 0);
327 sdlz->references++;
328 UNLOCK(&sdlz->refcnt_lock);
330 *targetp = source;
333 static void
334 destroy(dns_sdlz_db_t *sdlz) {
335 isc_mem_t *mctx;
336 mctx = sdlz->common.mctx;
338 sdlz->common.magic = 0;
339 sdlz->common.impmagic = 0;
341 (void)isc_mutex_destroy(&sdlz->refcnt_lock);
343 dns_name_free(&sdlz->common.origin, mctx);
345 isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t));
346 isc_mem_detach(&mctx);
349 static void
350 detach(dns_db_t **dbp) {
351 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp);
352 isc_boolean_t need_destroy = ISC_FALSE;
354 REQUIRE(VALID_SDLZDB(sdlz));
355 LOCK(&sdlz->refcnt_lock);
356 REQUIRE(sdlz->references > 0);
357 sdlz->references--;
358 if (sdlz->references == 0)
359 need_destroy = ISC_TRUE;
360 UNLOCK(&sdlz->refcnt_lock);
362 if (need_destroy)
363 destroy(sdlz);
365 *dbp = NULL;
368 static isc_result_t
369 beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
370 UNUSED(db);
371 UNUSED(callbacks);
372 return (ISC_R_NOTIMPLEMENTED);
375 static isc_result_t
376 endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
377 UNUSED(db);
378 UNUSED(callbacks);
379 return (ISC_R_NOTIMPLEMENTED);
382 static isc_result_t
383 dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
384 dns_masterformat_t masterformat)
386 UNUSED(db);
387 UNUSED(version);
388 UNUSED(filename);
389 UNUSED(masterformat);
390 return (ISC_R_NOTIMPLEMENTED);
393 static void
394 currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
395 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
396 REQUIRE(VALID_SDLZDB(sdlz));
397 REQUIRE(versionp != NULL && *versionp == NULL);
399 *versionp = (void *) &sdlz->dummy_version;
400 return;
403 static isc_result_t
404 newversion(dns_db_t *db, dns_dbversion_t **versionp) {
405 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
406 char origin[DNS_NAME_MAXTEXT + 1];
407 isc_result_t result;
409 REQUIRE(VALID_SDLZDB(sdlz));
411 if (sdlz->dlzimp->methods->newversion == NULL)
412 return (ISC_R_NOTIMPLEMENTED);
414 dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
416 result = sdlz->dlzimp->methods->newversion(origin,
417 sdlz->dlzimp->driverarg,
418 sdlz->dbdata, versionp);
419 if (result != ISC_R_SUCCESS) {
420 sdlz_log(ISC_LOG_ERROR,
421 "sdlz newversion on origin %s failed : %s",
422 origin, isc_result_totext(result));
423 return (result);
426 sdlz->future_version = *versionp;
427 return (ISC_R_SUCCESS);
430 static void
431 attachversion(dns_db_t *db, dns_dbversion_t *source,
432 dns_dbversion_t **targetp)
434 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
436 REQUIRE(VALID_SDLZDB(sdlz));
437 REQUIRE(source != NULL && source == (void *)&sdlz->dummy_version);
439 *targetp = source;
442 static void
443 closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
444 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
445 char origin[DNS_NAME_MAXTEXT + 1];
447 REQUIRE(VALID_SDLZDB(sdlz));
448 REQUIRE(versionp != NULL);
450 if (*versionp == (void *)&sdlz->dummy_version) {
451 *versionp = NULL;
452 return;
455 REQUIRE(*versionp == sdlz->future_version);
456 REQUIRE(sdlz->dlzimp->methods->closeversion != NULL);
458 dns_name_format(&sdlz->common.origin, origin, sizeof(origin));
460 sdlz->dlzimp->methods->closeversion(origin, commit,
461 sdlz->dlzimp->driverarg,
462 sdlz->dbdata, versionp);
463 if (*versionp != NULL)
464 sdlz_log(ISC_LOG_ERROR,
465 "sdlz closeversion on origin %s failed", origin);
467 sdlz->future_version = NULL;
470 static isc_result_t
471 createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) {
472 dns_sdlznode_t *node;
473 isc_result_t result;
474 void *sdlzv, *tdlzv;
476 node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t));
477 if (node == NULL)
478 return (ISC_R_NOMEMORY);
480 node->sdlz = NULL;
481 sdlzv = sdlz;
482 tdlzv = &node->sdlz;
483 attach(sdlzv, tdlzv);
484 ISC_LIST_INIT(node->lists);
485 ISC_LIST_INIT(node->buffers);
486 ISC_LINK_INIT(node, link);
487 node->name = NULL;
488 result = isc_mutex_init(&node->lock);
489 if (result != ISC_R_SUCCESS) {
490 UNEXPECTED_ERROR(__FILE__, __LINE__,
491 "isc_mutex_init() failed: %s",
492 isc_result_totext(result));
493 isc_mem_put(sdlz->common.mctx, node, sizeof(dns_sdlznode_t));
494 return (ISC_R_UNEXPECTED);
496 dns_rdatacallbacks_init(&node->callbacks);
497 node->references = 1;
498 node->magic = SDLZLOOKUP_MAGIC;
500 *nodep = node;
501 return (ISC_R_SUCCESS);
504 static void
505 destroynode(dns_sdlznode_t *node) {
506 dns_rdatalist_t *list;
507 dns_rdata_t *rdata;
508 isc_buffer_t *b;
509 dns_sdlz_db_t *sdlz;
510 dns_db_t *db;
511 isc_mem_t *mctx;
513 sdlz = node->sdlz;
514 mctx = sdlz->common.mctx;
516 while (!ISC_LIST_EMPTY(node->lists)) {
517 list = ISC_LIST_HEAD(node->lists);
518 while (!ISC_LIST_EMPTY(list->rdata)) {
519 rdata = ISC_LIST_HEAD(list->rdata);
520 ISC_LIST_UNLINK(list->rdata, rdata, link);
521 isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
523 ISC_LIST_UNLINK(node->lists, list, link);
524 isc_mem_put(mctx, list, sizeof(dns_rdatalist_t));
527 while (!ISC_LIST_EMPTY(node->buffers)) {
528 b = ISC_LIST_HEAD(node->buffers);
529 ISC_LIST_UNLINK(node->buffers, b, link);
530 isc_buffer_free(&b);
533 if (node->name != NULL) {
534 dns_name_free(node->name, mctx);
535 isc_mem_put(mctx, node->name, sizeof(dns_name_t));
537 DESTROYLOCK(&node->lock);
538 node->magic = 0;
539 isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));
540 db = &sdlz->common;
541 detach(&db);
544 static isc_result_t
545 findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
546 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
547 dns_dbnode_t **nodep)
549 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
550 dns_sdlznode_t *node = NULL;
551 isc_result_t result;
552 isc_buffer_t b;
553 char namestr[DNS_NAME_MAXTEXT + 1];
554 isc_buffer_t b2;
555 char zonestr[DNS_NAME_MAXTEXT + 1];
556 isc_boolean_t isorigin;
557 dns_sdlzauthorityfunc_t authority;
559 REQUIRE(VALID_SDLZDB(sdlz));
560 REQUIRE(nodep != NULL && *nodep == NULL);
562 if (sdlz->dlzimp->methods->newversion == NULL) {
563 REQUIRE(create == ISC_FALSE);
566 isc_buffer_init(&b, namestr, sizeof(namestr));
567 if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) {
568 dns_name_t relname;
569 unsigned int labels;
571 labels = dns_name_countlabels(name) -
572 dns_name_countlabels(&db->origin);
573 dns_name_init(&relname, NULL);
574 dns_name_getlabelsequence(name, 0, labels, &relname);
575 result = dns_name_totext(&relname, ISC_TRUE, &b);
576 if (result != ISC_R_SUCCESS)
577 return (result);
578 } else {
579 result = dns_name_totext(name, ISC_TRUE, &b);
580 if (result != ISC_R_SUCCESS)
581 return (result);
583 isc_buffer_putuint8(&b, 0);
585 isc_buffer_init(&b2, zonestr, sizeof(zonestr));
586 result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b2);
587 if (result != ISC_R_SUCCESS)
588 return (result);
589 isc_buffer_putuint8(&b2, 0);
591 result = createnode(sdlz, &node);
592 if (result != ISC_R_SUCCESS)
593 return (result);
595 isorigin = dns_name_equal(name, &sdlz->common.origin);
597 /* make sure strings are always lowercase */
598 dns_sdlz_tolower(zonestr);
599 dns_sdlz_tolower(namestr);
601 MAYBE_LOCK(sdlz->dlzimp);
603 /* try to lookup the host (namestr) */
604 result = sdlz->dlzimp->methods->lookup(zonestr, namestr,
605 sdlz->dlzimp->driverarg,
606 sdlz->dbdata, node,
607 methods, clientinfo);
610 * if the host (namestr) was not found, try to lookup a
611 * "wildcard" host.
613 if (result == ISC_R_NOTFOUND && !create)
614 result = sdlz->dlzimp->methods->lookup(zonestr, "*",
615 sdlz->dlzimp->driverarg,
616 sdlz->dbdata, node,
617 methods, clientinfo);
619 MAYBE_UNLOCK(sdlz->dlzimp);
621 if (result == ISC_R_NOTFOUND && (isorigin || create))
622 result = ISC_R_SUCCESS;
624 if (result != ISC_R_SUCCESS) {
625 destroynode(node);
626 return (result);
629 if (isorigin && sdlz->dlzimp->methods->authority != NULL) {
630 MAYBE_LOCK(sdlz->dlzimp);
631 authority = sdlz->dlzimp->methods->authority;
632 result = (*authority)(zonestr, sdlz->dlzimp->driverarg,
633 sdlz->dbdata, node);
634 MAYBE_UNLOCK(sdlz->dlzimp);
635 if (result != ISC_R_SUCCESS &&
636 result != ISC_R_NOTIMPLEMENTED)
638 destroynode(node);
639 return (result);
643 if (node->name == NULL) {
644 node->name = isc_mem_get(sdlz->common.mctx,
645 sizeof(dns_name_t));
646 if (node->name == NULL) {
647 destroynode(node);
648 return (ISC_R_NOMEMORY);
650 dns_name_init(node->name, NULL);
651 result = dns_name_dup(name, sdlz->common.mctx, node->name);
652 if (result != ISC_R_SUCCESS) {
653 isc_mem_put(sdlz->common.mctx, node->name,
654 sizeof(dns_name_t));
655 destroynode(node);
656 return (result);
660 *nodep = node;
661 return (ISC_R_SUCCESS);
664 static isc_result_t
665 findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
666 dns_dbnode_t **nodep)
668 return (findnodeext(db, name, create, NULL, NULL, nodep));
671 static isc_result_t
672 findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
673 isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
674 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
676 UNUSED(db);
677 UNUSED(name);
678 UNUSED(options);
679 UNUSED(now);
680 UNUSED(nodep);
681 UNUSED(foundname);
682 UNUSED(rdataset);
683 UNUSED(sigrdataset);
685 return (ISC_R_NOTIMPLEMENTED);
688 static void
689 attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
690 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
691 dns_sdlznode_t *node = (dns_sdlznode_t *)source;
693 REQUIRE(VALID_SDLZDB(sdlz));
695 UNUSED(sdlz);
697 LOCK(&node->lock);
698 INSIST(node->references > 0);
699 node->references++;
700 INSIST(node->references != 0); /* Catch overflow. */
701 UNLOCK(&node->lock);
703 *targetp = source;
706 static void
707 detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
708 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
709 dns_sdlznode_t *node;
710 isc_boolean_t need_destroy = ISC_FALSE;
712 REQUIRE(VALID_SDLZDB(sdlz));
713 REQUIRE(targetp != NULL && *targetp != NULL);
715 UNUSED(sdlz);
717 node = (dns_sdlznode_t *)(*targetp);
719 LOCK(&node->lock);
720 INSIST(node->references > 0);
721 node->references--;
722 if (node->references == 0)
723 need_destroy = ISC_TRUE;
724 UNLOCK(&node->lock);
726 if (need_destroy)
727 destroynode(node);
729 *targetp = NULL;
732 static isc_result_t
733 expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
734 UNUSED(db);
735 UNUSED(node);
736 UNUSED(now);
737 INSIST(0);
738 return (ISC_R_UNEXPECTED);
741 static void
742 printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
743 UNUSED(db);
744 UNUSED(node);
745 UNUSED(out);
746 return;
749 static isc_result_t
750 createiterator(dns_db_t *db, unsigned int options, dns_dbiterator_t **iteratorp)
752 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
753 sdlz_dbiterator_t *sdlziter;
754 isc_result_t result;
755 isc_buffer_t b;
756 char zonestr[DNS_NAME_MAXTEXT + 1];
758 REQUIRE(VALID_SDLZDB(sdlz));
760 if (sdlz->dlzimp->methods->allnodes == NULL)
761 return (ISC_R_NOTIMPLEMENTED);
763 if ((options & DNS_DB_NSEC3ONLY) != 0 ||
764 (options & DNS_DB_NONSEC3) != 0)
765 return (ISC_R_NOTIMPLEMENTED);
767 isc_buffer_init(&b, zonestr, sizeof(zonestr));
768 result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b);
769 if (result != ISC_R_SUCCESS)
770 return (result);
771 isc_buffer_putuint8(&b, 0);
773 sdlziter = isc_mem_get(sdlz->common.mctx, sizeof(sdlz_dbiterator_t));
774 if (sdlziter == NULL)
775 return (ISC_R_NOMEMORY);
777 sdlziter->common.methods = &dbiterator_methods;
778 sdlziter->common.db = NULL;
779 dns_db_attach(db, &sdlziter->common.db);
780 sdlziter->common.relative_names = ISC_TF(options & DNS_DB_RELATIVENAMES);
781 sdlziter->common.magic = DNS_DBITERATOR_MAGIC;
782 ISC_LIST_INIT(sdlziter->nodelist);
783 sdlziter->current = NULL;
784 sdlziter->origin = NULL;
786 /* make sure strings are always lowercase */
787 dns_sdlz_tolower(zonestr);
789 MAYBE_LOCK(sdlz->dlzimp);
790 result = sdlz->dlzimp->methods->allnodes(zonestr,
791 sdlz->dlzimp->driverarg,
792 sdlz->dbdata, sdlziter);
793 MAYBE_UNLOCK(sdlz->dlzimp);
794 if (result != ISC_R_SUCCESS) {
795 dns_dbiterator_t *iter = &sdlziter->common;
796 dbiterator_destroy(&iter);
797 return (result);
800 if (sdlziter->origin != NULL) {
801 ISC_LIST_UNLINK(sdlziter->nodelist, sdlziter->origin, link);
802 ISC_LIST_PREPEND(sdlziter->nodelist, sdlziter->origin, link);
805 *iteratorp = (dns_dbiterator_t *)sdlziter;
807 return (ISC_R_SUCCESS);
810 static isc_result_t
811 findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
812 dns_rdatatype_t type, dns_rdatatype_t covers,
813 isc_stdtime_t now, dns_rdataset_t *rdataset,
814 dns_rdataset_t *sigrdataset)
816 dns_rdatalist_t *list;
817 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node;
819 REQUIRE(VALID_SDLZNODE(node));
821 UNUSED(db);
822 UNUSED(version);
823 UNUSED(covers);
824 UNUSED(now);
825 UNUSED(sigrdataset);
827 if (type == dns_rdatatype_sig || type == dns_rdatatype_rrsig)
828 return (ISC_R_NOTIMPLEMENTED);
830 list = ISC_LIST_HEAD(sdlznode->lists);
831 while (list != NULL) {
832 if (list->type == type)
833 break;
834 list = ISC_LIST_NEXT(list, link);
836 if (list == NULL)
837 return (ISC_R_NOTFOUND);
839 list_tordataset(list, db, node, rdataset);
841 return (ISC_R_SUCCESS);
844 static isc_result_t
845 findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
846 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
847 dns_dbnode_t **nodep, dns_name_t *foundname,
848 dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
849 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
851 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
852 dns_dbnode_t *node = NULL;
853 dns_fixedname_t fname;
854 dns_rdataset_t xrdataset;
855 dns_name_t *xname;
856 unsigned int nlabels, olabels;
857 isc_result_t result;
858 unsigned int i;
860 REQUIRE(VALID_SDLZDB(sdlz));
861 REQUIRE(nodep == NULL || *nodep == NULL);
862 REQUIRE(version == NULL || version == (void*)&sdlz->dummy_version);
864 UNUSED(options);
865 UNUSED(sdlz);
867 if (!dns_name_issubdomain(name, &db->origin))
868 return (DNS_R_NXDOMAIN);
870 olabels = dns_name_countlabels(&db->origin);
871 nlabels = dns_name_countlabels(name);
873 dns_fixedname_init(&fname);
874 xname = dns_fixedname_name(&fname);
876 if (rdataset == NULL) {
877 dns_rdataset_init(&xrdataset);
878 rdataset = &xrdataset;
881 result = DNS_R_NXDOMAIN;
883 for (i = olabels; i <= nlabels; i++) {
885 * Look up the next label.
887 dns_name_getlabelsequence(name, nlabels - i, i, xname);
888 result = findnodeext(db, xname, ISC_FALSE,
889 methods, clientinfo, &node);
890 if (result == ISC_R_NOTFOUND) {
891 result = DNS_R_NXDOMAIN;
892 continue;
893 } else if (result != ISC_R_SUCCESS)
894 break;
897 * Look for a DNAME at the current label, unless this is
898 * the qname.
900 if (i < nlabels) {
901 result = findrdataset(db, node, version,
902 dns_rdatatype_dname, 0, now,
903 rdataset, sigrdataset);
904 if (result == ISC_R_SUCCESS) {
905 result = DNS_R_DNAME;
906 break;
911 * Look for an NS at the current label, unless this is the
912 * origin or glue is ok.
914 if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) {
915 result = findrdataset(db, node, version,
916 dns_rdatatype_ns, 0, now,
917 rdataset, sigrdataset);
918 if (result == ISC_R_SUCCESS) {
919 if (i == nlabels && type == dns_rdatatype_any)
921 result = DNS_R_ZONECUT;
922 dns_rdataset_disassociate(rdataset);
923 if (sigrdataset != NULL &&
924 dns_rdataset_isassociated
925 (sigrdataset)) {
926 dns_rdataset_disassociate
927 (sigrdataset);
929 } else
930 result = DNS_R_DELEGATION;
931 break;
936 * If the current name is not the qname, add another label
937 * and try again.
939 if (i < nlabels) {
940 destroynode(node);
941 node = NULL;
942 continue;
946 * If we're looking for ANY, we're done.
948 if (type == dns_rdatatype_any) {
949 result = ISC_R_SUCCESS;
950 break;
954 * Look for the qtype.
956 result = findrdataset(db, node, version, type, 0, now,
957 rdataset, sigrdataset);
958 if (result == ISC_R_SUCCESS)
959 break;
962 * Look for a CNAME
964 if (type != dns_rdatatype_cname) {
965 result = findrdataset(db, node, version,
966 dns_rdatatype_cname, 0, now,
967 rdataset, sigrdataset);
968 if (result == ISC_R_SUCCESS) {
969 result = DNS_R_CNAME;
970 break;
974 result = DNS_R_NXRRSET;
975 break;
978 if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset))
979 dns_rdataset_disassociate(rdataset);
981 if (foundname != NULL) {
982 isc_result_t xresult;
984 xresult = dns_name_copy(xname, foundname, NULL);
985 if (xresult != ISC_R_SUCCESS) {
986 if (node != NULL)
987 destroynode(node);
988 if (dns_rdataset_isassociated(rdataset))
989 dns_rdataset_disassociate(rdataset);
990 return (DNS_R_BADDB);
994 if (nodep != NULL)
995 *nodep = node;
996 else if (node != NULL)
997 detachnode(db, &node);
999 return (result);
1002 static isc_result_t
1003 find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
1004 dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
1005 dns_dbnode_t **nodep, dns_name_t *foundname,
1006 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
1008 return (findext(db, name, version, type, options, now, nodep,
1009 foundname, NULL, NULL, rdataset, sigrdataset));
1012 static isc_result_t
1013 allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1014 isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
1016 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) db;
1017 sdlz_rdatasetiter_t *iterator;
1019 REQUIRE(VALID_SDLZDB(sdlz));
1021 REQUIRE(version == NULL ||
1022 version == (void*)&sdlz->dummy_version ||
1023 version == sdlz->future_version);
1025 UNUSED(version);
1026 UNUSED(now);
1028 iterator = isc_mem_get(db->mctx, sizeof(sdlz_rdatasetiter_t));
1029 if (iterator == NULL)
1030 return (ISC_R_NOMEMORY);
1032 iterator->common.magic = DNS_RDATASETITER_MAGIC;
1033 iterator->common.methods = &rdatasetiter_methods;
1034 iterator->common.db = db;
1035 iterator->common.node = NULL;
1036 attachnode(db, node, &iterator->common.node);
1037 iterator->common.version = version;
1038 iterator->common.now = now;
1040 *iteratorp = (dns_rdatasetiter_t *)iterator;
1042 return (ISC_R_SUCCESS);
1045 static isc_result_t
1046 modrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1047 dns_rdataset_t *rdataset, unsigned int options,
1048 dns_sdlzmodrdataset_t mod_function)
1050 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1051 dns_master_style_t *style = NULL;
1052 isc_result_t result;
1053 isc_buffer_t *buffer = NULL;
1054 isc_mem_t *mctx;
1055 dns_sdlznode_t *sdlznode;
1056 char *rdatastr = NULL;
1057 char name[DNS_NAME_MAXTEXT + 1];
1059 REQUIRE(VALID_SDLZDB(sdlz));
1061 if (mod_function == NULL)
1062 return (ISC_R_NOTIMPLEMENTED);
1064 sdlznode = (dns_sdlznode_t *)node;
1066 UNUSED(options);
1068 dns_name_format(sdlznode->name, name, sizeof(name));
1070 mctx = sdlz->common.mctx;
1072 result = isc_buffer_allocate(mctx, &buffer, 1024);
1073 if (result != ISC_R_SUCCESS)
1074 return (result);
1076 result = dns_master_stylecreate(&style, 0, 0, 0, 0, 0, 0, 1, mctx);
1077 if (result != ISC_R_SUCCESS)
1078 goto cleanup;
1080 result = dns_master_rdatasettotext(sdlznode->name, rdataset,
1081 style, buffer);
1082 if (result != ISC_R_SUCCESS)
1083 goto cleanup;
1085 if (isc_buffer_usedlength(buffer) < 1) {
1086 result = ISC_R_BADADDRESSFORM;
1087 goto cleanup;
1090 rdatastr = isc_buffer_base(buffer);
1091 if (rdatastr == NULL) {
1092 result = ISC_R_NOMEMORY;
1093 goto cleanup;
1095 rdatastr[isc_buffer_usedlength(buffer) - 1] = 0;
1097 MAYBE_LOCK(sdlz->dlzimp);
1098 result = mod_function(name, rdatastr, sdlz->dlzimp->driverarg,
1099 sdlz->dbdata, version);
1100 MAYBE_UNLOCK(sdlz->dlzimp);
1102 cleanup:
1103 isc_buffer_free(&buffer);
1104 if (style != NULL)
1105 dns_master_styledestroy(&style, mctx);
1107 return (result);
1110 static isc_result_t
1111 addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1112 isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
1113 dns_rdataset_t *addedrdataset)
1115 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1116 isc_result_t result;
1118 UNUSED(now);
1119 UNUSED(addedrdataset);
1120 REQUIRE(VALID_SDLZDB(sdlz));
1122 if (sdlz->dlzimp->methods->addrdataset == NULL)
1123 return (ISC_R_NOTIMPLEMENTED);
1125 result = modrdataset(db, node, version, rdataset, options,
1126 sdlz->dlzimp->methods->addrdataset);
1127 return (result);
1131 static isc_result_t
1132 subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1133 dns_rdataset_t *rdataset, unsigned int options,
1134 dns_rdataset_t *newrdataset)
1136 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1137 isc_result_t result;
1139 UNUSED(newrdataset);
1140 REQUIRE(VALID_SDLZDB(sdlz));
1142 if (sdlz->dlzimp->methods->subtractrdataset == NULL) {
1143 return (ISC_R_NOTIMPLEMENTED);
1146 result = modrdataset(db, node, version, rdataset, options,
1147 sdlz->dlzimp->methods->subtractrdataset);
1148 return (result);
1151 static isc_result_t
1152 deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
1153 dns_rdatatype_t type, dns_rdatatype_t covers)
1155 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1156 char name[DNS_NAME_MAXTEXT + 1];
1157 char b_type[DNS_RDATATYPE_FORMATSIZE];
1158 dns_sdlznode_t *sdlznode;
1159 isc_result_t result;
1161 UNUSED(covers);
1163 REQUIRE(VALID_SDLZDB(sdlz));
1165 if (sdlz->dlzimp->methods->delrdataset == NULL)
1166 return (ISC_R_NOTIMPLEMENTED);
1168 sdlznode = (dns_sdlznode_t *)node;
1169 dns_name_format(sdlznode->name, name, sizeof(name));
1170 dns_rdatatype_format(type, b_type, sizeof(b_type));
1172 MAYBE_LOCK(sdlz->dlzimp);
1173 result = sdlz->dlzimp->methods->delrdataset(name, b_type,
1174 sdlz->dlzimp->driverarg,
1175 sdlz->dbdata, version);
1176 MAYBE_UNLOCK(sdlz->dlzimp);
1178 return (result);
1181 static isc_boolean_t
1182 issecure(dns_db_t *db) {
1183 UNUSED(db);
1185 return (ISC_FALSE);
1188 static unsigned int
1189 nodecount(dns_db_t *db) {
1190 UNUSED(db);
1192 return (0);
1195 static isc_boolean_t
1196 ispersistent(dns_db_t *db) {
1197 UNUSED(db);
1198 return (ISC_TRUE);
1201 static void
1202 overmem(dns_db_t *db, isc_boolean_t overmem) {
1203 UNUSED(db);
1204 UNUSED(overmem);
1207 static void
1208 settask(dns_db_t *db, isc_task_t *task) {
1209 UNUSED(db);
1210 UNUSED(task);
1214 * getoriginnode() is used by the update code to find the
1215 * dns_rdatatype_dnskey record for a zone
1217 static isc_result_t
1218 getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
1219 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
1220 isc_result_t result;
1222 REQUIRE(VALID_SDLZDB(sdlz));
1223 if (sdlz->dlzimp->methods->newversion == NULL)
1224 return (ISC_R_NOTIMPLEMENTED);
1226 result = findnodeext(db, &sdlz->common.origin, ISC_FALSE,
1227 NULL, NULL, nodep);
1228 if (result != ISC_R_SUCCESS)
1229 sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed: %s",
1230 isc_result_totext(result));
1231 return (result);
1234 static dns_dbmethods_t sdlzdb_methods = {
1235 attach,
1236 detach,
1237 beginload,
1238 endload,
1239 NULL,
1240 dump,
1241 currentversion,
1242 newversion,
1243 attachversion,
1244 closeversion,
1245 findnode,
1246 find,
1247 findzonecut,
1248 attachnode,
1249 detachnode,
1250 expirenode,
1251 printnode,
1252 createiterator,
1253 findrdataset,
1254 allrdatasets,
1255 addrdataset,
1256 subtractrdataset,
1257 deleterdataset,
1258 issecure,
1259 nodecount,
1260 ispersistent,
1261 overmem,
1262 settask,
1263 getoriginnode,
1264 NULL, /* transfernode */
1265 NULL, /* getnsec3parameters */
1266 NULL, /* findnsec3node */
1267 NULL, /* setsigningtime */
1268 NULL, /* getsigningtime */
1269 NULL, /* resigned */
1270 NULL, /* isdnssec */
1271 NULL, /* getrrsetstats */
1272 NULL, /* rpz_attach */
1273 NULL, /* rpz_ready */
1274 findnodeext,
1275 findext,
1276 NULL, /* setcachestats */
1277 NULL /* hashsize */
1281 * Database Iterator Methods. These methods were "borrowed" from the SDB
1282 * driver interface. See the SDB driver interface documentation for more info.
1285 static void
1286 dbiterator_destroy(dns_dbiterator_t **iteratorp) {
1287 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)(*iteratorp);
1288 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)sdlziter->common.db;
1290 while (!ISC_LIST_EMPTY(sdlziter->nodelist)) {
1291 dns_sdlznode_t *node;
1292 node = ISC_LIST_HEAD(sdlziter->nodelist);
1293 ISC_LIST_UNLINK(sdlziter->nodelist, node, link);
1294 destroynode(node);
1297 dns_db_detach(&sdlziter->common.db);
1298 isc_mem_put(sdlz->common.mctx, sdlziter, sizeof(sdlz_dbiterator_t));
1300 *iteratorp = NULL;
1303 static isc_result_t
1304 dbiterator_first(dns_dbiterator_t *iterator) {
1305 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1307 sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
1308 if (sdlziter->current == NULL)
1309 return (ISC_R_NOMORE);
1310 else
1311 return (ISC_R_SUCCESS);
1314 static isc_result_t
1315 dbiterator_last(dns_dbiterator_t *iterator) {
1316 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1318 sdlziter->current = ISC_LIST_TAIL(sdlziter->nodelist);
1319 if (sdlziter->current == NULL)
1320 return (ISC_R_NOMORE);
1321 else
1322 return (ISC_R_SUCCESS);
1325 static isc_result_t
1326 dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
1327 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1329 sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
1330 while (sdlziter->current != NULL) {
1331 if (dns_name_equal(sdlziter->current->name, name))
1332 return (ISC_R_SUCCESS);
1333 sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
1335 return (ISC_R_NOTFOUND);
1338 static isc_result_t
1339 dbiterator_prev(dns_dbiterator_t *iterator) {
1340 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1342 sdlziter->current = ISC_LIST_PREV(sdlziter->current, link);
1343 if (sdlziter->current == NULL)
1344 return (ISC_R_NOMORE);
1345 else
1346 return (ISC_R_SUCCESS);
1349 static isc_result_t
1350 dbiterator_next(dns_dbiterator_t *iterator) {
1351 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1353 sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
1354 if (sdlziter->current == NULL)
1355 return (ISC_R_NOMORE);
1356 else
1357 return (ISC_R_SUCCESS);
1360 static isc_result_t
1361 dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
1362 dns_name_t *name)
1364 sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
1366 attachnode(iterator->db, sdlziter->current, nodep);
1367 if (name != NULL)
1368 return (dns_name_copy(sdlziter->current->name, name, NULL));
1369 return (ISC_R_SUCCESS);
1372 static isc_result_t
1373 dbiterator_pause(dns_dbiterator_t *iterator) {
1374 UNUSED(iterator);
1375 return (ISC_R_SUCCESS);
1378 static isc_result_t
1379 dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) {
1380 UNUSED(iterator);
1381 return (dns_name_copy(dns_rootname, name, NULL));
1385 * Rdataset Methods. These methods were "borrowed" from the SDB driver
1386 * interface. See the SDB driver interface documentation for more info.
1389 static void
1390 disassociate(dns_rdataset_t *rdataset) {
1391 dns_dbnode_t *node = rdataset->private5;
1392 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
1393 dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
1395 detachnode(db, &node);
1396 isc__rdatalist_disassociate(rdataset);
1399 static void
1400 rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
1401 dns_dbnode_t *node = source->private5;
1402 dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node;
1403 dns_db_t *db = (dns_db_t *) sdlznode->sdlz;
1404 dns_dbnode_t *tempdb = NULL;
1406 isc__rdatalist_clone(source, target);
1407 attachnode(db, node, &tempdb);
1408 source->private5 = tempdb;
1411 static dns_rdatasetmethods_t rdataset_methods = {
1412 disassociate,
1413 isc__rdatalist_first,
1414 isc__rdatalist_next,
1415 isc__rdatalist_current,
1416 rdataset_clone,
1417 isc__rdatalist_count,
1418 isc__rdatalist_addnoqname,
1419 isc__rdatalist_getnoqname,
1420 NULL,
1421 NULL,
1422 NULL,
1423 NULL,
1424 NULL,
1425 NULL,
1426 NULL,
1427 NULL
1430 static void
1431 list_tordataset(dns_rdatalist_t *rdatalist,
1432 dns_db_t *db, dns_dbnode_t *node,
1433 dns_rdataset_t *rdataset)
1436 * The sdlz rdataset is an rdatalist with some additions.
1437 * - private1 & private2 are used by the rdatalist.
1438 * - private3 & private 4 are unused.
1439 * - private5 is the node.
1442 /* This should never fail. */
1443 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
1444 ISC_R_SUCCESS);
1446 rdataset->methods = &rdataset_methods;
1447 dns_db_attachnode(db, node, &rdataset->private5);
1451 * SDLZ core methods. This is the core of the new DLZ functionality.
1455 * Build a 'bind' database driver structure to be returned by
1456 * either the find zone or the allow zone transfer method.
1457 * This method is only available in this source file, it is
1458 * not made available anywhere else.
1461 static isc_result_t
1462 dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata,
1463 dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp)
1465 isc_result_t result;
1466 dns_sdlz_db_t *sdlzdb;
1467 dns_sdlzimplementation_t *imp;
1469 /* check that things are as we expect */
1470 REQUIRE(dbp != NULL && *dbp == NULL);
1471 REQUIRE(name != NULL);
1473 imp = (dns_sdlzimplementation_t *) driverarg;
1475 /* allocate and zero memory for driver structure */
1476 sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t));
1477 if (sdlzdb == NULL)
1478 return (ISC_R_NOMEMORY);
1479 memset(sdlzdb, 0, sizeof(dns_sdlz_db_t));
1481 /* initialize and set origin */
1482 dns_name_init(&sdlzdb->common.origin, NULL);
1483 result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin);
1484 if (result != ISC_R_SUCCESS)
1485 goto mem_cleanup;
1487 /* initialize the reference count mutex */
1488 result = isc_mutex_init(&sdlzdb->refcnt_lock);
1489 if (result != ISC_R_SUCCESS)
1490 goto name_cleanup;
1492 /* set the rest of the database structure attributes */
1493 sdlzdb->dlzimp = imp;
1494 sdlzdb->common.methods = &sdlzdb_methods;
1495 sdlzdb->common.attributes = 0;
1496 sdlzdb->common.rdclass = rdclass;
1497 sdlzdb->common.mctx = NULL;
1498 sdlzdb->dbdata = dbdata;
1499 sdlzdb->references = 1;
1501 /* attach to the memory context */
1502 isc_mem_attach(mctx, &sdlzdb->common.mctx);
1504 /* mark structure as valid */
1505 sdlzdb->common.magic = DNS_DB_MAGIC;
1506 sdlzdb->common.impmagic = SDLZDB_MAGIC;
1507 *dbp = (dns_db_t *) sdlzdb;
1509 return (result);
1512 * reference count mutex could not be initialized, clean up
1513 * name memory
1515 name_cleanup:
1516 dns_name_free(&sdlzdb->common.origin, mctx);
1517 mem_cleanup:
1518 isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t));
1519 return (result);
1522 static isc_result_t
1523 dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx,
1524 dns_rdataclass_t rdclass, dns_name_t *name,
1525 isc_sockaddr_t *clientaddr, dns_db_t **dbp)
1527 isc_buffer_t b;
1528 isc_buffer_t b2;
1529 char namestr[DNS_NAME_MAXTEXT + 1];
1530 char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")
1531 + 1];
1532 isc_netaddr_t netaddr;
1533 isc_result_t result;
1534 dns_sdlzimplementation_t *imp;
1537 * Perform checks to make sure data is as we expect it to be.
1539 REQUIRE(driverarg != NULL);
1540 REQUIRE(name != NULL);
1541 REQUIRE(clientaddr != NULL);
1542 REQUIRE(dbp != NULL && *dbp == NULL);
1544 imp = (dns_sdlzimplementation_t *) driverarg;
1546 /* Convert DNS name to ascii text */
1547 isc_buffer_init(&b, namestr, sizeof(namestr));
1548 result = dns_name_totext(name, ISC_TRUE, &b);
1549 if (result != ISC_R_SUCCESS)
1550 return (result);
1551 isc_buffer_putuint8(&b, 0);
1553 /* convert client address to ascii text */
1554 isc_buffer_init(&b2, clientstr, sizeof(clientstr));
1555 isc_netaddr_fromsockaddr(&netaddr, clientaddr);
1556 result = isc_netaddr_totext(&netaddr, &b2);
1557 if (result != ISC_R_SUCCESS)
1558 return (result);
1559 isc_buffer_putuint8(&b2, 0);
1561 /* make sure strings are always lowercase */
1562 dns_sdlz_tolower(namestr);
1563 dns_sdlz_tolower(clientstr);
1565 /* Call SDLZ driver's find zone method */
1566 if (imp->methods->allowzonexfr != NULL) {
1567 MAYBE_LOCK(imp);
1568 result = imp->methods->allowzonexfr(imp->driverarg, dbdata,
1569 namestr, clientstr);
1570 MAYBE_UNLOCK(imp);
1572 * if zone is supported and transfers allowed build a 'bind'
1573 * database driver
1575 if (result == ISC_R_SUCCESS)
1576 result = dns_sdlzcreateDBP(mctx, driverarg, dbdata,
1577 name, rdclass, dbp);
1578 return (result);
1581 return (ISC_R_NOTIMPLEMENTED);
1584 static isc_result_t
1585 dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc,
1586 char *argv[], void *driverarg, void **dbdata)
1588 dns_sdlzimplementation_t *imp;
1589 isc_result_t result = ISC_R_NOTFOUND;
1591 /* Write debugging message to log */
1592 sdlz_log(ISC_LOG_DEBUG(2), "Loading SDLZ driver.");
1595 * Performs checks to make sure data is as we expect it to be.
1597 REQUIRE(driverarg != NULL);
1598 REQUIRE(dlzname != NULL);
1599 REQUIRE(dbdata != NULL);
1600 UNUSED(mctx);
1602 imp = driverarg;
1604 /* If the create method exists, call it. */
1605 if (imp->methods->create != NULL) {
1606 MAYBE_LOCK(imp);
1607 result = imp->methods->create(dlzname, argc, argv,
1608 imp->driverarg, dbdata);
1609 MAYBE_UNLOCK(imp);
1612 /* Write debugging message to log */
1613 if (result == ISC_R_SUCCESS) {
1614 sdlz_log(ISC_LOG_DEBUG(2), "SDLZ driver loaded successfully.");
1615 } else {
1616 sdlz_log(ISC_LOG_ERROR, "SDLZ driver failed to load.");
1619 return (result);
1622 static void
1623 dns_sdlzdestroy(void *driverdata, void **dbdata) {
1624 dns_sdlzimplementation_t *imp;
1626 /* Write debugging message to log */
1627 sdlz_log(ISC_LOG_DEBUG(2), "Unloading SDLZ driver.");
1629 imp = driverdata;
1631 /* If the destroy method exists, call it. */
1632 if (imp->methods->destroy != NULL) {
1633 MAYBE_LOCK(imp);
1634 imp->methods->destroy(imp->driverarg, dbdata);
1635 MAYBE_UNLOCK(imp);
1639 static isc_result_t
1640 dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx,
1641 dns_rdataclass_t rdclass, dns_name_t *name,
1642 dns_clientinfomethods_t *methods,
1643 dns_clientinfo_t *clientinfo,
1644 dns_db_t **dbp)
1646 isc_buffer_t b;
1647 char namestr[DNS_NAME_MAXTEXT + 1];
1648 isc_result_t result;
1649 dns_sdlzimplementation_t *imp;
1652 * Perform checks to make sure data is as we expect it to be.
1654 REQUIRE(driverarg != NULL);
1655 REQUIRE(name != NULL);
1656 REQUIRE(dbp != NULL && *dbp == NULL);
1658 imp = (dns_sdlzimplementation_t *) driverarg;
1660 /* Convert DNS name to ascii text */
1661 isc_buffer_init(&b, namestr, sizeof(namestr));
1662 result = dns_name_totext(name, ISC_TRUE, &b);
1663 if (result != ISC_R_SUCCESS)
1664 return (result);
1665 isc_buffer_putuint8(&b, 0);
1667 /* make sure strings are always lowercase */
1668 dns_sdlz_tolower(namestr);
1670 /* Call SDLZ driver's find zone method */
1671 MAYBE_LOCK(imp);
1672 result = imp->methods->findzone(imp->driverarg, dbdata, namestr,
1673 methods, clientinfo);
1674 MAYBE_UNLOCK(imp);
1677 * if zone is supported build a 'bind' database driver
1678 * structure to return
1680 if (result == ISC_R_SUCCESS)
1681 result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name,
1682 rdclass, dbp);
1684 return (result);
1688 static isc_result_t
1689 dns_sdlzconfigure(void *driverarg, void *dbdata,
1690 dns_view_t *view, dns_dlzdb_t *dlzdb)
1692 isc_result_t result;
1693 dns_sdlzimplementation_t *imp;
1695 REQUIRE(driverarg != NULL);
1697 imp = (dns_sdlzimplementation_t *) driverarg;
1699 /* Call SDLZ driver's configure method */
1700 if (imp->methods->configure != NULL) {
1701 MAYBE_LOCK(imp);
1702 result = imp->methods->configure(view, dlzdb,
1703 imp->driverarg, dbdata);
1704 MAYBE_UNLOCK(imp);
1705 } else {
1706 result = ISC_R_SUCCESS;
1709 return (result);
1712 static isc_boolean_t
1713 dns_sdlzssumatch(dns_name_t *signer, dns_name_t *name, isc_netaddr_t *tcpaddr,
1714 dns_rdatatype_t type, const dst_key_t *key, void *driverarg,
1715 void *dbdata)
1717 dns_sdlzimplementation_t *imp;
1718 char b_signer[DNS_NAME_FORMATSIZE];
1719 char b_name[DNS_NAME_FORMATSIZE];
1720 char b_addr[ISC_NETADDR_FORMATSIZE];
1721 char b_type[DNS_RDATATYPE_FORMATSIZE];
1722 char b_key[DST_KEY_FORMATSIZE];
1723 isc_buffer_t *tkey_token = NULL;
1724 isc_region_t token_region;
1725 isc_uint32_t token_len = 0;
1726 isc_boolean_t ret;
1728 REQUIRE(driverarg != NULL);
1730 imp = (dns_sdlzimplementation_t *) driverarg;
1731 if (imp->methods->ssumatch == NULL)
1732 return (ISC_FALSE);
1735 * Format the request elements. sdlz operates on strings, not
1736 * structures
1738 if (signer != NULL)
1739 dns_name_format(signer, b_signer, sizeof(b_signer));
1740 else
1741 b_signer[0] = 0;
1743 dns_name_format(name, b_name, sizeof(b_name));
1745 if (tcpaddr != NULL)
1746 isc_netaddr_format(tcpaddr, b_addr, sizeof(b_addr));
1747 else
1748 b_addr[0] = 0;
1750 dns_rdatatype_format(type, b_type, sizeof(b_type));
1752 if (key != NULL) {
1753 dst_key_format(key, b_key, sizeof(b_key));
1754 tkey_token = dst_key_tkeytoken(key);
1755 } else
1756 b_key[0] = 0;
1758 if (tkey_token != NULL) {
1759 isc_buffer_region(tkey_token, &token_region);
1760 token_len = token_region.length;
1763 MAYBE_LOCK(imp);
1764 ret = imp->methods->ssumatch(b_signer, b_name, b_addr, b_type, b_key,
1765 token_len,
1766 token_len != 0 ? token_region.base : NULL,
1767 imp->driverarg, dbdata);
1768 MAYBE_UNLOCK(imp);
1769 return (ret);
1772 static dns_dlzmethods_t sdlzmethods = {
1773 dns_sdlzcreate,
1774 dns_sdlzdestroy,
1775 dns_sdlzfindzone,
1776 dns_sdlzallowzonexfr,
1777 dns_sdlzconfigure,
1778 dns_sdlzssumatch
1782 * Public functions.
1785 isc_result_t
1786 dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
1787 const char *data)
1789 dns_rdatalist_t *rdatalist;
1790 dns_rdata_t *rdata;
1791 dns_rdatatype_t typeval;
1792 isc_consttextregion_t r;
1793 isc_buffer_t b;
1794 isc_buffer_t *rdatabuf = NULL;
1795 isc_lex_t *lex;
1796 isc_result_t result;
1797 unsigned int size;
1798 isc_mem_t *mctx;
1799 dns_name_t *origin;
1801 REQUIRE(VALID_SDLZLOOKUP(lookup));
1802 REQUIRE(type != NULL);
1803 REQUIRE(data != NULL);
1805 mctx = lookup->sdlz->common.mctx;
1807 r.base = type;
1808 r.length = strlen(type);
1809 result = dns_rdatatype_fromtext(&typeval, (void *) &r);
1810 if (result != ISC_R_SUCCESS)
1811 return (result);
1813 rdatalist = ISC_LIST_HEAD(lookup->lists);
1814 while (rdatalist != NULL) {
1815 if (rdatalist->type == typeval)
1816 break;
1817 rdatalist = ISC_LIST_NEXT(rdatalist, link);
1820 if (rdatalist == NULL) {
1821 rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t));
1822 if (rdatalist == NULL)
1823 return (ISC_R_NOMEMORY);
1824 rdatalist->rdclass = lookup->sdlz->common.rdclass;
1825 rdatalist->type = typeval;
1826 rdatalist->covers = 0;
1827 rdatalist->ttl = ttl;
1828 ISC_LIST_INIT(rdatalist->rdata);
1829 ISC_LINK_INIT(rdatalist, link);
1830 ISC_LIST_APPEND(lookup->lists, rdatalist, link);
1831 } else
1832 if (rdatalist->ttl > ttl) {
1834 * BIND9 doesn't enforce all RRs in an RRset
1835 * having the same TTL, as per RFC 2136,
1836 * section 7.12. If a DLZ backend has
1837 * different TTLs, then the best
1838 * we can do is return the lowest.
1840 rdatalist->ttl = ttl;
1843 rdata = isc_mem_get(mctx, sizeof(dns_rdata_t));
1844 if (rdata == NULL)
1845 return (ISC_R_NOMEMORY);
1846 dns_rdata_init(rdata);
1848 if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
1849 origin = &lookup->sdlz->common.origin;
1850 else
1851 origin = dns_rootname;
1853 lex = NULL;
1854 result = isc_lex_create(mctx, 64, &lex);
1855 if (result != ISC_R_SUCCESS)
1856 goto failure;
1858 size = initial_size(data);
1859 do {
1860 isc_buffer_constinit(&b, data, strlen(data));
1861 isc_buffer_add(&b, strlen(data));
1863 result = isc_lex_openbuffer(lex, &b);
1864 if (result != ISC_R_SUCCESS)
1865 goto failure;
1867 rdatabuf = NULL;
1868 result = isc_buffer_allocate(mctx, &rdatabuf, size);
1869 if (result != ISC_R_SUCCESS)
1870 goto failure;
1872 result = dns_rdata_fromtext(rdata, rdatalist->rdclass,
1873 rdatalist->type, lex,
1874 origin, ISC_FALSE,
1875 mctx, rdatabuf,
1876 &lookup->callbacks);
1877 if (result != ISC_R_SUCCESS)
1878 isc_buffer_free(&rdatabuf);
1879 if (size >= 65535)
1880 break;
1881 size *= 2;
1882 if (size >= 65535)
1883 size = 65535;
1884 } while (result == ISC_R_NOSPACE);
1886 if (result != ISC_R_SUCCESS)
1887 goto failure;
1889 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1890 ISC_LIST_APPEND(lookup->buffers, rdatabuf, link);
1892 if (lex != NULL)
1893 isc_lex_destroy(&lex);
1895 return (ISC_R_SUCCESS);
1897 failure:
1898 if (rdatabuf != NULL)
1899 isc_buffer_free(&rdatabuf);
1900 if (lex != NULL)
1901 isc_lex_destroy(&lex);
1902 isc_mem_put(mctx, rdata, sizeof(dns_rdata_t));
1904 return (result);
1907 isc_result_t
1908 dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name,
1909 const char *type, dns_ttl_t ttl, const char *data)
1911 dns_name_t *newname, *origin;
1912 dns_fixedname_t fnewname;
1913 dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db;
1914 dns_sdlznode_t *sdlznode;
1915 isc_mem_t *mctx = sdlz->common.mctx;
1916 isc_buffer_t b;
1917 isc_result_t result;
1919 dns_fixedname_init(&fnewname);
1920 newname = dns_fixedname_name(&fnewname);
1922 if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0)
1923 origin = &sdlz->common.origin;
1924 else
1925 origin = dns_rootname;
1926 isc_buffer_constinit(&b, name, strlen(name));
1927 isc_buffer_add(&b, strlen(name));
1929 result = dns_name_fromtext(newname, &b, origin, 0, NULL);
1930 if (result != ISC_R_SUCCESS)
1931 return (result);
1933 if (allnodes->common.relative_names) {
1934 /* All names are relative to the root */
1935 unsigned int nlabels = dns_name_countlabels(newname);
1936 dns_name_getlabelsequence(newname, 0, nlabels - 1, newname);
1939 sdlznode = ISC_LIST_HEAD(allnodes->nodelist);
1940 if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) {
1941 sdlznode = NULL;
1942 result = createnode(sdlz, &sdlznode);
1943 if (result != ISC_R_SUCCESS)
1944 return (result);
1945 sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t));
1946 if (sdlznode->name == NULL) {
1947 destroynode(sdlznode);
1948 return (ISC_R_NOMEMORY);
1950 dns_name_init(sdlznode->name, NULL);
1951 result = dns_name_dup(newname, mctx, sdlznode->name);
1952 if (result != ISC_R_SUCCESS) {
1953 isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t));
1954 destroynode(sdlznode);
1955 return (result);
1957 ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link);
1958 if (allnodes->origin == NULL &&
1959 dns_name_equal(newname, &sdlz->common.origin))
1960 allnodes->origin = sdlznode;
1962 return (dns_sdlz_putrr(sdlznode, type, ttl, data));
1966 isc_result_t
1967 dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname,
1968 isc_uint32_t serial)
1970 char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7];
1971 int n;
1973 REQUIRE(mname != NULL);
1974 REQUIRE(rname != NULL);
1976 n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u",
1977 mname, rname, serial,
1978 SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY,
1979 SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM);
1980 if (n >= (int)sizeof(str) || n < 0)
1981 return (ISC_R_NOSPACE);
1982 return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str));
1985 isc_result_t
1986 dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods,
1987 void *driverarg, unsigned int flags, isc_mem_t *mctx,
1988 dns_sdlzimplementation_t **sdlzimp)
1991 dns_sdlzimplementation_t *imp;
1992 isc_result_t result;
1995 * Performs checks to make sure data is as we expect it to be.
1997 REQUIRE(drivername != NULL);
1998 REQUIRE(methods != NULL);
1999 REQUIRE(methods->findzone != NULL);
2000 REQUIRE(methods->lookup != NULL);
2001 REQUIRE(mctx != NULL);
2002 REQUIRE(sdlzimp != NULL && *sdlzimp == NULL);
2003 REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER |
2004 DNS_SDLZFLAG_RELATIVERDATA |
2005 DNS_SDLZFLAG_THREADSAFE)) == 0);
2007 /* Write debugging message to log */
2008 sdlz_log(ISC_LOG_DEBUG(2), "Registering SDLZ driver '%s'", drivername);
2011 * Allocate memory for a sdlz_implementation object. Error if
2012 * we cannot.
2014 imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t));
2015 if (imp == NULL)
2016 return (ISC_R_NOMEMORY);
2018 /* Make sure memory region is set to all 0's */
2019 memset(imp, 0, sizeof(dns_sdlzimplementation_t));
2021 /* Store the data passed into this method */
2022 imp->methods = methods;
2023 imp->driverarg = driverarg;
2024 imp->flags = flags;
2025 imp->mctx = NULL;
2027 /* attach the new sdlz_implementation object to a memory context */
2028 isc_mem_attach(mctx, &imp->mctx);
2031 * initialize the driver lock, error if we cannot
2032 * (used if a driver does not support multiple threads)
2034 result = isc_mutex_init(&imp->driverlock);
2035 if (result != ISC_R_SUCCESS) {
2036 UNEXPECTED_ERROR(__FILE__, __LINE__,
2037 "isc_mutex_init() failed: %s",
2038 isc_result_totext(result));
2039 goto cleanup_mctx;
2042 imp->dlz_imp = NULL;
2045 * register the DLZ driver. Pass in our "extra" sdlz information as
2046 * a driverarg. (that's why we stored the passed in driver arg in our
2047 * sdlz_implementation structure) Also, store the dlz_implementation
2048 * structure in our sdlz_implementation.
2050 result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx,
2051 &imp->dlz_imp);
2053 /* if registration fails, cleanup and get outta here. */
2054 if (result != ISC_R_SUCCESS)
2055 goto cleanup_mutex;
2057 *sdlzimp = imp;
2059 return (ISC_R_SUCCESS);
2061 cleanup_mutex:
2062 /* destroy the driver lock, we don't need it anymore */
2063 DESTROYLOCK(&imp->driverlock);
2065 cleanup_mctx:
2067 * return the memory back to the available memory pool and
2068 * remove it from the memory context.
2070 isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
2071 isc_mem_detach(&mctx);
2072 return (result);
2075 void
2076 dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) {
2077 dns_sdlzimplementation_t *imp;
2078 isc_mem_t *mctx;
2080 /* Write debugging message to log */
2081 sdlz_log(ISC_LOG_DEBUG(2), "Unregistering SDLZ driver.");
2084 * Performs checks to make sure data is as we expect it to be.
2086 REQUIRE(sdlzimp != NULL && *sdlzimp != NULL);
2088 imp = *sdlzimp;
2090 /* Unregister the DLZ driver implementation */
2091 dns_dlzunregister(&imp->dlz_imp);
2093 /* destroy the driver lock, we don't need it anymore */
2094 DESTROYLOCK(&imp->driverlock);
2096 mctx = imp->mctx;
2099 * return the memory back to the available memory pool and
2100 * remove it from the memory context.
2102 isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t));
2103 isc_mem_detach(&mctx);
2105 *sdlzimp = NULL;
2109 isc_result_t
2110 dns_sdlz_setdb(dns_dlzdb_t *dlzdatabase, dns_rdataclass_t rdclass,
2111 dns_name_t *name, dns_db_t **dbp)
2113 isc_result_t result;
2115 result = dns_sdlzcreateDBP(dlzdatabase->mctx,
2116 dlzdatabase->implementation->driverarg,
2117 dlzdatabase->dbdata, name, rdclass, dbp);
2118 return (result);