[master] merge dyndb

4224.	[func]		Added support for "dyndb", a new interface for loading
			zone data from an external database, developed by
			Red Hat for the FreeIPA project.

			DynDB drivers fully implement the BIND database
			API, and are capable of significantly better
			performance and functionality than DLZ drivers,
			while taking advantage of advanced database
			features not available in BIND such as multi-master
			replication.

			Thanks to Adam Tkac and Petr Spacek of Red Hat.
			[RT #35271]
This commit is contained in:
Evan Hunt
2015-09-28 23:12:35 -07:00
parent 4d085258cc
commit a00f9e2f50
56 changed files with 3270 additions and 109 deletions

View File

@@ -0,0 +1,138 @@
/*
* Driver API implementation and main entry point for BIND.
*
* BIND calls dyndb_version() before loading, dyndb_init() during startup
* and dyndb_destroy() during shutdown.
*
* It is completely up to implementation what to do.
*
* dyndb <name> <driver> {} sections in named.conf are independent so
* driver init() and destroy() functions are called independently for
* each section even if they reference the same driver/library. It is
* up to driver implementation to detect and catch this situation if
* it is undesirable.
*
* Copyright (C) 2009-2015 Red Hat ; see COPYRIGHT for license
*/
#include <config.h>
#include <isc/commandline.h>
#include <isc/hash.h>
#include <isc/mem.h>
#include <isc/lib.h>
#include <isc/util.h>
#include <dns/db.h>
#include <dns/dyndb.h>
#include <dns/lib.h>
#include <dns/types.h>
#include "db.h"
#include "log.h"
#include "instance.h"
#include "util.h"
dns_dyndb_destroy_t dyndb_destroy;
dns_dyndb_register_t dyndb_init;
dns_dyndb_version_t dyndb_version;
/*
* Driver init is called for each dyndb section in named.conf
* once during startup and then again on every reload.
*
* @code
* dyndb example-name "sample.so" { param1 param2 };
* @endcode
*
* @param[in] name User-defined string from dyndb "name" {}; definition
* in named.conf.
* The example above will have name = "example-name".
* @param[in] argc Number of arg parameters
* definition. The example above will have
* argc = 2;
* @param[in] argv User-defined strings from arg parameters in dyndb
* definition. The example above will have
* argv[0] = "param1";
* argv[1] = "param2";
* @param[out] instp Pointer to instance-specific data (for one dyndb section).
*/
isc_result_t
dyndb_init(isc_mem_t *mctx, const char *name, const char *parameters,
const dns_dyndbctx_t *dctx, void **instp)
{
isc_result_t result;
unsigned int argc;
char **argv = NULL;
char *s = NULL;
sample_instance_t *sample_inst = NULL;
REQUIRE(name != NULL);
REQUIRE(dctx != NULL);
/*
* Depending on how dlopen() was called, we may not have
* access to named's global namespace, in which case we need
* to initialize libisc/libdns
*/
if (dctx->refvar != &isc_bind9) {
isc_lib_register();
isc_log_setcontext(dctx->lctx);
dns_log_setcontext(dctx->lctx);
}
if (isc_hashctx != NULL && isc_hashctx != dctx->hctx)
isc_hash_ctxdetach(&isc_hashctx);
isc_hashctx = dctx->hctx;
s = isc_mem_strdup(mctx, parameters);
if (s == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
result = isc_commandline_strtoargv(mctx, s, &argc, &argv, 0);
if (result != ISC_R_SUCCESS)
goto cleanup;
/* Finally, create the instance. */
CHECK(new_sample_instance(mctx, name, argc, argv, dctx, &sample_inst));
/*
* This is an example so we create and load zones
* right now. This step can be arbitrarily postponed.
*/
CHECK(load_sample_instance_zones(sample_inst));
*instp = sample_inst;
cleanup:
if (s != NULL)
isc_mem_free(mctx, s);
if (argv != NULL)
isc_mem_put(mctx, argv, argc * sizeof(*argv));
return (result);
}
/*
* Driver destroy is called for every instance on every reload and then once
* during shutdown.
*
* @param[out] instp Pointer to instance-specific data (for one dyndb section).
*/
void
dyndb_destroy(void **instp) {
destroy_sample_instance((sample_instance_t **)instp);
}
/*
* Driver version is called when loading the driver to ensure there
* is no API mismatch betwen the driver and the caller.
*/
int
dyndb_version(unsigned int *flags) {
UNUSED(flags);
return (DNS_DYNDB_VERSION);
}