1 /* $NetBSD: dlz_bdbhpt_dynamic.c,v 1.1.1.5 2015/07/08 15:37:45 christos Exp $ */
4 * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all
11 * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
12 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
13 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14 * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
15 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
16 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
17 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
18 * USE OR PERFORMANCE OF THIS SOFTWARE.
20 * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
21 * conceived and contributed by Rob Butler.
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 ROB BUTLER
29 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
31 * ROB BUTLER 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.
39 * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
41 * Permission to use, copy, modify, and/or distribute this software for any
42 * purpose with or without fee is hereby granted, provided that the above
43 * copyright notice and this permission notice appear in all copies.
45 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
46 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
47 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
48 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
49 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
50 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
51 * PERFORMANCE OF THIS SOFTWARE.
55 * This is simply a merge of Andrew Tridgell's dlz_example.c and the
56 * original bdb_bdbhpt_driver.c
58 * This provides the externally loadable bdbhpt DLZ driver, without
71 #include "dlz_minimal.h"
73 /* should the bdb driver use threads. */
74 #ifdef ISC_PLATFORM_USETHREADS
75 #define bdbhpt_threads DB_THREAD
77 #define bdbhpt_threads 0
80 /* bdbhpt database names */
81 #define dlz_data "dns_data"
82 #define dlz_zone "dns_zone"
83 #define dlz_xfr "dns_xfr"
84 #define dlz_client "dns_client"
86 #define dlz_bdbhpt_dynamic_version "0.1"
89 * This structure contains all our DB handles and helper functions we
90 * inherit from the dlz_dlopen driver
93 typedef struct bdbhpt_instance
{
94 DB_ENV
*dbenv
; /* bdbhpt environment */
95 DB
*data
; /* dns_data database handle */
96 DB
*zone
; /* zone database handle */
97 DB
*xfr
; /* zone xfr database handle */
98 DB
*client
; /* client database handle */
100 /* Helper functions from the dlz_dlopen driver */
102 dns_sdlz_putrr_t
*putrr
;
103 dns_sdlz_putnamedrr_t
*putnamedrr
;
104 dns_dlz_writeablezone_t
*writeable_zone
;
107 typedef struct bdbhpt_parsed_data
{
112 } bdbhpt_parsed_data_t
;
115 b9_add_helper(struct bdbhpt_instance
*db
, const char *helper_name
, void *ptr
);
118 * Reverses a string in place.
121 *bdbhpt_strrev(char *str
) {
126 for (p1
= str
, p2
= str
+ strlen(str
) - 1; p2
> p1
; ++p1
, --p2
) {
135 * Parses the DBT from the Berkeley DB into a parsed_data record
136 * The parsed_data record should be allocated before and passed into the
137 * bdbhpt_parse_data function. The char (type & data) fields should not
138 * be "free"d as that memory is part of the DBT data field. It will be
139 * "free"d when the DBT is freed.
143 bdbhpt_parse_data(log_t
*log
, char *in
, bdbhpt_parsed_data_t
*pd
) {
147 char *lastchar
= (char *) &tmp
[strlen(tmp
)];
150 * String should be formatted as:
163 * 9191 host 10 A 127.0.0.1
164 * server1_212 host 10 A 127.0.0.2
165 * {xxxx-xxxx-xxxx-xxxx-xxxx} host 10 MX 20 mail.example.com
169 * we don't need the replication id, so don't
170 * bother saving a pointer to it.
173 /* find space after replication id */
174 tmp
= strchr(tmp
, ' ');
175 /* verify we found a space */
177 return ISC_R_FAILURE
;
178 /* make sure it is safe to increment pointer */
179 if (++tmp
> lastchar
)
180 return ISC_R_FAILURE
;
182 /* save pointer to host */
185 /* find space after host and change it to a '\0' */
186 tmp
= strchr(tmp
, ' ');
187 /* verify we found a space */
189 return ISC_R_FAILURE
;
190 /* change the space to a null (string terminator) */
192 /* make sure it is safe to increment pointer */
193 if (++tmp
> lastchar
)
194 return ISC_R_FAILURE
;
196 /* save pointer to ttl string */
199 /* find space after ttl and change it to a '\0' */
200 tmp
= strchr(tmp
, ' ');
201 /* verify we found a space */
203 return ISC_R_FAILURE
;
204 /* change the space to a null (string terminator) */
206 /* make sure it is safe to increment pointer */
207 if (++tmp
> lastchar
)
208 return ISC_R_FAILURE
;
210 /* save pointer to dns type */
213 /* find space after type and change it to a '\0' */
214 tmp
= strchr(tmp
, ' ');
215 /* verify we found a space */
217 return ISC_R_FAILURE
;
218 /* change the space to a null (string terminator) */
220 /* make sure it is safe to increment pointer */
221 if (++tmp
> lastchar
)
222 return ISC_R_FAILURE
;
224 /* save pointer to remainder of DNS data */
227 /* convert ttl string to integer */
228 pd
->ttl
= strtol(ttlStr
, &endp
, 10);
229 if (*endp
!= '\0' || pd
->ttl
< 0) {
232 "ttl must be a positive number");
233 return ISC_R_FAILURE
;
236 /* if we get this far everything should have worked. */
237 return ISC_R_SUCCESS
;
241 * See if a zone transfer is allowed
244 dlz_allowzonexfr(void *dbdata
, const char *name
, const char *client
) {
246 bdbhpt_instance_t
*db
= (bdbhpt_instance_t
*) dbdata
;
249 /* check to see if we are authoritative for the zone first. */
250 #if DLZ_DLOPEN_VERSION >= 3
251 result
= dlz_findzonedb(dbdata
, name
, NULL
, NULL
);
253 result
= dlz_findzonedb(dbdata
, name
);
255 if (result
!= ISC_R_SUCCESS
)
256 return (ISC_R_NOTFOUND
);
258 memset(&key
, 0, sizeof(DBT
));
259 key
.flags
= DB_DBT_MALLOC
;
260 key
.data
= strdup(name
);
261 if (key
.data
== NULL
) {
262 result
= ISC_R_NOMEMORY
;
265 key
.size
= strlen(key
.data
);
267 memset(&data
, 0, sizeof(DBT
));
268 data
.flags
= DB_DBT_MALLOC
;
269 data
.data
= strdup(client
);
270 if (data
.data
== NULL
) {
271 result
= ISC_R_NOMEMORY
;
274 data
.size
= strlen(data
.data
);
276 switch(db
->client
->get(db
->client
, NULL
, &key
, &data
, DB_GET_BOTH
)) {
278 result
= ISC_R_NOTFOUND
;
281 result
= ISC_R_SUCCESS
;
284 result
= ISC_R_FAILURE
;
288 /* free any memory duplicate string in the key field */
289 if (key
.data
!= NULL
)
292 /* free any memory allocated to the data field. */
293 if (data
.data
!= NULL
)
300 * Perform a zone transfer
302 * BDB does not allow a secondary index on a database that allows
303 * duplicates. We have a few options:
305 * 1) kill speed by having lookup method use a secondary db which
306 * is associated to the primary DB with the DNS data. Then have
307 * another secondary db for zone transfer which also points to
308 * the dns_data primary. NO - The point of this driver is
309 * lookup performance.
311 * 2) Blow up database size by storing DNS data twice. Once for
312 * the lookup (dns_data) database, and a second time for the zone
313 * transfer (dns_xfr) database. NO - That would probably require
314 * a larger cache to provide good performance. Also, that would
315 * make the DB larger on disk potentially slowing it as well.
317 * 3) Loop through the dns_xfr database with a cursor to get
318 * all the different hosts in a zone. Then use the zone & host
319 * together to lookup the data in the dns_data database. YES -
320 * This may slow down zone xfr's a little, but that's ok they
321 * don't happen as often and don't need to be as fast. We can
322 * also use this table when deleting a zone (The BDB driver
323 * is read only - the delete would be used during replication
324 * updates by a separate process).
327 dlz_allnodes(const char *zone
, void *dbdata
, dns_sdlzallnodes_t
*allnodes
) {
328 isc_result_t result
= ISC_R_NOTFOUND
;
329 bdbhpt_instance_t
*db
= (bdbhpt_instance_t
*) dbdata
;
330 DBC
*xfr_cursor
= NULL
;
331 DBC
*dns_cursor
= NULL
;
332 DBT xfr_key
, xfr_data
, dns_key
, dns_data
;
336 bdbhpt_parsed_data_t pd
;
337 char *tmp
= NULL
, *tmp_zone
, *tmp_zone_host
= NULL
;
339 memset(&xfr_key
, 0, sizeof(DBT
));
340 memset(&xfr_data
, 0, sizeof(DBT
));
341 memset(&dns_key
, 0, sizeof(DBT
));
342 memset(&dns_data
, 0, sizeof(DBT
));
344 xfr_key
.data
= tmp_zone
= strdup(zone
);
345 if (xfr_key
.data
== NULL
)
346 return (ISC_R_NOMEMORY
);
348 xfr_key
.size
= strlen(xfr_key
.data
);
350 /* get a cursor to loop through dns_xfr table */
351 if (db
->xfr
->cursor(db
->xfr
, NULL
, &xfr_cursor
, 0) != 0) {
352 result
= ISC_R_FAILURE
;
353 goto allnodes_cleanup
;
356 /* get a cursor to loop through dns_data table */
357 if (db
->data
->cursor(db
->data
, NULL
, &dns_cursor
, 0) != 0) {
358 result
= ISC_R_FAILURE
;
359 goto allnodes_cleanup
;
364 /* loop through xfr table for specified zone. */
365 while ((bdbhptres
= xfr_cursor
->c_get(xfr_cursor
, &xfr_key
,
366 &xfr_data
, xfr_flags
)) == 0)
368 xfr_flags
= DB_NEXT_DUP
;
370 /* +1 to allow for space between zone and host names */
371 dns_key
.size
= xfr_data
.size
+ xfr_key
.size
+ 1;
373 /* +1 to allow for null term at end of string. */
374 dns_key
.data
= tmp_zone_host
= malloc(dns_key
.size
+ 1);
375 if (dns_key
.data
== NULL
)
376 goto allnodes_cleanup
;
379 * construct search key for dns_data.
380 * zone_name(a space)host_name
382 strcpy(dns_key
.data
, zone
);
383 strcat(dns_key
.data
, " ");
384 strncat(dns_key
.data
, xfr_data
.data
, xfr_data
.size
);
388 while ((bdbhptres
= dns_cursor
->c_get(dns_cursor
,
393 dns_flags
= DB_NEXT_DUP
;
395 /* +1 to allow for null term at end of string. */
396 tmp
= realloc(tmp
, dns_data
.size
+ 1);
398 goto allnodes_cleanup
;
400 /* copy data to tmp string, and append null term. */
401 strncpy(tmp
, dns_data
.data
, dns_data
.size
);
402 tmp
[dns_data
.size
] = '\0';
404 /* split string into dns data parts. */
405 if (bdbhpt_parse_data(db
->log
,
406 tmp
, &pd
) != ISC_R_SUCCESS
)
407 goto allnodes_cleanup
;
408 result
= db
->putnamedrr(allnodes
, pd
.host
,
409 pd
.type
, pd
.ttl
, pd
.data
);
410 if (result
!= ISC_R_SUCCESS
)
411 goto allnodes_cleanup
;
413 } /* end inner while loop */
415 /* clean up memory */
416 if (tmp_zone_host
!= NULL
) {
418 tmp_zone_host
= NULL
;
420 } /* end outer while loop */
423 /* free any memory */
427 if (tmp_zone_host
!= NULL
)
430 if (tmp_zone
!= NULL
)
433 /* get rid of cursors */
434 if (xfr_cursor
!= NULL
)
435 xfr_cursor
->c_close(xfr_cursor
);
437 if (dns_cursor
!= NULL
)
438 dns_cursor
->c_close(dns_cursor
);
444 * Performs bdbhpt cleanup.
445 * Used by bdbhpt_create if there is an error starting up.
446 * Used by bdbhpt_destroy when the driver is shutting down.
449 bdbhpt_cleanup(bdbhpt_instance_t
*db
) {
450 /* close databases */
451 if (db
->data
!= NULL
)
452 db
->data
->close(db
->data
, 0);
454 db
->xfr
->close(db
->xfr
, 0);
455 if (db
->zone
!= NULL
)
456 db
->zone
->close(db
->zone
, 0);
457 if (db
->client
!= NULL
)
458 db
->client
->close(db
->client
, 0);
460 /* close environment */
461 if (db
->dbenv
!= NULL
)
462 db
->dbenv
->close(db
->dbenv
, 0);
466 * See if we handle a given zone
468 #if DLZ_DLOPEN_VERSION < 3
470 dlz_findzonedb(void *dbdata
, const char *name
)
473 dlz_findzonedb(void *dbdata
, const char *name
,
474 dns_clientinfomethods_t
*methods
,
475 dns_clientinfo_t
*clientinfo
)
479 bdbhpt_instance_t
*db
= (bdbhpt_instance_t
*) dbdata
;
482 memset(&key
, 0, sizeof(DBT
));
483 memset(&data
, 0, sizeof(DBT
));
484 data
.flags
= DB_DBT_MALLOC
;
486 #if DLZ_DLOPEN_VERSION >= 3
491 key
.data
= strdup(name
);
493 if (key
.data
== NULL
)
494 return (ISC_R_NOMEMORY
);
497 * reverse string to take advantage of BDB locality of reference
498 * if we need futher lookups because the zone doesn't match the
501 key
.data
= bdbhpt_strrev(key
.data
);
502 key
.size
= strlen(key
.data
);
504 switch(db
->zone
->get(db
->zone
, NULL
, &key
, &data
, 0)) {
506 result
= ISC_R_NOTFOUND
;
509 result
= ISC_R_SUCCESS
;
512 result
= ISC_R_FAILURE
;
515 /* free any memory duplicate string in the key field */
516 if (key
.data
!= NULL
)
519 /* free any memory allocated to the data field. */
520 if (data
.data
!= NULL
)
527 * Look up one record in the database.
530 #if DLZ_DLOPEN_VERSION == 1
531 isc_result_t
dlz_lookup(const char *zone
, const char *name
,
532 void *dbdata
, dns_sdlzlookup_t
*lookup
)
534 isc_result_t
dlz_lookup(const char *zone
, const char *name
, void *dbdata
,
535 dns_sdlzlookup_t
*lookup
,
536 dns_clientinfomethods_t
*methods
,
537 dns_clientinfo_t
*clientinfo
)
540 isc_result_t result
= ISC_R_NOTFOUND
;
541 bdbhpt_instance_t
*db
= (bdbhpt_instance_t
*) dbdata
;
542 DBC
*data_cursor
= NULL
;
547 bdbhpt_parsed_data_t pd
;
551 #if DLZ_DLOPEN_VERSION >= 2
556 memset(&key
, 0, sizeof(DBT
));
557 memset(&data
, 0, sizeof(DBT
));
559 key
.size
= strlen(zone
) + strlen(name
) + 1;
561 /* allocate mem for key */
562 key
.data
= keyStr
= malloc((key
.size
+ 1) * sizeof(char));
565 return ISC_R_NOMEMORY
;
567 strcpy(keyStr
, zone
);
569 strcat(keyStr
, name
);
571 /* get a cursor to loop through data */
572 if (db
->data
->cursor(db
->data
, NULL
, &data_cursor
, 0) != 0) {
573 result
= ISC_R_FAILURE
;
577 result
= ISC_R_NOTFOUND
;
580 while ((bdbhptres
= data_cursor
->c_get(data_cursor
, &key
, &data
,
584 tmp
= realloc(tmp
, data
.size
+ 1);
588 strncpy(tmp
, data
.data
, data
.size
);
589 tmp
[data
.size
] = '\0';
591 if (bdbhpt_parse_data(db
->log
, tmp
, &pd
) != ISC_R_SUCCESS
)
594 result
= db
->putrr(lookup
, pd
.type
, pd
.ttl
, pd
.data
);
595 if (result
!= ISC_R_SUCCESS
)
597 } /* end while loop */
600 /* get rid of cursor */
601 if (data_cursor
!= NULL
)
602 data_cursor
->c_close(data_cursor
);
613 * Initialises, sets flags and then opens Berkeley databases.
616 bdbhpt_opendb(log_t
*log
, DB_ENV
*db_env
, DBTYPE db_type
, DB
**db
,
617 const char *db_name
, char *db_file
, int flags
)
621 /* Initialise the database. */
622 if ((result
= db_create(db
, db_env
, 0)) != 0) {
624 "bdbhpt_dynamic: could not initialize %s database. "
625 "BerkeleyDB error: %s",
626 db_name
, db_strerror(result
));
627 return ISC_R_FAILURE
;
630 /* set database flags. */
631 if ((result
= (*db
)->set_flags(*db
, flags
)) != 0) {
633 "bdbhpt_dynamic: could not set flags for %s database. "
634 "BerkeleyDB error: %s",
635 db_name
, db_strerror(result
));
636 return ISC_R_FAILURE
;
639 /* open the database. */
640 if ((result
= (*db
)->open(*db
, NULL
, db_file
, db_name
, db_type
,
641 DB_RDONLY
| bdbhpt_threads
, 0)) != 0) {
643 "bdbhpt_dynamic: could not open %s database in %s. "
644 "BerkeleyDB error: %s",
645 db_name
, db_file
, db_strerror(result
));
646 return ISC_R_FAILURE
;
649 return ISC_R_SUCCESS
;
654 * Called to initialize the driver
657 dlz_create(const char *dlzname
, unsigned int argc
, char *argv
[],
663 bdbhpt_instance_t
*db
= NULL
;
665 const char *helper_name
;
670 /* Allocate memory for our db structures and helper functions */
671 db
= calloc(1, sizeof(struct bdbhpt_instance
));
673 return (ISC_R_NOMEMORY
);
675 /* Fill in the helper functions */
676 va_start(ap
, dbdata
);
677 while ((helper_name
= va_arg(ap
, const char *)) != NULL
)
678 b9_add_helper(db
, helper_name
, va_arg(ap
, void*));
681 /* verify we have 4 arg's passed to the driver */
683 db
->log(ISC_LOG_ERROR
,
684 "bdbhpt_dynamic: please supply 3 command line args. "
685 "You supplied: %s", argc
);
686 return (ISC_R_FAILURE
);
689 switch((char) *argv
[1]) {
691 * Transactional mode. Highest safety - lowest speed.
695 bdbFlags
= DB_INIT_MPOOL
| DB_INIT_LOCK
|
696 DB_INIT_LOG
| DB_INIT_TXN
;
697 db
->log(ISC_LOG_INFO
,
698 "bdbhpt_dynamic: using transactional mode.");
702 * Concurrent mode. Lower safety (no rollback) -
707 bdbFlags
= DB_INIT_CDB
| DB_INIT_MPOOL
;
708 db
->log(ISC_LOG_INFO
,
709 "bdbhpt_dynamic: using concurrent mode.");
713 * Private mode. No inter-process communication & no locking.
714 * Lowest saftey - highest speed.
718 bdbFlags
= DB_PRIVATE
| DB_INIT_MPOOL
;
719 db
->log(ISC_LOG_INFO
,
720 "bdbhpt_dynamic: using private mode.");
723 db
->log(ISC_LOG_ERROR
,
725 "operating mode must be set to P or C or T. "
726 "You specified '%s'", argv
[1]);
727 return (ISC_R_FAILURE
);
731 * create bdbhpt environment
732 * Basically bdbhpt allocates and assigns memory to db->dbenv
734 bdbhptres
= db_env_create(&db
->dbenv
, 0);
735 if (bdbhptres
!= 0) {
736 db
->log(ISC_LOG_ERROR
,
737 "bdbhpt_dynamic: db environment could not be created. "
738 "BerkeleyDB error: %s", db_strerror(bdbhptres
));
739 result
= ISC_R_FAILURE
;
743 /* open bdbhpt environment */
744 bdbhptres
= db
->dbenv
->open(db
->dbenv
, argv
[2],
745 bdbFlags
| bdbhpt_threads
| DB_CREATE
, 0);
746 if (bdbhptres
!= 0) {
747 db
->log(ISC_LOG_ERROR
,
749 "db environment at '%s' could not be opened. "
750 "BerkeleyDB error: %s",
751 argv
[2], db_strerror(bdbhptres
));
752 result
= ISC_R_FAILURE
;
756 /* open dlz_data database. */
757 result
= bdbhpt_opendb(db
->log
, db
->dbenv
, DB_UNKNOWN
, &db
->data
,
758 dlz_data
, argv
[3], DB_DUP
| DB_DUPSORT
);
759 if (result
!= ISC_R_SUCCESS
)
762 /* open dlz_xfr database. */
763 result
= bdbhpt_opendb(db
->log
, db
->dbenv
, DB_UNKNOWN
, &db
->xfr
,
764 dlz_xfr
, argv
[3], DB_DUP
| DB_DUPSORT
);
765 if (result
!= ISC_R_SUCCESS
)
768 /* open dlz_zone database. */
769 result
= bdbhpt_opendb(db
->log
, db
->dbenv
, DB_UNKNOWN
, &db
->zone
,
770 dlz_zone
, argv
[3], 0);
771 if (result
!= ISC_R_SUCCESS
)
774 /* open dlz_client database. */
775 result
= bdbhpt_opendb(db
->log
, db
->dbenv
, DB_UNKNOWN
, &db
->client
,
776 dlz_client
, argv
[3], DB_DUP
| DB_DUPSORT
);
777 if (result
!= ISC_R_SUCCESS
)
782 db
->log(ISC_LOG_INFO
,
783 "bdbhpt_dynamic: version %s, started",
784 dlz_bdbhpt_dynamic_version
);
785 return(ISC_R_SUCCESS
);
793 * Shut down the backend
796 dlz_destroy(void *dbdata
) {
797 struct bdbhpt_instance
*db
= (struct bdbhpt_instance
*)dbdata
;
799 db
->log(ISC_LOG_INFO
,
800 "dlz_bdbhpt_dynamic (%s): shutting down",
801 dlz_bdbhpt_dynamic_version
);
802 bdbhpt_cleanup((bdbhpt_instance_t
*) dbdata
);
807 * Return the version of the API
810 dlz_version(unsigned int *flags
) {
812 return (DLZ_DLOPEN_VERSION
);
816 * Register a helper function from the bind9 dlz_dlopen driver
819 b9_add_helper(struct bdbhpt_instance
*db
, const char *helper_name
, void *ptr
) {
820 if (strcmp(helper_name
, "log") == 0)
821 db
->log
= (log_t
*)ptr
;
822 if (strcmp(helper_name
, "putrr") == 0)
823 db
->putrr
= (dns_sdlz_putrr_t
*)ptr
;
824 if (strcmp(helper_name
, "putnamedrr") == 0)
825 db
->putnamedrr
= (dns_sdlz_putnamedrr_t
*)ptr
;
826 if (strcmp(helper_name
, "writeable_zone") == 0)
827 db
->writeable_zone
= (dns_dlz_writeablezone_t
*)ptr
;