summaryrefslogtreecommitdiffstats
path: root/contrib/dlz/example/README
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dlz/example/README')
-rw-r--r--contrib/dlz/example/README256
1 files changed, 256 insertions, 0 deletions
diff --git a/contrib/dlz/example/README b/contrib/dlz/example/README
new file mode 100644
index 0000000..d87812a
--- /dev/null
+++ b/contrib/dlz/example/README
@@ -0,0 +1,256 @@
+<!--
+Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+
+SPDX-License-Identifier: MPL-2.0
+
+This Source Code Form is subject to the terms of the Mozilla Public
+License, v. 2.0. If a copy of the MPL was not distributed with this
+file, you can obtain one at https://mozilla.org/MPL/2.0/.
+
+See the COPYRIGHT file distributed with this work for additional
+information regarding copyright ownership.
+-->
+
+OVERVIEW:
+
+DLZ (Dynamically Loadable Zones) is an extension 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 unless using older DLZ drivers.
+
+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
+primary configuration, with secondaries retrieving zone updates via AXFR.
+(Note, however, that DLZ has no built-in support for DNS notify; secondaries
+are not automatically informed of changes to the zones in the database.)
+
+CONFIGURING DLZ:
+
+A DLZ database is configured with a "dlz" statement in named.conf.
+
+ dlz example {
+ database "dlopen driver.so <args>";
+ search yes;
+ };
+
+This specifies a DLZ module to search when answering queries; the module
+is implemented in "driver.so" and is loaded at runtime by the dlopen DLZ
+driver. Multiple "dlz" statements can be specified; when answering a
+query, all DLZ modules with the "search" option set to "yes" will be
+checked for an answer, and the best available answer will be returned
+to the client.
+
+The "search" option in this example can be omitted, as "yes" is the
+default value. If it is set to "no", then this DLZ module is *not*
+searched for best-match when a query is received. Instead, zones in
+this DLZ must be separately specified in a zone statement. This can
+be useful when conventional zone semantics are desired but you wish
+to use a different back-end storage mechanism than the standard zone
+database. For example, to use a DLZ module for an NXDOMAIN redirection
+zone:
+
+ dlz other {
+ database "dlopen driver.so <args>";
+ search no;
+ };
+
+ zone "." {
+ type redirect;
+ dlz other;
+ };
+
+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.)
+
+DYNAMIC UPDATES AND TRANSACTIONS:
+
+If a DLZ module wants to implement dynamic DNS updates (DDNS), the
+normal calling sequence is
+ - dlz_newversion (start a 'transaction')
+ - dlz_addrdataset (add records)
+ - dlz_subrdataset (remove records)
+ - dlz_closeversion (end a 'transaction')
+
+However, BIND may also query the database during the transaction
+(e.g., to check prerequisites), and your DLZ might need to know whether
+the lookup is against the pre-existing data, or the new data.
+dlz_lookup() doesn't give you access to the 'versionp' pointer
+directly, so it must be passed via 'clientinfo' structure if
+it is needed.
+
+The dlz_example.c code has sample code to show how to get the 'versionp'
+pointer from within dlz_lookup(). If it's set to NULL, we query
+the standard database; if non-NULL, we query against the in-flight
+data within the appropriate uncommitted transaction.
+
+IMPLEMENTATION NOTES:
+
+The minimal set of type definitions, prototypes, and macros needed
+for implementing a DLZ driver is in ../modules/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 writeable_zone(dns_view_t *view, const char *zone_name);
+
+ Allows the DLZ module to inform named that a given zone can receive
+ DDNS updates. (Note: This is not currently supported for DLZ
+ databases that are configured as 'search no;')
+
+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 the file
+ contrib/dlz/modules/dlz_minimal.h and is currently 3. '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,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo);
+
+ Required for all external DLZ modules. This indicates whether
+ the DLZ module can answer for the given name. Returns ISC_R_SUCCESS
+ if so, and ISC_R_NOTFOUND if not. As an optimization, it can
+ also return ISC_R_NOMORE: this indicates that the DLZ module has
+ no data for the given name or for any name above it in the DNS.
+ This prevents named from searching for a zone cut.
+
+ - 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, bool 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.
+
+ - bool 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.