a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/*
8664a1bd40814ed0b42eacfc5eb354b598dfd6dfTinderbox User * Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <config.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont#if HAVE_DLFCN_H
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont#include <dlfcn.h>
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont#elif _WIN32
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont#include <windows.h>
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont#endif
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/buffer.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/mem.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/mutex.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/once.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/result.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/region.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/task.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/types.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <isc/util.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/dyndb.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/log.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/types.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/view.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <dns/zone.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#include <string.h>
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#define CHECK(op) \
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt do { result = (op); \
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (result != ISC_R_SUCCESS) goto cleanup; \
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt } while (0)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunttypedef struct dyndb_implementation dyndb_implementation_t;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstruct dyndb_implementation {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_t *mctx;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt void *handle;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dyndb_register_t *register_func;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dyndb_destroy_t *destroy_func;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt char *name;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt void *inst;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt LINK(dyndb_implementation_t) link;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt};
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/*
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * List of dyndb implementations. Locked by dyndb_lock.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * These are stored here so they can be cleaned up on shutdown.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * (The order in which they are stored is not important.)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic LIST(dyndb_implementation_t) dyndb_implementations;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/* Locks dyndb_implementations. */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic isc_mutex_t dyndb_lock;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic isc_once_t once = ISC_ONCE_INIT;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic void
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdyndb_initialize(void) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt RUNTIME_CHECK(isc_mutex_init(&dyndb_lock) == ISC_R_SUCCESS);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt INIT_LIST(dyndb_implementations);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic dyndb_implementation_t *
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntimpfind(const char *name) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t *imp;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt for (imp = ISC_LIST_HEAD(dyndb_implementations);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp != NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp = ISC_LIST_NEXT(imp, link))
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (strcasecmp(name, imp->name) == 0)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (imp);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
541ce84ff2f0c54340da8b3e04c5686ed82420e1Mark Andrews#if HAVE_DLFCN_H && HAVE_DLOPEN
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic isc_result_t
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntload_symbol(void *handle, const char *filename,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt const char *symbol_name, void **symbolp)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt{
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt const char *errmsg;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt void *symbol;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(handle != NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(symbolp != NULL && *symbolp == NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt symbol = dlsym(handle, symbol_name);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (symbol == NULL) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt errmsg = dlerror();
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (errmsg == NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt errmsg = "returned function pointer is NULL";
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt "failed to lookup symbol %s in "
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt "dyndb module '%s': %s",
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt symbol_name, filename, errmsg);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (ISC_R_FAILURE);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt }
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dlerror();
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *symbolp = symbol;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (ISC_R_SUCCESS);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic isc_result_t
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntload_library(isc_mem_t *mctx, const char *filename, const char *instname,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t **impp)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt{
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_result_t result;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt void *handle = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t *imp = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dyndb_register_t *register_func = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dyndb_destroy_t *destroy_func = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dyndb_version_t *version_func = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt int version, flags;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(impp != NULL && *impp == NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt DNS_LOGMODULE_DYNDB, ISC_LOG_INFO,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt "loading DynDB instance '%s' driver '%s'",
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt instname, filename);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt flags = RTLD_NOW|RTLD_LOCAL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#ifdef RTLD_DEEPBIND
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt flags |= RTLD_DEEPBIND;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#endif
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt handle = dlopen(filename, flags);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (handle == NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(ISC_R_FAILURE);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Clear dlerror */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dlerror();
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(load_symbol(handle, filename, "dyndb_version",
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt (void **)&version_func));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt version = version_func(NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (version < (DNS_DYNDB_VERSION - DNS_DYNDB_AGE) ||
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt version > DNS_DYNDB_VERSION)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt "driver API version mismatch: %d/%d",
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt version, DNS_DYNDB_VERSION);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(ISC_R_FAILURE);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt }
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(load_symbol(handle, filename, "dyndb_init",
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt (void **)&register_func));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(load_symbol(handle, filename, "dyndb_destroy",
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt (void **)&destroy_func));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp = isc_mem_get(mctx, sizeof(dyndb_implementation_t));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (imp == NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(ISC_R_NOMEMORY);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp->mctx = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_attach(mctx, &imp->mctx);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp->handle = handle;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp->register_func = register_func;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp->destroy_func = destroy_func;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp->name = isc_mem_strdup(mctx, instname);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (imp->name == NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(ISC_R_NOMEMORY);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp->inst = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt INIT_LINK(imp, link);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *impp = imp;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntcleanup:
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (result != ISC_R_SUCCESS)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt "failed to dynamically load instance '%s' "
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt "driver '%s': %s (%s)", instname, filename,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dlerror(), isc_result_totext(result));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (imp != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (result != ISC_R_SUCCESS && handle != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dlclose(handle);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (result);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic void
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntunload_library(dyndb_implementation_t **impp) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t *imp;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(impp != NULL && *impp != NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt imp = *impp;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_free(imp->mctx, imp->name);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *impp = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont#elif _WIN32
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupontstatic isc_result_t
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupontload_symbol(HMODULE handle, const char *filename,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont const char *symbol_name, void **symbolp)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont{
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont void *symbol;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont REQUIRE(handle != NULL);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont REQUIRE(symbolp != NULL && *symbolp == NULL);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont symbol = GetProcAddress(handle, symbol_name);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (symbol == NULL) {
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont int errstatus = GetLastError();
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont "failed to lookup symbol %s in "
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont "dyndb module '%s': %d",
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont symbol_name, filename, errstatus);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont return (ISC_R_FAILURE);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont }
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont *symbolp = symbol;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont return (ISC_R_SUCCESS);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont}
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupontstatic isc_result_t
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupontload_library(isc_mem_t *mctx, const char *filename, const char *instname,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont dyndb_implementation_t **impp)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont{
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_result_t result;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont HMODULE handle;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont dyndb_implementation_t *imp = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont dns_dyndb_register_t *register_func = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont dns_dyndb_destroy_t *destroy_func = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont dns_dyndb_version_t *version_func = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont int version;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont REQUIRE(impp != NULL && *impp == NULL);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont DNS_LOGMODULE_DYNDB, ISC_LOG_INFO,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont "loading DynDB instance '%s' driver '%s'",
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont instname, filename);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont handle = LoadLibraryA(filename);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (handle == NULL)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont CHECK(ISC_R_FAILURE);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont CHECK(load_symbol(handle, filename, "dyndb_version",
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont (void **)&version_func));
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont version = version_func(NULL);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (version < (DNS_DYNDB_VERSION - DNS_DYNDB_AGE) ||
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont version > DNS_DYNDB_VERSION)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont {
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont "driver API version mismatch: %d/%d",
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont version, DNS_DYNDB_VERSION);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont CHECK(ISC_R_FAILURE);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont }
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont CHECK(load_symbol(handle, filename, "dyndb_init",
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont (void **)&register_func));
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont CHECK(load_symbol(handle, filename, "dyndb_destroy",
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont (void **)&destroy_func));
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp = isc_mem_get(mctx, sizeof(dyndb_implementation_t));
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (imp == NULL)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont CHECK(ISC_R_NOMEMORY);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp->mctx = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_mem_attach(mctx, &imp->mctx);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp->handle = handle;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp->register_func = register_func;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp->destroy_func = destroy_func;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp->name = isc_mem_strdup(mctx, instname);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (imp->name == NULL)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont CHECK(ISC_R_NOMEMORY);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp->inst = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont INIT_LINK(imp, link);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont *impp = imp;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupontcleanup:
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (result != ISC_R_SUCCESS)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont DNS_LOGMODULE_DYNDB, ISC_LOG_ERROR,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont "failed to dynamically load instance '%s' "
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont "driver '%s': %d (%s)", instname, filename,
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont GetLastError(), isc_result_totext(result));
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (imp != NULL)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t));
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont if (result != ISC_R_SUCCESS && handle != NULL)
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont FreeLibrary(handle);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont return (result);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont}
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupontstatic void
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupontunload_library(dyndb_implementation_t **impp) {
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont dyndb_implementation_t *imp;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont REQUIRE(impp != NULL && *impp != NULL);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont imp = *impp;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_mem_free(imp->mctx, imp->name);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont isc_mem_putanddetach(&imp->mctx, imp, sizeof(dyndb_implementation_t));
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont *impp = NULL;
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont}
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont#else /* HAVE_DLFCN_H || _WIN32 */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic isc_result_t
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntload_library(isc_mem_t *mctx, const char *filename, const char *instname,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t **impp)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt{
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNUSED(mctx);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNUSED(filename);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNUSED(instname);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNUSED(impp);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DYNDB,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt ISC_LOG_ERROR,
dd784c18ef799e9e35c9debe34323c50d4e7f8a5Francis Dupont "dynamic database support is not implemented");
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (ISC_R_NOTIMPLEMENTED);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic void
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntunload_library(dyndb_implementation_t **impp)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt{
dd784c18ef799e9e35c9debe34323c50d4e7f8a5Francis Dupont UNUSED(impp);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#endif /* HAVE_DLFCN_H */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntisc_result_t
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdns_dyndb_load(const char *libname, const char *name, const char *parameters,
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt const char *file, unsigned long line, isc_mem_t *mctx,
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt const dns_dyndbctx_t *dctx)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt{
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_result_t result;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t *implementation = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(DNS_DYNDBCTX_VALID(dctx));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(name != NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt RUNTIME_CHECK(isc_once_do(&once, dyndb_initialize) == ISC_R_SUCCESS);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt LOCK(&dyndb_lock);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* duplicate instance names are not allowed */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (impfind(name) != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(ISC_R_EXISTS);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(load_library(mctx, libname, name, &implementation));
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt CHECK(implementation->register_func(mctx, name, parameters, file, line,
f503aa345b451f94875a5bab637223bcbbd93b6dEvan Hunt dctx, &implementation->inst));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt APPEND(dyndb_implementations, implementation, link);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt result = ISC_R_SUCCESS;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntcleanup:
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (result != ISC_R_SUCCESS)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (implementation != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt unload_library(&implementation);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNLOCK(&dyndb_lock);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (result);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntvoid
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdns_dyndb_cleanup(isc_boolean_t exiting) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t *elem;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dyndb_implementation_t *prev;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt RUNTIME_CHECK(isc_once_do(&once, dyndb_initialize) == ISC_R_SUCCESS);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt LOCK(&dyndb_lock);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt elem = TAIL(dyndb_implementations);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt while (elem != NULL) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt prev = PREV(elem, link);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNLINK(dyndb_implementations, elem, link);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt DNS_LOGMODULE_DYNDB, ISC_LOG_INFO,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt "unloading DynDB instance '%s'", elem->name);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt elem->destroy_func(&elem->inst);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt ENSURE(elem->inst == NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt unload_library(&elem);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt elem = prev;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt }
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNLOCK(&dyndb_lock);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (exiting == ISC_TRUE)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mutex_destroy(&dyndb_lock);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntisc_result_t
93c211afc97e7a072c12ef346581065e4065ff15Evan Huntdns_dyndb_createctx(isc_mem_t *mctx, const void *hashinit, isc_log_t *lctx,
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt dns_view_t *view, dns_zonemgr_t *zmgr, isc_task_t *task,
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt isc_timermgr_t *tmgr, dns_dyndbctx_t **dctxp)
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt{
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dyndbctx_t *dctx;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(dctxp != NULL && *dctxp == NULL);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx = isc_mem_get(mctx, sizeof(*dctx));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (dctx == NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (ISC_R_NOMEMORY);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt memset(dctx, 0, sizeof(*dctx));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (view != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_view_attach(view, &dctx->view);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (zmgr != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_zonemgr_attach(zmgr, &dctx->zmgr);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (task != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_task_attach(task, &dctx->task);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx->timermgr = tmgr;
93c211afc97e7a072c12ef346581065e4065ff15Evan Hunt dctx->hashinit = hashinit;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx->lctx = lctx;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx->refvar = &isc_bind9;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_attach(mctx, &dctx->mctx);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx->magic = DNS_DYNDBCTX_MAGIC;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt *dctxp = dctx;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (ISC_R_SUCCESS);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntvoid
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdns_dyndb_destroyctx(dns_dyndbctx_t **dctxp) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dyndbctx_t *dctx;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(dctxp != NULL && DNS_DYNDBCTX_VALID(*dctxp));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx = *dctxp;
30f8d5e386a283c7e3a24683b78e489881c16c34Mark Andrews *dctxp = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx->magic = 0;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (dctx->view != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_view_detach(&dctx->view);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (dctx->zmgr != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_zonemgr_detach(&dctx->zmgr);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (dctx->task != NULL)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_task_detach(&dctx->task);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx->timermgr = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dctx->lctx = NULL;
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(*dctx));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt}