driver.c revision 1.1
1/* $NetBSD: driver.c,v 1.1 2018/08/12 12:07:38 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 } 86 87 isc_hash_set_initializer(dctx->hashinit); 88 89 s = isc_mem_strdup(mctx, parameters); 90 if (s == NULL) { 91 result = ISC_R_NOMEMORY; 92 goto cleanup; 93 } 94 95 result = isc_commandline_strtoargv(mctx, s, &argc, &argv, 0); 96 if (result != ISC_R_SUCCESS) 97 goto cleanup; 98 99 log_write(ISC_LOG_DEBUG(9), 100 "loading params for dyndb '%s' from %s:%lu", 101 name, file, line); 102 103 /* Finally, create the instance. */ 104 CHECK(new_sample_instance(mctx, name, argc, argv, dctx, &sample_inst)); 105 106 /* 107 * This is an example so we create and load zones 108 * right now. This step can be arbitrarily postponed. 109 */ 110 CHECK(load_sample_instance_zones(sample_inst)); 111 112 *instp = sample_inst; 113 114 cleanup: 115 if (s != NULL) 116 isc_mem_free(mctx, s); 117 if (argv != NULL) 118 isc_mem_put(mctx, argv, argc * sizeof(*argv)); 119 120 return (result); 121} 122 123/* 124 * Driver destroy is called for every instance on every reload and then once 125 * during shutdown. 126 * 127 * @param[out] instp Pointer to instance-specific data (for one dyndb section). 128 */ 129void 130dyndb_destroy(void **instp) { 131 destroy_sample_instance((sample_instance_t **)instp); 132} 133 134/* 135 * Driver version is called when loading the driver to ensure there 136 * is no API mismatch betwen the driver and the caller. 137 */ 138int 139dyndb_version(unsigned int *flags) { 140 UNUSED(flags); 141 142 return (DNS_DYNDB_VERSION); 143} 144