--- /dev/null
+OVERVIEW:
+
+DLZ (Dynamically Loadable Zones) is an extention to BIND 9 that
+allows zone data to be retrieved directly from an external database.
+There is no required format or schema. DLZ drivers exist for several
+different database backends including PostgreSQL, MySQL, and LDAP and
+can be written for any other.
+
+Historically, DLZ drivers had to be statically linked with the named
+binary and were turned on via a configure option at compile time (for
+example, "configure --with-dlz-ldap"). Currently, the drivers provided
+in the BIND 9 tarball in contrib/dlz/drivers are still linked this way.
+
+However, as of BIND 9.8, it is also possible to link some DLZ modules
+dynamically at runtime, via the DLZ "dlopen" driver, which acts as a
+generic wrapper around a shared object that implements the DLZ API. The
+"dlopen" driver is linked into named by default, so configure options are
+no longer necessary.
+
+When the DLZ module provides data to named, it does so in text format.
+The response is converted to DNS wire format by named. This conversion,
+and the lack of any internal caching, places significant limits on the
+query performance of DLZ modules. Consequently, DLZ is not recommended
+for use on high-volume servers. However, it can be used in a hidden
+master configuration, with slaves retrieving zone updates via AXFR.
+(Note, however, that DLZ has no built-in support for DNS notify; slaves
+are not automatically informed of changes to the zones in the database.)
+
+EXAMPLE DRIVER:
+
+This directory contains an example of an externally-lodable DLZ module,
+dlz_example.c, which demonstrates the features of the DLZ API. It sets up
+a single zone, whose name is configured in named.conf. The zone can answer
+queries and AXFR requests, and accept DDNS updates.
+
+By default, at runtime, the zone implemented by this driver will contain
+an SOA, NS, and a single A record at the apex. If configured in named.conf
+to use the name "example.nil", then, the zone will look like this:
+
+ example.nil. 3600 IN SOA example.nil. hostmaster.example.nil. (
+ 123 900 600 86400 3600
+ )
+ example.nil. 3600 IN NS example.nil.
+ example.nil. 1800 IN A 10.53.0.1
+
+The driver is also capable of retrieving information about the querying
+client, and altering its response on the basis of this information. To
+demonstrate this feature, the example driver responds to queries for
+"source-addr.<zonename>/TXT" with the source address of the query.
+Note, however, that this record will *not* be included in AXFR or ANY
+responses. (Normally, this feature would be used to alter responses in
+some other fashion, e.g., by providing different address records for
+a particular name depending on the network from which the query arrived.)
+
+IMPLEMENTATION NOTES:
+
+The minimal set of type definitions, prototypes, and macros needed
+for implementing a DLZ driver is in dlz_minimal.h. Copy this header
+file into your source tree when creating an external DLZ module.
+
+The DLZ dlopen driver provides a set of callback functions:
+
+ - void log(int level, const char *fmt, ...);
+
+ Writes the specified string to the named log, at the specified
+ log level. Uses printf() format semantics.
+
+ - isc_result_t putrr(dns_sdlzlookup_t *lookup, const char *type,
+ dns_ttl_t ttl, const char *data);
+
+ Puts a DNS resource record into the query response, which
+ referenced by the opaque structure 'lookup' provided by named.
+
+ - isc_result_t putnamedrr(dns_sdlzallnotes_t *allnodes,
+ const char *name, const char *type,
+ dns_ttl_t ttl, const char *data);
+
+ Puts a DNS resource record into an AXFR response, which is
+ referenced by the opaque structure 'allnodes' provided by named.
+
+ - isc_result_t writable_zone(dns_view_t *view, const char *zone_name);
+
+ Allows the DLZ module to inform named that a given zone can recieve
+ DDNS updates.
+
+The external DLZ module can define the following functions (some of these
+are mandatory, others optional).
+
+ - int dlz_version(unsigned int *flags);
+
+ Required for alL external DLZ modules, to indicate the version number
+ of the DLZ dlopen driver that this module supports. It should return
+ the value DLZ_DLOPEN_VERSION, which is defined in dlz_minimal.h and
+ is currently 2. 'flags' is updated to indicate capabilities
+ of the module. In particular, if the module is thread-safe then it
+ sets 'flags' to include DNS_SDLZFLAG_THREADSAFE. (Other capability
+ flags may be added in the future.)
+
+ - isc_result_t dlz_create(const char *dlzname,
+ unsigned int argc, char *argv[],
+ void **dbdata, ...);
+
+ Required for all external DLZ modules; this call initializes the
+ module.
+
+ - void dlz_destroy(void *dbdata);
+
+ Optional. If supplied, this will be called when the driver is
+ unloaded.
+
+ - isc_result_t dlz_findzonedb(void *dbdata, const char *name);
+
+ Required for all external DLZ modules. This indicates whether the
+ DLZ module can answer for a given zone. Returns ISC_R_SUCCESS if
+ so, otherwise ISC_R_NOTFOUND.
+
+ - isc_result_t dlz_lookup(const char *zone, const char *name, void *dbdata,
+ dns_sdlzlookup_t *lookup,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo);
+
+ Required for all external DLZ modules. This carries out the database
+ lookup for a query.
+
+ - isc_result_t dlz_allowzonexfr(void *dbdata, const char *name,
+ const char *client);
+
+ Optional. Supply this if you want the module to support AXFR
+ for the specified zone and client. A return value of ISC_R_SUCCESS
+ means AXFR is allowed, any other value means it isn't.
+
+ - isc_result_t dlz_allnodes(const char *zone, void *dbdata,
+ dns_sdlzallnodes_t *allnodes);
+
+ Optional, but must be supplied dlz_allowzonexfr() is. This function
+ returns all nodes in the zone in order to perform a zone transfer.
+
+ - isc_result_t dlz_newversion(const char *zone, void *dbdata,
+ void **versionp);
+
+ Optional. Supply this if you want the module to support DDNS
+ updates. This function starts a transaction in the database.
+
+
+ - void dlz_closeversion(const char *zone, isc_boolean_t commit,
+ void *dbdata, void **versionp);
+
+ Optional, but must be supplied if dlz_newversion() is. This function
+ closes a transaction. 'commit' indicates whether to commit the changes
+ to the database, or ignore them.
+
+ - isc_result_t dlz_configure(dns_view_t *view, void *dbdata);
+
+ Optional, but must be supplied in order to support DDNS updates.
+
+ - isc_boolean_t dlz_ssumatch(const char *signer, const char *name,
+ const char *tcpaddr, const char *type,
+ const char *key, uint32_t keydatalen,
+ uint8_t *keydata, void *dbdata);
+
+ Optional, but must be supplied in order to support DDNS updates.
+
+ - isc_result_t dlz_addrdataset(const char *name, const char *rdatastr,
+ void *dbdata, void *version);
+
+ Optional, but must be supplied in order to support DDNS updates.
+ Adds the data in 'rdatastr' to a database node.
+
+ - isc_result_t dlz_subrdataset(const char *name, const char *rdatastr,
+ void *dbdata, void *version);
+
+ Optional, but must be supplied in order to support DDNS updates.
+ Removes the data in 'rdatastr' from a database node.
+
+ - isc_result_t dlz_delrdataset(const char *name, const char *rdatastr,
+ void *dbdata, void *version);
+
+ Optional, but must be supplied in order to support DDNS updates.
+ Deletes all data matching the type specified in 'rdatastr' from
+ the database.
/*
- * Copyright (C) 2010 Andrew Tridgell
+ * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
*
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the
- * above copyright notice and this permission notice appear in all
- * copies.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
- * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
- * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
- * USE OR PERFORMANCE OF THIS SOFTWARE.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
*/
+/* $Id: dlz_example.c,v 1.3 2011/10/20 22:01:48 each Exp $ */
+
/*
- this provides a very simple example of an external loadable DLZ
- driver, with update support
+ * This provides a very simple example of an external loadable DLZ
+ * driver, with update support.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdarg.h>
+#include <stdint.h>
#include "dlz_minimal.h"
+#ifdef WIN32
+#define STRTOK_R(a, b, c) strtok_s(a, b, c)
+#elif defined(_REENTRANT)
+#define STRTOK_R(a, b, c) strtok_r(a, b, c)
+#else
+#define STRTOK_R(a, b, c) strtok(a, b)
+#endif
-/* for this simple example, use fixed sized strings */
+/* For this simple example, use fixed sized strings */
struct record {
char name[100];
char type[10];
char data[200];
- uint32_t ttl;
+ dns_ttl_t ttl;
};
#define MAX_RECORDS 100
struct dlz_example_data {
char *zone_name;
- /* an example driver doesn't need good memory management :-) */
+ /* An example driver doesn't need good memory management :-) */
struct record current[MAX_RECORDS];
struct record adds[MAX_RECORDS];
struct record deletes[MAX_RECORDS];
- bool transaction_started;
+ isc_boolean_t transaction_started;
- /* helper functions from the dlz_dlopen driver */
- void (*log)(int level, const char *fmt, ...);
- isc_result_t (*putrr)(dns_sdlzlookup_t *handle, const char *type,
- dns_ttl_t ttl, const char *data);
- isc_result_t (*putnamedrr)(dns_sdlzlookup_t *handle, const char *name,
- const char *type, dns_ttl_t ttl, const char *data);
- isc_result_t (*writeable_zone)(dns_view_t *view, const char *zone_name);
+ /* Helper functions from the dlz_dlopen driver */
+ log_t *log;
+ dns_sdlz_putrr_t *putrr;
+ dns_sdlz_putnamedrr_t *putnamedrr;
+ dns_dlz_writeablezone_t *writeable_zone;
};
-static bool single_valued(const char *type)
-{
+static isc_boolean_t
+single_valued(const char *type) {
const char *single[] = { "soa", "cname", NULL };
int i;
- for (i=0; single[i]; i++) {
+
+ for (i = 0; single[i]; i++) {
if (strcasecmp(single[i], type) == 0) {
- return true;
+ return (ISC_TRUE);
}
}
- return false;
+ return (ISC_FALSE);
}
/*
- add a record to a list
+ * Add a record to a list
*/
-static isc_result_t add_name(struct dlz_example_data *state,
- struct record *list, const char *name, const char *type,
- uint32_t ttl, const char *data)
+static isc_result_t
+add_name(struct dlz_example_data *state, struct record *list,
+ const char *name, const char *type, dns_ttl_t ttl, const char *data)
{
int i;
- bool single = single_valued(type);
+ isc_boolean_t single = single_valued(type);
int first_empty = -1;
- for (i=0; i<MAX_RECORDS; i++) {
- if (first_empty == -1 && strlen(list[i].name) == 0) {
+ for (i = 0; i < MAX_RECORDS; i++) {
+ if (first_empty == -1 && strlen(list[i].name) == 0U) {
first_empty = i;
}
- if (strcasecmp(list[i].name, name) != 0)
+ if (strcasecmp(list[i].name, name) != 0)
continue;
if (strcasecmp(list[i].type, type) != 0)
continue;
}
if (i == MAX_RECORDS) {
state->log(ISC_LOG_ERROR, "dlz_example: out of record space");
- return ISC_R_FAILURE;
+ return (ISC_R_FAILURE);
}
strcpy(list[i].name, name);
strcpy(list[i].type, type);
strcpy(list[i].data, data);
list[i].ttl = ttl;
- return ISC_R_SUCCESS;
+ return (ISC_R_SUCCESS);
}
/*
- delete a record from a list
+ * Delete a record from a list
*/
-static isc_result_t del_name(struct dlz_example_data *state,
- struct record *list, const char *name, const char *type,
- uint32_t ttl, const char *data)
+static isc_result_t
+del_name(struct dlz_example_data *state, struct record *list,
+ const char *name, const char *type, dns_ttl_t ttl,
+ const char *data)
{
int i;
- for (i=0; i<MAX_RECORDS; i++) {
+
+ UNUSED(state);
+
+ for (i = 0; i < MAX_RECORDS; i++) {
if (strcasecmp(name, list[i].name) == 0 &&
strcasecmp(type, list[i].type) == 0 &&
strcasecmp(data, list[i].data) == 0 &&
}
}
if (i == MAX_RECORDS) {
- return ISC_R_NOTFOUND;
+ return (ISC_R_NOTFOUND);
}
memset(&list[i], 0, sizeof(struct record));
- return ISC_R_SUCCESS;
+ return (ISC_R_SUCCESS);
}
+static isc_result_t
+fmt_address(isc_sockaddr_t *addr, char *buffer, size_t size) {
+ char addr_buf[100];
+ const char *ret;
+ uint16_t port = 0;
+
+ switch (addr->type.sa.sa_family) {
+ case AF_INET:
+ port = ntohs(addr->type.sin.sin_port);
+ ret = inet_ntop(AF_INET, &addr->type.sin.sin_addr, addr_buf,
+ sizeof(addr_buf));
+ break;
+ case AF_INET6:
+ port = ntohs(addr->type.sin6.sin6_port);
+ ret = inet_ntop(AF_INET6, &addr->type.sin6.sin6_addr, addr_buf,
+ sizeof(addr_buf));
+ break;
+ default:
+ return (ISC_R_FAILURE);
+ }
+
+ if (ret == NULL)
+ return (ISC_R_FAILURE);
+ snprintf(buffer, size, "%s#%u", addr_buf, port);
+ return (ISC_R_SUCCESS);
+}
/*
- return the version of the API
+ * Return the version of the API
*/
-int dlz_version(unsigned int *flags)
-{
- return DLZ_DLOPEN_VERSION;
+int
+dlz_version(unsigned int *flags) {
+ UNUSED(flags);
+ return (DLZ_DLOPEN_VERSION);
}
/*
- remember a helper function from the bind9 dlz_dlopen driver
+ * Remember a helper function from the bind9 dlz_dlopen driver
*/
-static void b9_add_helper(struct dlz_example_data *state, const char *helper_name, void *ptr)
+static void
+b9_add_helper(struct dlz_example_data *state,
+ const char *helper_name, void *ptr)
{
- if (strcmp(helper_name, "log") == 0) {
- state->log = ptr;
- }
- if (strcmp(helper_name, "putrr") == 0) {
- state->putrr = ptr;
- }
- if (strcmp(helper_name, "putnamedrr") == 0) {
- state->putnamedrr = ptr;
- }
- if (strcmp(helper_name, "writeable_zone") == 0) {
- state->writeable_zone = ptr;
- }
+ if (strcmp(helper_name, "log") == 0)
+ state->log = (log_t *)ptr;
+ if (strcmp(helper_name, "putrr") == 0)
+ state->putrr = (dns_sdlz_putrr_t *)ptr;
+ if (strcmp(helper_name, "putnamedrr") == 0)
+ state->putnamedrr = (dns_sdlz_putnamedrr_t *)ptr;
+ if (strcmp(helper_name, "writeable_zone") == 0)
+ state->writeable_zone = (dns_dlz_writeablezone_t *)ptr;
}
/*
- called to initialise the driver
+ * Called to initialize the driver
*/
-isc_result_t dlz_create(const char *dlzname, unsigned int argc, char *argv[],
- void **dbdata, ...)
+isc_result_t
+dlz_create(const char *dlzname, unsigned int argc, char *argv[],
+ void **dbdata, ...)
{
struct dlz_example_data *state;
const char *helper_name;
va_list ap;
char soa_data[200];
+ UNUSED(dlzname);
+
state = calloc(1, sizeof(struct dlz_example_data));
- if (state == NULL) {
- return ISC_R_NOMEMORY;
- }
+ if (state == NULL)
+ return (ISC_R_NOMEMORY);
- /* fill in the helper functions */
+ /* Fill in the helper functions */
va_start(ap, dbdata);
while ((helper_name = va_arg(ap, const char *)) != NULL) {
b9_add_helper(state, helper_name, va_arg(ap, void*));
va_end(ap);
if (argc < 2) {
- state->log(ISC_LOG_ERROR, "dlz_example: please specify a zone name");
- return ISC_R_FAILURE;
+ state->log(ISC_LOG_ERROR,
+ "dlz_example: please specify a zone name");
+ return (ISC_R_FAILURE);
}
state->zone_name = strdup(argv[1]);
sprintf(soa_data, "%s hostmaster.%s 123 900 600 86400 3600",
state->zone_name, state->zone_name);
- add_name(state, &state->current[0], state->zone_name, "soa", 3600, soa_data);
- add_name(state, &state->current[0], state->zone_name, "ns", 3600, state->zone_name);
- add_name(state, &state->current[0], state->zone_name, "a", 1800, "10.53.0.1");
+ add_name(state, &state->current[0], state->zone_name,
+ "soa", 3600, soa_data);
+ add_name(state, &state->current[0], state->zone_name,
+ "ns", 3600, state->zone_name);
+ add_name(state, &state->current[0], state->zone_name,
+ "a", 1800, "10.53.0.1");
- state->log(ISC_LOG_INFO, "dlz_example: started for zone %s", state->zone_name);
+ state->log(ISC_LOG_INFO,
+ "dlz_example: started for zone %s",
+ state->zone_name);
*dbdata = state;
- return ISC_R_SUCCESS;
+ return (ISC_R_SUCCESS);
}
/*
- shutdown the backend
+ * Shut down the backend
*/
-void dlz_destroy(void *dbdata)
-{
+void
+dlz_destroy(void *dbdata) {
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
- state->log(ISC_LOG_INFO, "dlz_example: shutting down zone %s", state->zone_name);
+
+ state->log(ISC_LOG_INFO,
+ "dlz_example: shutting down zone %s",
+ state->zone_name);
free(state->zone_name);
free(state);
}
/*
- see if we handle a given zone
+ * See if we handle a given zone
*/
-isc_result_t dlz_findzonedb(void *dbdata, const char *name)
-{
+isc_result_t
+dlz_findzonedb(void *dbdata, const char *name) {
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
- if (strcasecmp(state->zone_name, name) == 0) {
- return ISC_R_SUCCESS;
- }
- return ISC_R_NOTFOUND;
-}
+ if (strcasecmp(state->zone_name, name) == 0)
+ return (ISC_R_SUCCESS);
+ return (ISC_R_NOTFOUND);
+}
/*
- lookup one record
+ * Look up one record in the sample database.
+ *
+ * If the queryname is "source-addr", we add a TXT record containing
+ * the address of the client; this demonstrates the use of 'methods'
+ * and 'clientinfo'.
*/
-isc_result_t dlz_lookup(const char *zone, const char *name,
- void *dbdata, dns_sdlzlookup_t *lookup)
+isc_result_t
+dlz_lookup(const char *zone, const char *name, void *dbdata,
+ dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo)
{
+ isc_result_t result;
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
- int i;
- bool found = false;
+ isc_boolean_t found = ISC_FALSE;
+ isc_sockaddr_t *src;
char full_name[100];
-
- if (strcmp(name, "@") == 0) {
+ int i;
+
+ UNUSED(zone);
+
+ if (strcmp(name, "@") == 0)
strcpy(full_name, state->zone_name);
- } else {
+ else
sprintf(full_name, "%s.%s", name, state->zone_name);
+
+ if (strcmp(name, "source-addr") == 0) {
+ char buf[100];
+ strcpy(buf, "unknown");
+ if (methods != NULL &&
+ methods->version - methods->age >=
+ DNS_CLIENTINFOMETHODS_VERSION)
+ {
+ methods->sourceip(clientinfo, &src);
+ fmt_address(src, buf, sizeof(buf));
+ }
+
+ fprintf(stderr, "connection from: %s\n", buf);
+
+ found = ISC_TRUE;
+ result = state->putrr(lookup, "TXT", 0, buf);
+ if (result != ISC_R_SUCCESS)
+ return (result);
}
- for (i=0; i<MAX_RECORDS; i++) {
+
+ for (i = 0; i < MAX_RECORDS; i++) {
if (strcasecmp(state->current[i].name, full_name) == 0) {
- isc_result_t result;
- found = true;
- result = state->putrr(lookup, state->current[i].type,
- state->current[i].ttl, state->current[i].data);
- if (result != ISC_R_SUCCESS) {
- return result;
- }
+ found = ISC_TRUE;
+ result = state->putrr(lookup, state->current[i].type,
+ state->current[i].ttl,
+ state->current[i].data);
+ if (result != ISC_R_SUCCESS)
+ return (result);
}
}
- if (!found) {
- return ISC_R_NOTFOUND;
- }
- return ISC_R_SUCCESS;
+
+ if (!found)
+ return (ISC_R_NOTFOUND);
+
+ return (ISC_R_SUCCESS);
}
/*
- see if a zone transfer is allowed
+ * See if a zone transfer is allowed
*/
-isc_result_t dlz_allowzonexfr(void *dbdata, const char *name, const char *client)
-{
- /* just say yes for all our zones */
- return dlz_findzonedb(dbdata, name);
+isc_result_t
+dlz_allowzonexfr(void *dbdata, const char *name, const char *client) {
+ UNUSED(client);
+
+ /* Just say yes for all our zones */
+ return (dlz_findzonedb(dbdata, name));
}
/*
- perform a zone transfer
+ * Perform a zone transfer
*/
-isc_result_t dlz_allnodes(const char *zone, void *dbdata,
- dns_sdlzallnodes_t *allnodes)
-{
+isc_result_t
+dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes) {
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
int i;
- for (i=0; i<MAX_RECORDS; i++) {
+ UNUSED(zone);
+
+ for (i = 0; i < MAX_RECORDS; i++) {
isc_result_t result;
- if (strlen(state->current[i].name) == 0) {
+ if (strlen(state->current[i].name) == 0U) {
continue;
}
- result = state->putnamedrr(allnodes, state->current[i].name, state->current[i].type,
- state->current[i].ttl, state->current[i].data);
- if (result != ISC_R_SUCCESS) {
- return result;
- }
+ result = state->putnamedrr(allnodes, state->current[i].name,
+ state->current[i].type,
+ state->current[i].ttl,
+ state->current[i].data);
+ if (result != ISC_R_SUCCESS)
+ return (result);
}
- return ISC_R_SUCCESS;
+ return (ISC_R_SUCCESS);
}
/*
- start a transaction
+ * Start a transaction
*/
-isc_result_t dlz_newversion(const char *zone, void *dbdata, void **versionp)
-{
+isc_result_t
+dlz_newversion(const char *zone, void *dbdata, void **versionp) {
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
if (state->transaction_started) {
- state->log(ISC_LOG_INFO, "dlz_example: transaction already started for zone %s", zone);
- return ISC_R_FAILURE;
+ state->log(ISC_LOG_INFO,
+ "dlz_example: transaction already "
+ "started for zone %s", zone);
+ return (ISC_R_FAILURE);
}
- state->transaction_started = true;
-
+ state->transaction_started = ISC_TRUE;
*versionp = (void *) &state->transaction_started;
- return ISC_R_SUCCESS;
+ return (ISC_R_SUCCESS);
}
/*
- end a transaction
+ * End a transaction
*/
-void dlz_closeversion(const char *zone, isc_boolean_t commit, void *dbdata, void **versionp)
+void
+dlz_closeversion(const char *zone, isc_boolean_t commit,
+ void *dbdata, void **versionp)
{
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
if (!state->transaction_started) {
- state->log(ISC_LOG_INFO, "dlz_example: transaction not started for zone %s", zone);
+ state->log(ISC_LOG_INFO,
+ "dlz_example: transaction not started for zone %s",
+ zone);
*versionp = NULL;
return;
}
- state->transaction_started = false;
+ state->transaction_started = ISC_FALSE;
*versionp = NULL;
if (commit) {
int i;
- state->log(ISC_LOG_INFO, "dlz_example: committing transaction on zone %s", zone);
- for (i=0; i<MAX_RECORDS; i++) {
- if (strlen(state->adds[i].name) > 0) {
- add_name(state, &state->current[0],
- state->adds[i].name,
- state->adds[i].type,
- state->adds[i].ttl,
+ state->log(ISC_LOG_INFO,
+ "dlz_example: committing transaction on zone %s",
+ zone);
+ for (i = 0; i < MAX_RECORDS; i++) {
+ if (strlen(state->adds[i].name) > 0U) {
+ add_name(state, &state->current[0],
+ state->adds[i].name,
+ state->adds[i].type,
+ state->adds[i].ttl,
state->adds[i].data);
}
}
- for (i=0; i<MAX_RECORDS; i++) {
- if (strlen(state->deletes[i].name) > 0) {
- del_name(state, &state->current[0],
- state->deletes[i].name,
- state->deletes[i].type,
- state->deletes[i].ttl,
+ for (i = 0; i < MAX_RECORDS; i++) {
+ if (strlen(state->deletes[i].name) > 0U) {
+ del_name(state, &state->current[0],
+ state->deletes[i].name,
+ state->deletes[i].type,
+ state->deletes[i].ttl,
state->deletes[i].data);
}
}
} else {
- state->log(ISC_LOG_INFO, "dlz_example: cancelling transaction on zone %s", zone);
+ state->log(ISC_LOG_INFO,
+ "dlz_example: cancelling transaction on zone %s",
+ zone);
}
memset(state->adds, 0, sizeof(state->adds));
memset(state->deletes, 0, sizeof(state->deletes));
/*
- configure a writeable zone
+ * Configure a writeable zone
*/
-isc_result_t dlz_configure(dns_view_t *view, void *dbdata)
-{
+isc_result_t
+dlz_configure(dns_view_t *view, void *dbdata) {
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
isc_result_t result;
state->log(ISC_LOG_INFO, "dlz_example: starting configure");
if (state->writeable_zone == NULL) {
- state->log(ISC_LOG_INFO, "dlz_example: no writeable_zone method available");
- return ISC_R_FAILURE;
+ state->log(ISC_LOG_INFO,
+ "dlz_example: no writeable_zone method available");
+ return (ISC_R_FAILURE);
}
result = state->writeable_zone(view, state->zone_name);
if (result != ISC_R_SUCCESS) {
- state->log(ISC_LOG_ERROR, "dlz_example: failed to configure zone %s", state->zone_name);
- return result;
+ state->log(ISC_LOG_ERROR,
+ "dlz_example: failed to configure zone %s",
+ state->zone_name);
+ return (result);
}
- state->log(ISC_LOG_INFO, "dlz_example: configured writeable zone %s", state->zone_name);
- return ISC_R_SUCCESS;
+ state->log(ISC_LOG_INFO,
+ "dlz_example: configured writeable zone %s",
+ state->zone_name);
+ return (ISC_R_SUCCESS);
}
/*
- authorize a zone update
+ * Authorize a zone update
*/
-isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
- const char *type, const char *key, uint32_t keydatalen, uint8_t *keydata,
- void *dbdata)
+isc_boolean_t
+dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr,
+ const char *type, const char *key, uint32_t keydatalen,
+ unsigned char *keydata, void *dbdata)
{
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
+
+ UNUSED(tcpaddr);
+ UNUSED(type);
+ UNUSED(key);
+ UNUSED(keydatalen);
+ UNUSED(keydata);
+
if (strncmp(name, "deny.", 5) == 0) {
- state->log(ISC_LOG_INFO, "dlz_example: denying update of name=%s by %s",
+ state->log(ISC_LOG_INFO,
+ "dlz_example: denying update of name=%s by %s",
name, signer);
- return false;
+ return (ISC_FALSE);
}
- state->log(ISC_LOG_INFO, "dlz_example: allowing update of name=%s by %s",
+ state->log(ISC_LOG_INFO,
+ "dlz_example: allowing update of name=%s by %s",
name, signer);
- return true;
+ return (ISC_TRUE);
}
-static isc_result_t modrdataset(struct dlz_example_data *state, const char *name, const char *rdatastr,
- struct record *list)
+static isc_result_t
+modrdataset(struct dlz_example_data *state, const char *name,
+ const char *rdatastr, struct record *list)
{
char *full_name, *dclass, *type, *data, *ttlstr;
char *buf = strdup(rdatastr);
isc_result_t result;
+#if defined(WIN32) || defined(_REENTRANT)
char *saveptr = NULL;
+#endif
/*
- the format is:
- FULLNAME\tTTL\tDCLASS\tTYPE\tDATA
-
- The DATA field is space separated, and is in the data format
- for the type used by dig
+ * The format is:
+ * FULLNAME\tTTL\tDCLASS\tTYPE\tDATA
+ *
+ * The DATA field is space separated, and is in the data format
+ * for the type used by dig
*/
- full_name = strtok_r(buf, "\t", &saveptr);
- if (full_name == NULL) return ISC_R_FAILURE;
- ttlstr = strtok_r(NULL, "\t", &saveptr);
- if (ttlstr == NULL) return ISC_R_FAILURE;
- dclass = strtok_r(NULL, "\t", &saveptr);
- if (dclass == NULL) return ISC_R_FAILURE;
- type = strtok_r(NULL, "\t", &saveptr);
- if (type == NULL) return ISC_R_FAILURE;
- data = strtok_r(NULL, "\t", &saveptr);
- if (data == NULL) return ISC_R_FAILURE;
-
- result = add_name(state, list, name, type, strtoul(ttlstr, NULL, 10), data);
+ full_name = STRTOK_R(buf, "\t", &saveptr);
+ if (full_name == NULL)
+ return (ISC_R_FAILURE);
+
+ ttlstr = STRTOK_R(NULL, "\t", &saveptr);
+ if (ttlstr == NULL)
+ return (ISC_R_FAILURE);
+
+ dclass = STRTOK_R(NULL, "\t", &saveptr);
+ if (dclass == NULL)
+ return (ISC_R_FAILURE);
+
+ type = STRTOK_R(NULL, "\t", &saveptr);
+ if (type == NULL)
+ return (ISC_R_FAILURE);
+
+ data = STRTOK_R(NULL, "\t", &saveptr);
+ if (data == NULL)
+ return (ISC_R_FAILURE);
+
+ result = add_name(state, list, name, type,
+ strtoul(ttlstr, NULL, 10), data);
free(buf);
- return result;
+ return (result);
}
-isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata, void *version)
+isc_result_t
+dlz_addrdataset(const char *name, const char *rdatastr,
+ void *dbdata, void *version)
{
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
- if (version != (void *) &state->transaction_started) {
- return ISC_R_FAILURE;
- }
+ if (version != (void *) &state->transaction_started)
+ return (ISC_R_FAILURE);
- state->log(ISC_LOG_INFO, "dlz_example: adding rdataset %s '%s'", name, rdatastr);
+ state->log(ISC_LOG_INFO,
+ "dlz_example: adding rdataset %s '%s'",
+ name, rdatastr);
- return modrdataset(state, name, rdatastr, &state->adds[0]);
+ return (modrdataset(state, name, rdatastr, &state->adds[0]));
}
-isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, void *dbdata, void *version)
+isc_result_t
+dlz_subrdataset(const char *name, const char *rdatastr,
+ void *dbdata, void *version)
{
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
- if (version != (void *) &state->transaction_started) {
- return ISC_R_FAILURE;
- }
+ if (version != (void *) &state->transaction_started)
+ return (ISC_R_FAILURE);
- state->log(ISC_LOG_INFO, "dlz_example: subtracting rdataset %s '%s'", name, rdatastr);
-
- return modrdataset(state, name, rdatastr, &state->deletes[0]);
+ state->log(ISC_LOG_INFO,
+ "dlz_example: subtracting rdataset %s '%s'",
+ name, rdatastr);
+
+ return (modrdataset(state, name, rdatastr, &state->deletes[0]));
}
-isc_result_t dlz_delrdataset(const char *name, const char *type, void *dbdata, void *version)
+isc_result_t
+dlz_delrdataset(const char *name, const char *type,
+ void *dbdata, void *version)
{
struct dlz_example_data *state = (struct dlz_example_data *)dbdata;
- if (version != (void *) &state->transaction_started) {
- return ISC_R_FAILURE;
- }
+ if (version != (void *) &state->transaction_started)
+ return (ISC_R_FAILURE);
+
+ state->log(ISC_LOG_INFO,
+ "dlz_example: deleting rdataset %s of type %s",
+ name, type);
- state->log(ISC_LOG_INFO, "dlz_example: deleting rdataset %s of type %s", name, type);
-
- return ISC_R_SUCCESS;
+ return (ISC_R_SUCCESS);
}