driver.c revision 1.4
1/* $NetBSD: driver.c,v 1.4 2019/09/05 19:32:56 christos Exp $ */ 2 3/* 4 * Driver API implementation and main entry point for BIND. 5 * 6 * BIND calls dyndb_version() before loading, dyndb_init() during startup 7 * and dyndb_destroy() during shutdown. 8 * 9 * It is completely up to implementation what to do. 10 * 11 * dyndb <name> <driver> {} sections in named.conf are independent so 12 * driver init() and destroy() functions are called independently for 13 * each section even if they reference the same driver/library. It is 14 * up to driver implementation to detect and catch this situation if 15 * it is undesirable. 16 * 17 * Copyright (C) 2009-2015 Red Hat ; see COPYRIGHT for license 18 */ 19 20#include <config.h> 21 22#include <isc/commandline.h> 23#include <isc/hash.h> 24#include <isc/mem.h> 25#include <isc/lib.h> 26#include <isc/util.h> 27 28#include <dns/db.h> 29#include <dns/dyndb.h> 30#include <dns/lib.h> 31#include <dns/types.h> 32 33#include "db.h" 34#include "log.h" 35#include "instance.h" 36#include "util.h" 37 38dns_dyndb_destroy_t dyndb_destroy; 39dns_dyndb_register_t dyndb_init; 40dns_dyndb_version_t dyndb_version; 41 42/* 43 * Driver init is called for each dyndb section in named.conf 44 * once during startup and then again on every reload. 45 * 46 * @code 47 * dyndb example-name "sample.so" { param1 param2 }; 48 * @endcode 49 * 50 * @param[in] name User-defined string from dyndb "name" {}; definition 51 * in named.conf. 52 * The example above will have name = "example-name". 53 * @param[in] parameters User-defined parameters from dyndb section as one 54 * string. The example above will have 55 * params = "param1 param2"; 56 * @param[in] file The name of the file from which the parameters 57 * were read. 58 * @param[in] line The line number from which the parameters were read. 59 * @param[out] instp Pointer to instance-specific data 60 * (for one dyndb section). 61 */ 62isc_result_t 63dyndb_init(isc_mem_t *mctx, const char *name, const char *parameters, 64 const char *file, unsigned long line, 65 const dns_dyndbctx_t *dctx, void **instp) 66{ 67 isc_result_t result; 68 unsigned int argc; 69 char **argv = NULL; 70 char *s = NULL; 71 sample_instance_t *sample_inst = NULL; 72 73 REQUIRE(name != NULL); 74 REQUIRE(dctx != NULL); 75 76 /* 77 * Depending on how dlopen() was called, we may not have 78 * access to named's global namespace, in which case we need 79 * to initialize libisc/libdns 80 */ 81 if (dctx->refvar != &isc_bind9) { 82 isc_lib_register(); 83 isc_log_setcontext(dctx->lctx); 84 dns_log_setcontext(dctx->lctx); 85 isc_hash_set_initializer(dctx->hashinit); 86 } 87 88 s = isc_mem_strdup(mctx, parameters); 89 if (s == NULL) { 90 result = ISC_R_NOMEMORY; 91 goto cleanup; 92 } 93 94 result = isc_commandline_strtoargv(mctx, s, &argc, &argv, 0); 95 if (result != ISC_R_SUCCESS) { 96 log_write(ISC_LOG_ERROR, 97 "dyndb_init: isc_commandline_strtoargv -> %s\n", 98 isc_result_totext(result)); 99 goto cleanup; 100 } 101 102 log_write(ISC_LOG_DEBUG(9), 103 "loading params for dyndb '%s' from %s:%lu", 104 name, file, line); 105 106 /* Finally, create the instance. */ 107 result = new_sample_instance(mctx, name, argc, argv, dctx, 108 &sample_inst); 109 if (result != ISC_R_SUCCESS) { 110 log_write(ISC_LOG_ERROR, 111 "dyndb_init: new_sample_instance -> %s\n", 112 isc_result_totext(result)); 113 goto cleanup; 114 } 115 116 /* 117 * This is an example so we create and load zones 118 * right now. This step can be arbitrarily postponed. 119 */ 120 result = load_sample_instance_zones(sample_inst); 121 if (result != ISC_R_SUCCESS) { 122 log_write(ISC_LOG_ERROR, 123 "dyndb_init: load_sample_instance_zones -> %s\n", 124 isc_result_totext(result)); 125 goto cleanup; 126 } 127 128 *instp = sample_inst; 129 130 cleanup: 131 if (s != NULL) 132 isc_mem_free(mctx, s); 133 if (argv != NULL) 134 isc_mem_put(mctx, argv, argc * sizeof(*argv)); 135 136 return (result); 137} 138 139/* 140 * Driver destroy is called for every instance on every reload and then once 141 * during shutdown. 142 * 143 * @param[out] instp Pointer to instance-specific data (for one dyndb section). 144 */ 145void 146dyndb_destroy(void **instp) { 147 destroy_sample_instance((sample_instance_t **)instp); 148} 149 150/* 151 * Driver version is called when loading the driver to ensure there 152 * is no API mismatch betwen the driver and the caller. 153 */ 154int 155dyndb_version(unsigned int *flags) { 156 UNUSED(flags); 157 158 return (DNS_DYNDB_VERSION); 159} 160