a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Database API implementation. The interface is defined in lib/dns/db.h.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * dns_db_*() calls on database instances backed by this driver use
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * struct sampledb_methods to find appropriate function implementation.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * This example re-uses RBT DB implementation from original BIND and blindly
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * proxies most of dns_db_*() calls to this underlying RBT DB.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * See struct sampledb below.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Copyright (C) 2009-2015 Red Hat ; see COPYRIGHT for license
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt#define SAMPLEDB_MAGIC ISC_MAGIC('S', 'M', 'D', 'B')
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt ((sampledb) != NULL && (sampledb)->common.impmagic == SAMPLEDB_MAGIC)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Internal RBT database implementation provided by BIND.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Most dns_db_* calls (find(), createiterator(), etc.)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * are blindly forwarded to this RBT DB.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Get full DNS name from the node.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * The code silently expects that "node" came from RBTDB and thus
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * assumption dns_dbnode_t (from RBTDB) == dns_rbtnode_t is correct.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * This should work as long as we use only RBTDB and nothing else.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntsample_name_fromnode(dns_dbnode_t *node, dns_name_t *name) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_name_free(&sampledb->common.origin, sampledb->common.mctx);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_mem_putanddetach(&sampledb->common.mctx, sampledb, sizeof(*sampledb));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * This method should never be called, because DB is "persistent".
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * See ispersistent() function. It means that database do not need to be
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * loaded in the usual sense.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntbeginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt fatal_error("current implementation should never call beginload()");
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Not reached */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * This method should never be called, because DB is "persistent".
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * See ispersistent() function. It means that database do not need to be
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * loaded in the usual sense.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntendload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt fatal_error("current implementation should never call endload()");
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Not reached */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntserialize(dns_db_t *db, dns_dbversion_t *version, FILE *file) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_serialize(sampledb->rbtdb, version, file));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt fatal_error("current implementation should never call dump()");
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Not reached */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntcurrentversion(dns_db_t *db, dns_dbversion_t **versionp) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntnewversion(dns_db_t *db, dns_dbversion_t **versionp) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_newversion(sampledb->rbtdb, versionp));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntattachversion(dns_db_t *db, dns_dbversion_t *source,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_db_attachversion(sampledb->rbtdb, source, targetp);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntcloseversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_db_closeversion(sampledb->rbtdb, versionp, commit);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntfindnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_findnode(sampledb->rbtdb, name, create, nodep));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntfind(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_find(sampledb->rbtdb, name, version, type,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntfindzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_findzonecut(sampledb->rbtdb, name, options,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntattachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_db_attachnode(sampledb->rbtdb, source, targetp);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntexpirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_expirenode(sampledb->rbtdb, node, now));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntprintnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_createiterator(sampledb->rbtdb, options, iteratorp));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntfindrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_findrdataset(sampledb->rbtdb, node, version, type,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntallrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_allrdatasets(sampledb->rbtdb, node, version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntaddrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_addrdataset(sampledb->rbtdb, node, version, now,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(sample_name_fromnode(node, dns_fixedname_name(&name)));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(syncptrs(sampledb->inst, dns_fixedname_name(&name),
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntsubtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt result = dns_db_subtractrdataset(sampledb->rbtdb, node, version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(sample_name_fromnode(node, dns_fixedname_name(&name)));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(syncptrs(sampledb->inst, dns_fixedname_name(&name),
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * deleterdataset() function is not used during DNS update processing so syncptr
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * implementation is left as an exercise to the reader.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntdeleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_deleterdataset(sampledb->rbtdb, node, version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntstatic unsigned int
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * The database does not need to be loaded from disk or written to disk.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Always return ISC_TRUE.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntgetoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_getoriginnode(sampledb->rbtdb, nodep));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunttransfernode(dns_db_t *db, dns_dbnode_t **sourcep, dns_dbnode_t **targetp) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_db_transfernode(sampledb->rbtdb, sourcep, targetp);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntgetnsec3parameters(dns_db_t *db, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_getnsec3parameters(sampledb->rbtdb, version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntfindnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_findnsec3node(sampledb->rbtdb, name, create, nodep));
93c211afc97e7a072c12ef346581065e4065ff15Evan Huntsetsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_setsigningtime(sampledb->rbtdb, rdataset, resign));
93c211afc97e7a072c12ef346581065e4065ff15Evan Huntgetsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_getsigningtime(sampledb->rbtdb, rdataset, name));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntresigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_db_resigned(sampledb->rbtdb, rdataset, version);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntrpz_attach(dns_db_t *db, dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num) {
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_db_rpz_attach(sampledb->rbtdb, rpzs, rpz_num);
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt isc_boolean_t create, dns_clientinfomethods_t *methods,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_findnodeext(sampledb->rbtdb, name, create,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntfindext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_findext(sampledb->rbtdb, name, version, type,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt return (dns_db_setcachestats(sampledb->rbtdb, stats));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * DB interface definition. Database driver uses this structure to
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * determine which implementation of dns_db_*() function to call.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt/* Auxiliary driver functions. */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Auxiliary functions add_*() create minimal database which can be loaded.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * This is necessary because this driver create empty 'fake' zone which
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * is not loaded from disk so there is no way for user to supply SOA, NS and A
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Following functions were copied from BIND 9.10.2rc1 named/server.c,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * credit goes to ISC.
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntadd_soa(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_soa_buildrdata(origin, contact, dns_db_class(db),
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntadd_ns(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntadd_a(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_a,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * Driver-specific implementation of dns_db_create().
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * @param[in] argv Database-specific parameters from dns_db_create().
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt * @param[in] driverarg Driver-specific parameter from dns_db_register().
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Huntcreate_db(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt REQUIRE(driverarg != NULL); /* pointer to driver instance */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt UNUSED(driverarg); /* no driver-specific configuration */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Translate instance name to instance pointer. */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Create internal instance of RBT DB implementation from BIND. */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_create(mctx, "rbt", origin, dns_dbtype_zone,
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt /* Create fake SOA, NS, and A records to make database loadable. */
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(dns_db_newversion(sampledb->rbtdb, &version));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(add_soa(sampledb->rbtdb, version, origin, origin, origin));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(add_ns(sampledb->rbtdb, version, origin, origin));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt CHECK(add_a(sampledb->rbtdb, version, origin, a_addr));
a00f9e2f50675bd43cc6a9fe2669709162a2ccb4Evan Hunt dns_db_closeversion(sampledb->rbtdb, &version, ISC_TRUE);