4 * Portions Copyright (C) 2005-2009 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
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
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: sdlz.c,v 1.22 2009/09/01 00:22:26 jinmei Exp */
62 #include <isc/buffer.h>
65 #include <isc/rwlock.h>
66 #include <isc/string.h>
68 #include <isc/magic.h>
71 #include <isc/print.h>
72 #include <isc/region.h>
74 #include <dns/callbacks.h>
76 #include <dns/dbiterator.h>
78 #include <dns/fixedname.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>
88 #include <dns/types.h>
90 #include "rdatalist_p.h"
96 struct dns_sdlzimplementation
{
97 const dns_sdlzmethods_t
*methods
;
101 isc_mutex_t driverlock
;
102 dns_dlzimplementation_t
*dlz_imp
;
109 dns_sdlzimplementation_t
*dlzimp
;
110 isc_mutex_t refcnt_lock
;
112 unsigned int references
;
115 struct dns_sdlzlookup
{
119 ISC_LIST(dns_rdatalist_t
) lists
;
120 ISC_LIST(isc_buffer_t
) buffers
;
122 ISC_LINK(dns_sdlzlookup_t
) link
;
124 dns_rdatacallbacks_t callbacks
;
126 unsigned int references
;
129 typedef struct dns_sdlzlookup dns_sdlznode_t
;
131 struct dns_sdlzallnodes
{
132 dns_dbiterator_t common
;
133 ISC_LIST(dns_sdlznode_t
) nodelist
;
134 dns_sdlznode_t
*current
;
135 dns_sdlznode_t
*origin
;
138 typedef dns_sdlzallnodes_t sdlz_dbiterator_t
;
140 typedef struct sdlz_rdatasetiter
{
141 dns_rdatasetiter_t common
;
142 dns_rdatalist_t
*current
;
143 } sdlz_rdatasetiter_t
;
146 #define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S')
149 * Note that "impmagic" is not the first four bytes of the struct, so
150 * ISC_MAGIC_VALID cannot be used.
153 #define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \
154 (sdlzdb)->common.impmagic == SDLZDB_MAGIC)
156 #define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L')
157 #define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC)
158 #define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn)
160 /* These values are taken from RFC 1537 */
161 #define SDLZ_DEFAULT_REFRESH (60 * 60 * 8)
162 #define SDLZ_DEFAULT_RETRY (60 * 60 * 2)
163 #define SDLZ_DEFAULT_EXPIRE (60 * 60 * 24 * 7)
164 #define SDLZ_DEFAULT_MINIMUM (60 * 60 * 24)
166 /* This is a reasonable value */
167 #define SDLZ_DEFAULT_TTL (60 * 60 * 24)
172 #define MAYBE_LOCK(imp) LOCK(&imp->driverlock)
173 #define MAYBE_UNLOCK(imp) UNLOCK(&imp->driverlock)
175 #define MAYBE_LOCK(imp) \
177 unsigned int flags = imp->flags; \
178 if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
179 LOCK(&imp->driverlock); \
182 #define MAYBE_UNLOCK(imp) \
184 unsigned int flags = imp->flags; \
185 if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \
186 UNLOCK(&imp->driverlock); \
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
,
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
,
210 static isc_result_t
dbiterator_pause(dns_dbiterator_t
*iterator
);
211 static isc_result_t
dbiterator_origin(dns_dbiterator_t
*iterator
,
214 static dns_dbiteratormethods_t dbiterator_methods
= {
230 /*% Converts the input string to lowercase, in place. */
233 dns_sdlz_tolower(char *str
) {
235 unsigned int len
= strlen(str
);
238 for (i
= 0; i
< len
; i
++) {
239 if (str
[i
] >= 'A' && str
[i
] <= 'Z')
245 static inline unsigned int
246 initial_size(const char *data
) {
247 unsigned int len
= (strlen(data
) / 64) + 1;
248 return (len
* 64 + 64);
252 * Rdataset Iterator Methods. These methods were "borrowed" from the SDB
253 * driver interface. See the SDB driver interface documentation for more info.
257 rdatasetiter_destroy(dns_rdatasetiter_t
**iteratorp
) {
258 sdlz_rdatasetiter_t
*sdlziterator
=
259 (sdlz_rdatasetiter_t
*)(*iteratorp
);
261 detachnode(sdlziterator
->common
.db
, &sdlziterator
->common
.node
);
262 isc_mem_put(sdlziterator
->common
.db
->mctx
, sdlziterator
,
263 sizeof(sdlz_rdatasetiter_t
));
268 rdatasetiter_first(dns_rdatasetiter_t
*iterator
) {
269 sdlz_rdatasetiter_t
*sdlziterator
= (sdlz_rdatasetiter_t
*)iterator
;
270 dns_sdlznode_t
*sdlznode
= (dns_sdlznode_t
*)iterator
->node
;
272 if (ISC_LIST_EMPTY(sdlznode
->lists
))
273 return (ISC_R_NOMORE
);
274 sdlziterator
->current
= ISC_LIST_HEAD(sdlznode
->lists
);
275 return (ISC_R_SUCCESS
);
279 rdatasetiter_next(dns_rdatasetiter_t
*iterator
) {
280 sdlz_rdatasetiter_t
*sdlziterator
= (sdlz_rdatasetiter_t
*)iterator
;
282 sdlziterator
->current
= ISC_LIST_NEXT(sdlziterator
->current
, link
);
283 if (sdlziterator
->current
== NULL
)
284 return (ISC_R_NOMORE
);
286 return (ISC_R_SUCCESS
);
290 rdatasetiter_current(dns_rdatasetiter_t
*iterator
, dns_rdataset_t
*rdataset
) {
291 sdlz_rdatasetiter_t
*sdlziterator
= (sdlz_rdatasetiter_t
*)iterator
;
293 list_tordataset(sdlziterator
->current
, iterator
->db
, iterator
->node
,
297 static dns_rdatasetitermethods_t rdatasetiter_methods
= {
298 rdatasetiter_destroy
,
305 * DB routines. These methods were "borrowed" from the SDB driver interface.
306 * See the SDB driver interface documentation for more info.
310 attach(dns_db_t
*source
, dns_db_t
**targetp
) {
311 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*) source
;
313 REQUIRE(VALID_SDLZDB(sdlz
));
315 LOCK(&sdlz
->refcnt_lock
);
316 REQUIRE(sdlz
->references
> 0);
318 UNLOCK(&sdlz
->refcnt_lock
);
324 destroy(dns_sdlz_db_t
*sdlz
) {
326 mctx
= sdlz
->common
.mctx
;
328 sdlz
->common
.magic
= 0;
329 sdlz
->common
.impmagic
= 0;
331 isc_mutex_destroy(&sdlz
->refcnt_lock
);
333 dns_name_free(&sdlz
->common
.origin
, mctx
);
335 isc_mem_put(mctx
, sdlz
, sizeof(dns_sdlz_db_t
));
336 isc_mem_detach(&mctx
);
340 detach(dns_db_t
**dbp
) {
341 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)(*dbp
);
342 isc_boolean_t need_destroy
= ISC_FALSE
;
344 REQUIRE(VALID_SDLZDB(sdlz
));
345 LOCK(&sdlz
->refcnt_lock
);
346 REQUIRE(sdlz
->references
> 0);
348 if (sdlz
->references
== 0)
349 need_destroy
= ISC_TRUE
;
350 UNLOCK(&sdlz
->refcnt_lock
);
359 beginload(dns_db_t
*db
, dns_addrdatasetfunc_t
*addp
, dns_dbload_t
**dbloadp
) {
363 return (ISC_R_NOTIMPLEMENTED
);
367 endload(dns_db_t
*db
, dns_dbload_t
**dbloadp
) {
370 return (ISC_R_NOTIMPLEMENTED
);
374 dump(dns_db_t
*db
, dns_dbversion_t
*version
, const char *filename
,
375 dns_masterformat_t masterformat
)
380 UNUSED(masterformat
);
381 return (ISC_R_NOTIMPLEMENTED
);
385 currentversion(dns_db_t
*db
, dns_dbversion_t
**versionp
) {
386 REQUIRE(versionp
!= NULL
&& *versionp
== NULL
);
390 *versionp
= (void *) &dummy
;
395 newversion(dns_db_t
*db
, dns_dbversion_t
**versionp
) {
399 return (ISC_R_NOTIMPLEMENTED
);
403 attachversion(dns_db_t
*db
, dns_dbversion_t
*source
,
404 dns_dbversion_t
**targetp
)
406 REQUIRE(source
!= NULL
&& source
== (void *) &dummy
);
415 closeversion(dns_db_t
*db
, dns_dbversion_t
**versionp
, isc_boolean_t commit
) {
416 REQUIRE(versionp
!= NULL
&& *versionp
== (void *) &dummy
);
417 REQUIRE(commit
== ISC_FALSE
);
426 createnode(dns_sdlz_db_t
*sdlz
, dns_sdlznode_t
**nodep
) {
427 dns_sdlznode_t
*node
;
430 node
= isc_mem_get(sdlz
->common
.mctx
, sizeof(dns_sdlznode_t
));
432 return (ISC_R_NOMEMORY
);
435 attach((dns_db_t
*)sdlz
, (dns_db_t
**)&node
->sdlz
);
436 ISC_LIST_INIT(node
->lists
);
437 ISC_LIST_INIT(node
->buffers
);
438 ISC_LINK_INIT(node
, link
);
440 result
= isc_mutex_init(&node
->lock
);
441 if (result
!= ISC_R_SUCCESS
) {
442 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
443 "isc_mutex_init() failed: %s",
444 isc_result_totext(result
));
445 isc_mem_put(sdlz
->common
.mctx
, node
, sizeof(dns_sdlznode_t
));
446 return (ISC_R_UNEXPECTED
);
448 dns_rdatacallbacks_init(&node
->callbacks
);
449 node
->references
= 1;
450 node
->magic
= SDLZLOOKUP_MAGIC
;
453 return (ISC_R_SUCCESS
);
457 destroynode(dns_sdlznode_t
*node
) {
458 dns_rdatalist_t
*list
;
466 mctx
= sdlz
->common
.mctx
;
468 while (!ISC_LIST_EMPTY(node
->lists
)) {
469 list
= ISC_LIST_HEAD(node
->lists
);
470 while (!ISC_LIST_EMPTY(list
->rdata
)) {
471 rdata
= ISC_LIST_HEAD(list
->rdata
);
472 ISC_LIST_UNLINK(list
->rdata
, rdata
, link
);
473 isc_mem_put(mctx
, rdata
, sizeof(dns_rdata_t
));
475 ISC_LIST_UNLINK(node
->lists
, list
, link
);
476 isc_mem_put(mctx
, list
, sizeof(dns_rdatalist_t
));
479 while (!ISC_LIST_EMPTY(node
->buffers
)) {
480 b
= ISC_LIST_HEAD(node
->buffers
);
481 ISC_LIST_UNLINK(node
->buffers
, b
, link
);
485 if (node
->name
!= NULL
) {
486 dns_name_free(node
->name
, mctx
);
487 isc_mem_put(mctx
, node
->name
, sizeof(dns_name_t
));
489 DESTROYLOCK(&node
->lock
);
491 isc_mem_put(mctx
, node
, sizeof(dns_sdlznode_t
));
497 findnode(dns_db_t
*db
, dns_name_t
*name
, isc_boolean_t create
,
498 dns_dbnode_t
**nodep
)
500 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)db
;
501 dns_sdlznode_t
*node
= NULL
;
504 char namestr
[DNS_NAME_MAXTEXT
+ 1];
506 char zonestr
[DNS_NAME_MAXTEXT
+ 1];
507 isc_boolean_t isorigin
;
508 dns_sdlzauthorityfunc_t authority
;
510 REQUIRE(VALID_SDLZDB(sdlz
));
511 REQUIRE(create
== ISC_FALSE
);
512 REQUIRE(nodep
!= NULL
&& *nodep
== NULL
);
517 isc_buffer_init(&b
, namestr
, sizeof(namestr
));
518 if ((sdlz
->dlzimp
->flags
& DNS_SDLZFLAG_RELATIVEOWNER
) != 0) {
522 labels
= dns_name_countlabels(name
) -
523 dns_name_countlabels(&db
->origin
);
524 dns_name_init(&relname
, NULL
);
525 dns_name_getlabelsequence(name
, 0, labels
, &relname
);
526 result
= dns_name_totext(&relname
, ISC_TRUE
, &b
);
527 if (result
!= ISC_R_SUCCESS
)
530 result
= dns_name_totext(name
, ISC_TRUE
, &b
);
531 if (result
!= ISC_R_SUCCESS
)
534 isc_buffer_putuint8(&b
, 0);
536 isc_buffer_init(&b2
, zonestr
, sizeof(zonestr
));
537 result
= dns_name_totext(&sdlz
->common
.origin
, ISC_TRUE
, &b2
);
538 if (result
!= ISC_R_SUCCESS
)
540 isc_buffer_putuint8(&b2
, 0);
542 result
= createnode(sdlz
, &node
);
543 if (result
!= ISC_R_SUCCESS
)
546 isorigin
= dns_name_equal(name
, &sdlz
->common
.origin
);
548 /* make sure strings are always lowercase */
549 dns_sdlz_tolower(zonestr
);
550 dns_sdlz_tolower(namestr
);
552 MAYBE_LOCK(sdlz
->dlzimp
);
554 /* try to lookup the host (namestr) */
555 result
= sdlz
->dlzimp
->methods
->lookup(zonestr
, namestr
,
556 sdlz
->dlzimp
->driverarg
,
560 * if the host (namestr) was not found, try to lookup a
563 if (result
!= ISC_R_SUCCESS
) {
564 result
= sdlz
->dlzimp
->methods
->lookup(zonestr
, "*",
565 sdlz
->dlzimp
->driverarg
,
569 MAYBE_UNLOCK(sdlz
->dlzimp
);
571 if (result
!= ISC_R_SUCCESS
&& !isorigin
) {
576 if (isorigin
&& sdlz
->dlzimp
->methods
->authority
!= NULL
) {
577 MAYBE_LOCK(sdlz
->dlzimp
);
578 authority
= sdlz
->dlzimp
->methods
->authority
;
579 result
= (*authority
)(zonestr
, sdlz
->dlzimp
->driverarg
,
581 MAYBE_UNLOCK(sdlz
->dlzimp
);
582 if (result
!= ISC_R_SUCCESS
&&
583 result
!= ISC_R_NOTIMPLEMENTED
) {
590 return (ISC_R_SUCCESS
);
594 findzonecut(dns_db_t
*db
, dns_name_t
*name
, unsigned int options
,
595 isc_stdtime_t now
, dns_dbnode_t
**nodep
, dns_name_t
*foundname
,
596 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
)
607 return (ISC_R_NOTIMPLEMENTED
);
611 attachnode(dns_db_t
*db
, dns_dbnode_t
*source
, dns_dbnode_t
**targetp
) {
612 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)db
;
613 dns_sdlznode_t
*node
= (dns_sdlznode_t
*)source
;
615 REQUIRE(VALID_SDLZDB(sdlz
));
620 INSIST(node
->references
> 0);
622 INSIST(node
->references
!= 0); /* Catch overflow. */
629 detachnode(dns_db_t
*db
, dns_dbnode_t
**targetp
) {
630 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)db
;
631 dns_sdlznode_t
*node
;
632 isc_boolean_t need_destroy
= ISC_FALSE
;
634 REQUIRE(VALID_SDLZDB(sdlz
));
635 REQUIRE(targetp
!= NULL
&& *targetp
!= NULL
);
639 node
= (dns_sdlznode_t
*)(*targetp
);
642 INSIST(node
->references
> 0);
644 if (node
->references
== 0)
645 need_destroy
= ISC_TRUE
;
655 expirenode(dns_db_t
*db
, dns_dbnode_t
*node
, isc_stdtime_t now
) {
660 return (ISC_R_UNEXPECTED
);
664 printnode(dns_db_t
*db
, dns_dbnode_t
*node
, FILE *out
) {
672 createiterator(dns_db_t
*db
, unsigned int options
, dns_dbiterator_t
**iteratorp
)
674 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)db
;
675 sdlz_dbiterator_t
*sdlziter
;
678 char zonestr
[DNS_NAME_MAXTEXT
+ 1];
680 REQUIRE(VALID_SDLZDB(sdlz
));
682 if (sdlz
->dlzimp
->methods
->allnodes
== NULL
)
683 return (ISC_R_NOTIMPLEMENTED
);
685 if ((options
& DNS_DB_NSEC3ONLY
) != 0 ||
686 (options
& DNS_DB_NONSEC3
) != 0)
687 return (ISC_R_NOTIMPLEMENTED
);
689 isc_buffer_init(&b
, zonestr
, sizeof(zonestr
));
690 result
= dns_name_totext(&sdlz
->common
.origin
, ISC_TRUE
, &b
);
691 if (result
!= ISC_R_SUCCESS
)
693 isc_buffer_putuint8(&b
, 0);
695 sdlziter
= isc_mem_get(sdlz
->common
.mctx
, sizeof(sdlz_dbiterator_t
));
696 if (sdlziter
== NULL
)
697 return (ISC_R_NOMEMORY
);
699 sdlziter
->common
.methods
= &dbiterator_methods
;
700 sdlziter
->common
.db
= NULL
;
701 dns_db_attach(db
, &sdlziter
->common
.db
);
702 sdlziter
->common
.relative_names
= ISC_TF(options
& DNS_DB_RELATIVENAMES
);
703 sdlziter
->common
.magic
= DNS_DBITERATOR_MAGIC
;
704 ISC_LIST_INIT(sdlziter
->nodelist
);
705 sdlziter
->current
= NULL
;
706 sdlziter
->origin
= NULL
;
708 /* make sure strings are always lowercase */
709 dns_sdlz_tolower(zonestr
);
711 MAYBE_LOCK(sdlz
->dlzimp
);
712 result
= sdlz
->dlzimp
->methods
->allnodes(zonestr
,
713 sdlz
->dlzimp
->driverarg
,
714 sdlz
->dbdata
, sdlziter
);
715 MAYBE_UNLOCK(sdlz
->dlzimp
);
716 if (result
!= ISC_R_SUCCESS
) {
717 dns_dbiterator_t
*iter
= &sdlziter
->common
;
718 dbiterator_destroy(&iter
);
722 if (sdlziter
->origin
!= NULL
) {
723 ISC_LIST_UNLINK(sdlziter
->nodelist
, sdlziter
->origin
, link
);
724 ISC_LIST_PREPEND(sdlziter
->nodelist
, sdlziter
->origin
, link
);
727 *iteratorp
= (dns_dbiterator_t
*)sdlziter
;
729 return (ISC_R_SUCCESS
);
733 findrdataset(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
734 dns_rdatatype_t type
, dns_rdatatype_t covers
,
735 isc_stdtime_t now
, dns_rdataset_t
*rdataset
,
736 dns_rdataset_t
*sigrdataset
)
738 dns_rdatalist_t
*list
;
739 dns_sdlznode_t
*sdlznode
= (dns_sdlznode_t
*)node
;
741 REQUIRE(VALID_SDLZNODE(node
));
749 if (type
== dns_rdatatype_sig
|| type
== dns_rdatatype_rrsig
)
750 return (ISC_R_NOTIMPLEMENTED
);
752 list
= ISC_LIST_HEAD(sdlznode
->lists
);
753 while (list
!= NULL
) {
754 if (list
->type
== type
)
756 list
= ISC_LIST_NEXT(list
, link
);
759 return (ISC_R_NOTFOUND
);
761 list_tordataset(list
, db
, node
, rdataset
);
763 return (ISC_R_SUCCESS
);
767 find(dns_db_t
*db
, dns_name_t
*name
, dns_dbversion_t
*version
,
768 dns_rdatatype_t type
, unsigned int options
, isc_stdtime_t now
,
769 dns_dbnode_t
**nodep
, dns_name_t
*foundname
,
770 dns_rdataset_t
*rdataset
, dns_rdataset_t
*sigrdataset
)
772 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)db
;
773 dns_dbnode_t
*node
= NULL
;
774 dns_fixedname_t fname
;
775 dns_rdataset_t xrdataset
;
777 unsigned int nlabels
, olabels
;
781 REQUIRE(VALID_SDLZDB(sdlz
));
782 REQUIRE(nodep
== NULL
|| *nodep
== NULL
);
783 REQUIRE(version
== NULL
|| version
== (void *) &dummy
);
788 if (!dns_name_issubdomain(name
, &db
->origin
))
789 return (DNS_R_NXDOMAIN
);
791 olabels
= dns_name_countlabels(&db
->origin
);
792 nlabels
= dns_name_countlabels(name
);
794 dns_fixedname_init(&fname
);
795 xname
= dns_fixedname_name(&fname
);
797 if (rdataset
== NULL
) {
798 dns_rdataset_init(&xrdataset
);
799 rdataset
= &xrdataset
;
802 result
= DNS_R_NXDOMAIN
;
804 for (i
= olabels
; i
<= nlabels
; i
++) {
806 * Unless this is an explicit lookup at the origin, don't
807 * look at the origin.
809 if (i
== olabels
&& i
!= nlabels
)
813 * Look up the next label.
815 dns_name_getlabelsequence(name
, nlabels
- i
, i
, xname
);
816 result
= findnode(db
, xname
, ISC_FALSE
, &node
);
817 if (result
!= ISC_R_SUCCESS
) {
818 result
= DNS_R_NXDOMAIN
;
823 * Look for a DNAME at the current label, unless this is
827 result
= findrdataset(db
, node
, version
,
829 0, now
, rdataset
, sigrdataset
);
830 if (result
== ISC_R_SUCCESS
) {
831 result
= DNS_R_DNAME
;
837 * Look for an NS at the current label, unless this is the
838 * origin or glue is ok.
840 if (i
!= olabels
&& (options
& DNS_DBFIND_GLUEOK
) == 0) {
841 result
= findrdataset(db
, node
, version
,
843 0, now
, rdataset
, sigrdataset
);
844 if (result
== ISC_R_SUCCESS
) {
845 if (i
== nlabels
&& type
== dns_rdatatype_any
)
847 result
= DNS_R_ZONECUT
;
848 dns_rdataset_disassociate(rdataset
);
849 if (sigrdataset
!= NULL
&&
850 dns_rdataset_isassociated
852 dns_rdataset_disassociate
856 result
= DNS_R_DELEGATION
;
862 * If the current name is not the qname, add another label
872 * If we're looking for ANY, we're done.
874 if (type
== dns_rdatatype_any
) {
875 result
= ISC_R_SUCCESS
;
880 * Look for the qtype.
882 result
= findrdataset(db
, node
, version
, type
,
883 0, now
, rdataset
, sigrdataset
);
884 if (result
== ISC_R_SUCCESS
)
890 if (type
!= dns_rdatatype_cname
) {
891 result
= findrdataset(db
, node
, version
,
893 0, now
, rdataset
, sigrdataset
);
894 if (result
== ISC_R_SUCCESS
) {
895 result
= DNS_R_CNAME
;
900 result
= DNS_R_NXRRSET
;
904 if (rdataset
== &xrdataset
&& dns_rdataset_isassociated(rdataset
))
905 dns_rdataset_disassociate(rdataset
);
907 if (foundname
!= NULL
) {
908 isc_result_t xresult
;
910 xresult
= dns_name_copy(xname
, foundname
, NULL
);
911 if (xresult
!= ISC_R_SUCCESS
) {
914 if (dns_rdataset_isassociated(rdataset
))
915 dns_rdataset_disassociate(rdataset
);
916 return (DNS_R_BADDB
);
922 else if (node
!= NULL
)
923 detachnode(db
, &node
);
929 allrdatasets(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
930 isc_stdtime_t now
, dns_rdatasetiter_t
**iteratorp
)
932 sdlz_rdatasetiter_t
*iterator
;
934 REQUIRE(version
== NULL
|| version
== &dummy
);
939 iterator
= isc_mem_get(db
->mctx
, sizeof(sdlz_rdatasetiter_t
));
940 if (iterator
== NULL
)
941 return (ISC_R_NOMEMORY
);
943 iterator
->common
.magic
= DNS_RDATASETITER_MAGIC
;
944 iterator
->common
.methods
= &rdatasetiter_methods
;
945 iterator
->common
.db
= db
;
946 iterator
->common
.node
= NULL
;
947 attachnode(db
, node
, &iterator
->common
.node
);
948 iterator
->common
.version
= version
;
949 iterator
->common
.now
= now
;
951 *iteratorp
= (dns_rdatasetiter_t
*)iterator
;
953 return (ISC_R_SUCCESS
);
957 addrdataset(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
958 isc_stdtime_t now
, dns_rdataset_t
*rdataset
, unsigned int options
,
959 dns_rdataset_t
*addedrdataset
)
967 UNUSED(addedrdataset
);
969 return (ISC_R_NOTIMPLEMENTED
);
973 subtractrdataset(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
974 dns_rdataset_t
*rdataset
, unsigned int options
,
975 dns_rdataset_t
*newrdataset
)
984 return (ISC_R_NOTIMPLEMENTED
);
988 deleterdataset(dns_db_t
*db
, dns_dbnode_t
*node
, dns_dbversion_t
*version
,
989 dns_rdatatype_t type
, dns_rdatatype_t covers
)
997 return (ISC_R_NOTIMPLEMENTED
);
1000 static isc_boolean_t
1001 issecure(dns_db_t
*db
) {
1008 nodecount(dns_db_t
*db
) {
1014 static isc_boolean_t
1015 ispersistent(dns_db_t
*db
) {
1021 overmem(dns_db_t
*db
, isc_boolean_t overmem
) {
1027 settask(dns_db_t
*db
, isc_task_t
*task
) {
1033 static dns_dbmethods_t sdlzdb_methods
= {
1073 * Database Iterator Methods. These methods were "borrowed" from the SDB
1074 * driver interface. See the SDB driver interface documentation for more info.
1078 dbiterator_destroy(dns_dbiterator_t
**iteratorp
) {
1079 sdlz_dbiterator_t
*sdlziter
= (sdlz_dbiterator_t
*)(*iteratorp
);
1080 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)sdlziter
->common
.db
;
1082 while (!ISC_LIST_EMPTY(sdlziter
->nodelist
)) {
1083 dns_sdlznode_t
*node
;
1084 node
= ISC_LIST_HEAD(sdlziter
->nodelist
);
1085 ISC_LIST_UNLINK(sdlziter
->nodelist
, node
, link
);
1089 dns_db_detach(&sdlziter
->common
.db
);
1090 isc_mem_put(sdlz
->common
.mctx
, sdlziter
, sizeof(sdlz_dbiterator_t
));
1096 dbiterator_first(dns_dbiterator_t
*iterator
) {
1097 sdlz_dbiterator_t
*sdlziter
= (sdlz_dbiterator_t
*)iterator
;
1099 sdlziter
->current
= ISC_LIST_HEAD(sdlziter
->nodelist
);
1100 if (sdlziter
->current
== NULL
)
1101 return (ISC_R_NOMORE
);
1103 return (ISC_R_SUCCESS
);
1107 dbiterator_last(dns_dbiterator_t
*iterator
) {
1108 sdlz_dbiterator_t
*sdlziter
= (sdlz_dbiterator_t
*)iterator
;
1110 sdlziter
->current
= ISC_LIST_TAIL(sdlziter
->nodelist
);
1111 if (sdlziter
->current
== NULL
)
1112 return (ISC_R_NOMORE
);
1114 return (ISC_R_SUCCESS
);
1118 dbiterator_seek(dns_dbiterator_t
*iterator
, dns_name_t
*name
) {
1119 sdlz_dbiterator_t
*sdlziter
= (sdlz_dbiterator_t
*)iterator
;
1121 sdlziter
->current
= ISC_LIST_HEAD(sdlziter
->nodelist
);
1122 while (sdlziter
->current
!= NULL
) {
1123 if (dns_name_equal(sdlziter
->current
->name
, name
))
1124 return (ISC_R_SUCCESS
);
1125 sdlziter
->current
= ISC_LIST_NEXT(sdlziter
->current
, link
);
1127 return (ISC_R_NOTFOUND
);
1131 dbiterator_prev(dns_dbiterator_t
*iterator
) {
1132 sdlz_dbiterator_t
*sdlziter
= (sdlz_dbiterator_t
*)iterator
;
1134 sdlziter
->current
= ISC_LIST_PREV(sdlziter
->current
, link
);
1135 if (sdlziter
->current
== NULL
)
1136 return (ISC_R_NOMORE
);
1138 return (ISC_R_SUCCESS
);
1142 dbiterator_next(dns_dbiterator_t
*iterator
) {
1143 sdlz_dbiterator_t
*sdlziter
= (sdlz_dbiterator_t
*)iterator
;
1145 sdlziter
->current
= ISC_LIST_NEXT(sdlziter
->current
, link
);
1146 if (sdlziter
->current
== NULL
)
1147 return (ISC_R_NOMORE
);
1149 return (ISC_R_SUCCESS
);
1153 dbiterator_current(dns_dbiterator_t
*iterator
, dns_dbnode_t
**nodep
,
1156 sdlz_dbiterator_t
*sdlziter
= (sdlz_dbiterator_t
*)iterator
;
1158 attachnode(iterator
->db
, sdlziter
->current
, nodep
);
1160 return (dns_name_copy(sdlziter
->current
->name
, name
, NULL
));
1161 return (ISC_R_SUCCESS
);
1165 dbiterator_pause(dns_dbiterator_t
*iterator
) {
1167 return (ISC_R_SUCCESS
);
1171 dbiterator_origin(dns_dbiterator_t
*iterator
, dns_name_t
*name
) {
1173 return (dns_name_copy(dns_rootname
, name
, NULL
));
1177 * Rdataset Methods. These methods were "borrowed" from the SDB driver
1178 * interface. See the SDB driver interface documentation for more info.
1182 disassociate(dns_rdataset_t
*rdataset
) {
1183 dns_dbnode_t
*node
= rdataset
->private5
;
1184 dns_sdlznode_t
*sdlznode
= (dns_sdlznode_t
*) node
;
1185 dns_db_t
*db
= (dns_db_t
*) sdlznode
->sdlz
;
1187 detachnode(db
, &node
);
1188 isc__rdatalist_disassociate(rdataset
);
1192 rdataset_clone(dns_rdataset_t
*source
, dns_rdataset_t
*target
) {
1193 dns_dbnode_t
*node
= source
->private5
;
1194 dns_sdlznode_t
*sdlznode
= (dns_sdlznode_t
*) node
;
1195 dns_db_t
*db
= (dns_db_t
*) sdlznode
->sdlz
;
1196 dns_dbnode_t
*tempdb
= NULL
;
1198 isc__rdatalist_clone(source
, target
);
1199 attachnode(db
, node
, &tempdb
);
1200 source
->private5
= tempdb
;
1203 static dns_rdatasetmethods_t rdataset_methods
= {
1205 isc__rdatalist_first
,
1206 isc__rdatalist_next
,
1207 isc__rdatalist_current
,
1209 isc__rdatalist_count
,
1210 isc__rdatalist_addnoqname
,
1211 isc__rdatalist_getnoqname
,
1220 list_tordataset(dns_rdatalist_t
*rdatalist
,
1221 dns_db_t
*db
, dns_dbnode_t
*node
,
1222 dns_rdataset_t
*rdataset
)
1225 * The sdlz rdataset is an rdatalist with some additions.
1226 * - private1 & private2 are used by the rdatalist.
1227 * - private3 & private 4 are unused.
1228 * - private5 is the node.
1231 /* This should never fail. */
1232 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist
, rdataset
) ==
1235 rdataset
->methods
= &rdataset_methods
;
1236 dns_db_attachnode(db
, node
, &rdataset
->private5
);
1240 * SDLZ core methods. This is the core of the new DLZ functionality.
1244 * Build a 'bind' database driver structure to be returned by
1245 * either the find zone or the allow zone transfer method.
1246 * This method is only available in this source file, it is
1247 * not made available anywhere else.
1251 dns_sdlzcreateDBP(isc_mem_t
*mctx
, void *driverarg
, void *dbdata
,
1252 dns_name_t
*name
, dns_rdataclass_t rdclass
, dns_db_t
**dbp
)
1254 isc_result_t result
;
1255 dns_sdlz_db_t
*sdlzdb
;
1256 dns_sdlzimplementation_t
*imp
;
1258 /* check that things are as we expect */
1259 REQUIRE(dbp
!= NULL
&& *dbp
== NULL
);
1260 REQUIRE(name
!= NULL
);
1262 imp
= (dns_sdlzimplementation_t
*) driverarg
;
1264 /* allocate and zero memory for driver structure */
1265 sdlzdb
= isc_mem_get(mctx
, sizeof(dns_sdlz_db_t
));
1267 return (ISC_R_NOMEMORY
);
1268 memset(sdlzdb
, 0, sizeof(dns_sdlz_db_t
));
1270 /* initialize and set origin */
1271 dns_name_init(&sdlzdb
->common
.origin
, NULL
);
1272 result
= dns_name_dupwithoffsets(name
, mctx
, &sdlzdb
->common
.origin
);
1273 if (result
!= ISC_R_SUCCESS
)
1276 /* initialize the reference count mutex */
1277 result
= isc_mutex_init(&sdlzdb
->refcnt_lock
);
1278 if (result
!= ISC_R_SUCCESS
)
1281 /* set the rest of the database structure attributes */
1282 sdlzdb
->dlzimp
= imp
;
1283 sdlzdb
->common
.methods
= &sdlzdb_methods
;
1284 sdlzdb
->common
.attributes
= 0;
1285 sdlzdb
->common
.rdclass
= rdclass
;
1286 sdlzdb
->common
.mctx
= NULL
;
1287 sdlzdb
->dbdata
= dbdata
;
1288 sdlzdb
->references
= 1;
1290 /* attach to the memory context */
1291 isc_mem_attach(mctx
, &sdlzdb
->common
.mctx
);
1293 /* mark structure as valid */
1294 sdlzdb
->common
.magic
= DNS_DB_MAGIC
;
1295 sdlzdb
->common
.impmagic
= SDLZDB_MAGIC
;
1296 *dbp
= (dns_db_t
*) sdlzdb
;
1301 * reference count mutex could not be initialized, clean up
1305 dns_name_free(&sdlzdb
->common
.origin
, mctx
);
1307 isc_mem_put(mctx
, sdlzdb
, sizeof(dns_sdlz_db_t
));
1312 dns_sdlzallowzonexfr(void *driverarg
, void *dbdata
, isc_mem_t
*mctx
,
1313 dns_rdataclass_t rdclass
, dns_name_t
*name
,
1314 isc_sockaddr_t
*clientaddr
, dns_db_t
**dbp
)
1318 char namestr
[DNS_NAME_MAXTEXT
+ 1];
1319 char clientstr
[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")
1321 isc_netaddr_t netaddr
;
1322 isc_result_t result
;
1323 dns_sdlzimplementation_t
*imp
;
1326 * Perform checks to make sure data is as we expect it to be.
1328 REQUIRE(driverarg
!= NULL
);
1329 REQUIRE(name
!= NULL
);
1330 REQUIRE(clientaddr
!= NULL
);
1331 REQUIRE(dbp
!= NULL
&& *dbp
== NULL
);
1333 imp
= (dns_sdlzimplementation_t
*) driverarg
;
1335 /* Convert DNS name to ascii text */
1336 isc_buffer_init(&b
, namestr
, sizeof(namestr
));
1337 result
= dns_name_totext(name
, ISC_TRUE
, &b
);
1338 if (result
!= ISC_R_SUCCESS
)
1340 isc_buffer_putuint8(&b
, 0);
1342 /* convert client address to ascii text */
1343 isc_buffer_init(&b2
, clientstr
, sizeof(clientstr
));
1344 isc_netaddr_fromsockaddr(&netaddr
, clientaddr
);
1345 result
= isc_netaddr_totext(&netaddr
, &b2
);
1346 if (result
!= ISC_R_SUCCESS
)
1348 isc_buffer_putuint8(&b2
, 0);
1350 /* make sure strings are always lowercase */
1351 dns_sdlz_tolower(namestr
);
1352 dns_sdlz_tolower(clientstr
);
1354 /* Call SDLZ driver's find zone method */
1355 if (imp
->methods
->allowzonexfr
!= NULL
) {
1357 result
= imp
->methods
->allowzonexfr(imp
->driverarg
, dbdata
,
1358 namestr
, clientstr
);
1361 * if zone is supported and transfers allowed build a 'bind'
1364 if (result
== ISC_R_SUCCESS
)
1365 result
= dns_sdlzcreateDBP(mctx
, driverarg
, dbdata
,
1366 name
, rdclass
, dbp
);
1370 return (ISC_R_NOTIMPLEMENTED
);
1374 dns_sdlzcreate(isc_mem_t
*mctx
, const char *dlzname
, unsigned int argc
,
1375 char *argv
[], void *driverarg
, void **dbdata
)
1377 dns_sdlzimplementation_t
*imp
;
1378 isc_result_t result
= ISC_R_NOTFOUND
;
1380 /* Write debugging message to log */
1381 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_DATABASE
,
1382 DNS_LOGMODULE_DLZ
, ISC_LOG_DEBUG(2),
1383 "Loading SDLZ driver.");
1386 * Performs checks to make sure data is as we expect it to be.
1388 REQUIRE(driverarg
!= NULL
);
1389 REQUIRE(dlzname
!= NULL
);
1390 REQUIRE(dbdata
!= NULL
);
1395 /* If the create method exists, call it. */
1396 if (imp
->methods
->create
!= NULL
) {
1398 result
= imp
->methods
->create(dlzname
, argc
, argv
,
1399 imp
->driverarg
, dbdata
);
1403 /* Write debugging message to log */
1404 if (result
== ISC_R_SUCCESS
) {
1405 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_DATABASE
,
1406 DNS_LOGMODULE_DLZ
, ISC_LOG_DEBUG(2),
1407 "SDLZ driver loaded successfully.");
1409 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_DATABASE
,
1410 DNS_LOGMODULE_DLZ
, ISC_LOG_ERROR
,
1411 "SDLZ driver failed to load.");
1418 dns_sdlzdestroy(void *driverdata
, void **dbdata
)
1421 dns_sdlzimplementation_t
*imp
;
1423 /* Write debugging message to log */
1424 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_DATABASE
,
1425 DNS_LOGMODULE_DLZ
, ISC_LOG_DEBUG(2),
1426 "Unloading SDLZ driver.");
1430 /* If the destroy method exists, call it. */
1431 if (imp
->methods
->destroy
!= NULL
) {
1433 imp
->methods
->destroy(imp
->driverarg
, dbdata
);
1439 dns_sdlzfindzone(void *driverarg
, void *dbdata
, isc_mem_t
*mctx
,
1440 dns_rdataclass_t rdclass
, dns_name_t
*name
, dns_db_t
**dbp
)
1443 char namestr
[DNS_NAME_MAXTEXT
+ 1];
1444 isc_result_t result
;
1445 dns_sdlzimplementation_t
*imp
;
1448 * Perform checks to make sure data is as we expect it to be.
1450 REQUIRE(driverarg
!= NULL
);
1451 REQUIRE(name
!= NULL
);
1452 REQUIRE(dbp
!= NULL
&& *dbp
== NULL
);
1454 imp
= (dns_sdlzimplementation_t
*) driverarg
;
1456 /* Convert DNS name to ascii text */
1457 isc_buffer_init(&b
, namestr
, sizeof(namestr
));
1458 result
= dns_name_totext(name
, ISC_TRUE
, &b
);
1459 if (result
!= ISC_R_SUCCESS
)
1461 isc_buffer_putuint8(&b
, 0);
1463 /* make sure strings are always lowercase */
1464 dns_sdlz_tolower(namestr
);
1466 /* Call SDLZ driver's find zone method */
1468 result
= imp
->methods
->findzone(imp
->driverarg
, dbdata
, namestr
);
1472 * if zone is supported build a 'bind' database driver
1473 * structure to return
1475 if (result
== ISC_R_SUCCESS
)
1476 result
= dns_sdlzcreateDBP(mctx
, driverarg
, dbdata
, name
,
1482 static dns_dlzmethods_t sdlzmethods
= {
1486 dns_sdlzallowzonexfr
1494 dns_sdlz_putrr(dns_sdlzlookup_t
*lookup
, const char *type
, dns_ttl_t ttl
,
1497 dns_rdatalist_t
*rdatalist
;
1499 dns_rdatatype_t typeval
;
1500 isc_consttextregion_t r
;
1502 isc_buffer_t
*rdatabuf
= NULL
;
1504 isc_result_t result
;
1509 REQUIRE(VALID_SDLZLOOKUP(lookup
));
1510 REQUIRE(type
!= NULL
);
1511 REQUIRE(data
!= NULL
);
1513 mctx
= lookup
->sdlz
->common
.mctx
;
1516 r
.length
= strlen(type
);
1517 result
= dns_rdatatype_fromtext(&typeval
, (void *) &r
);
1518 if (result
!= ISC_R_SUCCESS
)
1521 rdatalist
= ISC_LIST_HEAD(lookup
->lists
);
1522 while (rdatalist
!= NULL
) {
1523 if (rdatalist
->type
== typeval
)
1525 rdatalist
= ISC_LIST_NEXT(rdatalist
, link
);
1528 if (rdatalist
== NULL
) {
1529 rdatalist
= isc_mem_get(mctx
, sizeof(dns_rdatalist_t
));
1530 if (rdatalist
== NULL
)
1531 return (ISC_R_NOMEMORY
);
1532 rdatalist
->rdclass
= lookup
->sdlz
->common
.rdclass
;
1533 rdatalist
->type
= typeval
;
1534 rdatalist
->covers
= 0;
1535 rdatalist
->ttl
= ttl
;
1536 ISC_LIST_INIT(rdatalist
->rdata
);
1537 ISC_LINK_INIT(rdatalist
, link
);
1538 ISC_LIST_APPEND(lookup
->lists
, rdatalist
, link
);
1540 if (rdatalist
->ttl
!= ttl
)
1541 return (DNS_R_BADTTL
);
1543 rdata
= isc_mem_get(mctx
, sizeof(dns_rdata_t
));
1545 return (ISC_R_NOMEMORY
);
1546 dns_rdata_init(rdata
);
1548 if ((lookup
->sdlz
->dlzimp
->flags
& DNS_SDLZFLAG_RELATIVERDATA
) != 0)
1549 origin
= &lookup
->sdlz
->common
.origin
;
1551 origin
= dns_rootname
;
1554 result
= isc_lex_create(mctx
, 64, &lex
);
1555 if (result
!= ISC_R_SUCCESS
)
1558 size
= initial_size(data
);
1560 isc_buffer_init(&b
, data
, strlen(data
));
1561 isc_buffer_add(&b
, strlen(data
));
1563 result
= isc_lex_openbuffer(lex
, &b
);
1564 if (result
!= ISC_R_SUCCESS
)
1568 result
= isc_buffer_allocate(mctx
, &rdatabuf
, size
);
1569 if (result
!= ISC_R_SUCCESS
)
1572 result
= dns_rdata_fromtext(rdata
, rdatalist
->rdclass
,
1573 rdatalist
->type
, lex
,
1576 &lookup
->callbacks
);
1577 if (result
!= ISC_R_SUCCESS
)
1578 isc_buffer_free(&rdatabuf
);
1580 } while (result
== ISC_R_NOSPACE
);
1582 if (result
!= ISC_R_SUCCESS
)
1585 ISC_LIST_APPEND(rdatalist
->rdata
, rdata
, link
);
1586 ISC_LIST_APPEND(lookup
->buffers
, rdatabuf
, link
);
1589 isc_lex_destroy(&lex
);
1591 return (ISC_R_SUCCESS
);
1594 if (rdatabuf
!= NULL
)
1595 isc_buffer_free(&rdatabuf
);
1597 isc_lex_destroy(&lex
);
1598 isc_mem_put(mctx
, rdata
, sizeof(dns_rdata_t
));
1604 dns_sdlz_putnamedrr(dns_sdlzallnodes_t
*allnodes
, const char *name
,
1605 const char *type
, dns_ttl_t ttl
, const char *data
)
1607 dns_name_t
*newname
, *origin
;
1608 dns_fixedname_t fnewname
;
1609 dns_sdlz_db_t
*sdlz
= (dns_sdlz_db_t
*)allnodes
->common
.db
;
1610 dns_sdlznode_t
*sdlznode
;
1611 isc_mem_t
*mctx
= sdlz
->common
.mctx
;
1613 isc_result_t result
;
1615 dns_fixedname_init(&fnewname
);
1616 newname
= dns_fixedname_name(&fnewname
);
1618 if ((sdlz
->dlzimp
->flags
& DNS_SDLZFLAG_RELATIVERDATA
) != 0)
1619 origin
= &sdlz
->common
.origin
;
1621 origin
= dns_rootname
;
1622 isc_buffer_init(&b
, name
, strlen(name
));
1623 isc_buffer_add(&b
, strlen(name
));
1625 result
= dns_name_fromtext(newname
, &b
, origin
, 0, NULL
);
1626 if (result
!= ISC_R_SUCCESS
)
1629 if (allnodes
->common
.relative_names
) {
1630 /* All names are relative to the root */
1631 unsigned int nlabels
= dns_name_countlabels(newname
);
1632 dns_name_getlabelsequence(newname
, 0, nlabels
- 1, newname
);
1635 sdlznode
= ISC_LIST_HEAD(allnodes
->nodelist
);
1636 if (sdlznode
== NULL
|| !dns_name_equal(sdlznode
->name
, newname
)) {
1638 result
= createnode(sdlz
, &sdlznode
);
1639 if (result
!= ISC_R_SUCCESS
)
1641 sdlznode
->name
= isc_mem_get(mctx
, sizeof(dns_name_t
));
1642 if (sdlznode
->name
== NULL
) {
1643 destroynode(sdlznode
);
1644 return (ISC_R_NOMEMORY
);
1646 dns_name_init(sdlznode
->name
, NULL
);
1647 result
= dns_name_dup(newname
, mctx
, sdlznode
->name
);
1648 if (result
!= ISC_R_SUCCESS
) {
1649 isc_mem_put(mctx
, sdlznode
->name
, sizeof(dns_name_t
));
1650 destroynode(sdlznode
);
1653 ISC_LIST_PREPEND(allnodes
->nodelist
, sdlznode
, link
);
1654 if (allnodes
->origin
== NULL
&&
1655 dns_name_equal(newname
, &sdlz
->common
.origin
))
1656 allnodes
->origin
= sdlznode
;
1658 return (dns_sdlz_putrr(sdlznode
, type
, ttl
, data
));
1663 dns_sdlz_putsoa(dns_sdlzlookup_t
*lookup
, const char *mname
, const char *rname
,
1664 isc_uint32_t serial
)
1666 char str
[2 * DNS_NAME_MAXTEXT
+ 5 * (sizeof("2147483647")) + 7];
1669 REQUIRE(mname
!= NULL
);
1670 REQUIRE(rname
!= NULL
);
1672 n
= snprintf(str
, sizeof str
, "%s %s %u %u %u %u %u",
1673 mname
, rname
, serial
,
1674 SDLZ_DEFAULT_REFRESH
, SDLZ_DEFAULT_RETRY
,
1675 SDLZ_DEFAULT_EXPIRE
, SDLZ_DEFAULT_MINIMUM
);
1676 if (n
>= (int)sizeof(str
) || n
< 0)
1677 return (ISC_R_NOSPACE
);
1678 return (dns_sdlz_putrr(lookup
, "SOA", SDLZ_DEFAULT_TTL
, str
));
1682 dns_sdlzregister(const char *drivername
, const dns_sdlzmethods_t
*methods
,
1683 void *driverarg
, unsigned int flags
, isc_mem_t
*mctx
,
1684 dns_sdlzimplementation_t
**sdlzimp
)
1687 dns_sdlzimplementation_t
*imp
;
1688 isc_result_t result
;
1691 * Performs checks to make sure data is as we expect it to be.
1693 REQUIRE(drivername
!= NULL
);
1694 REQUIRE(methods
!= NULL
);
1695 REQUIRE(methods
->findzone
!= NULL
);
1696 REQUIRE(methods
->lookup
!= NULL
);
1697 REQUIRE(mctx
!= NULL
);
1698 REQUIRE(sdlzimp
!= NULL
&& *sdlzimp
== NULL
);
1699 REQUIRE((flags
& ~(DNS_SDLZFLAG_RELATIVEOWNER
|
1700 DNS_SDLZFLAG_RELATIVERDATA
|
1701 DNS_SDLZFLAG_THREADSAFE
)) == 0);
1703 /* Write debugging message to log */
1704 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_DATABASE
,
1705 DNS_LOGMODULE_DLZ
, ISC_LOG_DEBUG(2),
1706 "Registering SDLZ driver '%s'", drivername
);
1709 * Allocate memory for a sdlz_implementation object. Error if
1712 imp
= isc_mem_get(mctx
, sizeof(dns_sdlzimplementation_t
));
1714 return (ISC_R_NOMEMORY
);
1716 /* Make sure memory region is set to all 0's */
1717 memset(imp
, 0, sizeof(dns_sdlzimplementation_t
));
1719 /* Store the data passed into this method */
1720 imp
->methods
= methods
;
1721 imp
->driverarg
= driverarg
;
1725 /* attach the new sdlz_implementation object to a memory context */
1726 isc_mem_attach(mctx
, &imp
->mctx
);
1729 * initialize the driver lock, error if we cannot
1730 * (used if a driver does not support multiple threads)
1732 result
= isc_mutex_init(&imp
->driverlock
);
1733 if (result
!= ISC_R_SUCCESS
) {
1734 UNEXPECTED_ERROR(__FILE__
, __LINE__
,
1735 "isc_mutex_init() failed: %s",
1736 isc_result_totext(result
));
1740 imp
->dlz_imp
= NULL
;
1743 * register the DLZ driver. Pass in our "extra" sdlz information as
1744 * a driverarg. (that's why we stored the passed in driver arg in our
1745 * sdlz_implementation structure) Also, store the dlz_implementation
1746 * structure in our sdlz_implementation.
1748 result
= dns_dlzregister(drivername
, &sdlzmethods
, imp
, mctx
,
1751 /* if registration fails, cleanup and get outta here. */
1752 if (result
!= ISC_R_SUCCESS
)
1757 return (ISC_R_SUCCESS
);
1760 /* destroy the driver lock, we don't need it anymore */
1761 DESTROYLOCK(&imp
->driverlock
);
1765 * return the memory back to the available memory pool and
1766 * remove it from the memory context.
1768 isc_mem_put(mctx
, imp
, sizeof(dns_sdlzimplementation_t
));
1769 isc_mem_detach(&mctx
);
1774 dns_sdlzunregister(dns_sdlzimplementation_t
**sdlzimp
) {
1775 dns_sdlzimplementation_t
*imp
;
1778 /* Write debugging message to log */
1779 isc_log_write(dns_lctx
, DNS_LOGCATEGORY_DATABASE
,
1780 DNS_LOGMODULE_DLZ
, ISC_LOG_DEBUG(2),
1781 "Unregistering SDLZ driver.");
1784 * Performs checks to make sure data is as we expect it to be.
1786 REQUIRE(sdlzimp
!= NULL
&& *sdlzimp
!= NULL
);
1790 /* Unregister the DLZ driver implementation */
1791 dns_dlzunregister(&imp
->dlz_imp
);
1793 /* destroy the driver lock, we don't need it anymore */
1794 DESTROYLOCK(&imp
->driverlock
);
1799 * return the memory back to the available memory pool and
1800 * remove it from the memory context.
1802 isc_mem_put(mctx
, imp
, sizeof(dns_sdlzimplementation_t
));
1803 isc_mem_detach(&mctx
);