2005-09-06 03:51:37 +00:00
|
|
|
/*
|
2011-03-12 04:59:49 +00:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2021-06-03 08:37:05 +02:00
|
|
|
*
|
2011-03-12 04:59:49 +00:00
|
|
|
* SPDX-License-Identifier: MPL-2.0 AND ISC
|
2005-09-06 03:51:37 +00:00
|
|
|
*
|
|
|
|
* 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/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
2005-09-06 03:51:37 +00:00
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
2005-09-05 00:12:29 +00:00
|
|
|
* information regarding copyright ownership.
|
2005-09-06 03:51:37 +00:00
|
|
|
*/
|
|
|
|
|
2005-09-05 00:12:29 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
|
|
|
|
* 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 development of Dynamically Loadable Zones (DLZ) for Bind 9 was
|
|
|
|
* conceived and contributed by Rob Butler.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
|
|
|
|
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
|
|
|
* ROB BUTLER 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*! \file */
|
|
|
|
|
|
|
|
/***
|
|
|
|
*** Imports
|
|
|
|
***/
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
2005-09-05 00:12:29 +00:00
|
|
|
#include <isc/buffer.h>
|
2015-09-28 23:12:35 -07:00
|
|
|
#include <isc/commandline.h>
|
2024-08-14 13:25:50 +02:00
|
|
|
#include <isc/log.h>
|
2005-09-05 00:12:29 +00:00
|
|
|
#include <isc/magic.h>
|
|
|
|
#include <isc/mem.h>
|
2022-03-17 23:37:26 +01:00
|
|
|
#include <isc/netmgr.h>
|
|
|
|
#include <isc/random.h>
|
2005-09-05 00:12:29 +00:00
|
|
|
#include <isc/rwlock.h>
|
|
|
|
#include <isc/string.h>
|
|
|
|
#include <isc/util.h>
|
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
#include <dns/db.h>
|
|
|
|
#include <dns/dlz.h>
|
2005-09-05 00:12:29 +00:00
|
|
|
#include <dns/fixedname.h>
|
|
|
|
#include <dns/master.h>
|
2010-12-18 01:56:23 +00:00
|
|
|
#include <dns/ssu.h>
|
|
|
|
#include <dns/zone.h>
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2025-02-04 13:17:31 +01:00
|
|
|
#include "dlz_p.h"
|
|
|
|
|
2005-09-05 00:12:29 +00:00
|
|
|
/***
|
|
|
|
*** Supported DLZ DB Implementations Registry
|
|
|
|
***/
|
|
|
|
|
|
|
|
static ISC_LIST(dns_dlzimplementation_t) dlz_implementations;
|
|
|
|
static isc_rwlock_t dlz_implock;
|
|
|
|
|
2025-02-04 13:17:31 +01:00
|
|
|
void
|
|
|
|
dns__dlz_initialize(void) {
|
Add the reader-writer synchronization with modified C-RW-WP
This changes the internal isc_rwlock implementation to:
Irina Calciu, Dave Dice, Yossi Lev, Victor Luchangco, Virendra
J. Marathe, and Nir Shavit. 2013. NUMA-aware reader-writer locks.
SIGPLAN Not. 48, 8 (August 2013), 157–166.
DOI:https://doi.org/10.1145/2517327.24425
(The full article available from:
http://mcg.cs.tau.ac.il/papers/ppopp2013-rwlocks.pdf)
The implementation is based on the The Writer-Preference Lock (C-RW-WP)
variant (see the 3.4 section of the paper for the rationale).
The implemented algorithm has been modified for simplicity and for usage
patterns in rbtdb.c.
The changes compared to the original algorithm:
* We haven't implemented the cohort locks because that would require a
knowledge of NUMA nodes, instead a simple atomic_bool is used as
synchronization point for writer lock.
* The per-thread reader counters are not being used - this would
require the internal thread id (isc_tid_v) to be always initialized,
even in the utilities; the change has a slight performance penalty,
so we might revisit this change in the future. However, this change
also saves a lot of memory, because cache-line aligned counters were
used, so on 32-core machine, the rwlock would be 4096+ bytes big.
* The readers use a writer_barrier that will raise after a while when
readers lock can't be acquired to prevent readers starvation.
* Separate ingress and egress readers counters queues to reduce both
inter and intra-thread contention.
2021-03-24 17:52:56 +01:00
|
|
|
isc_rwlock_init(&dlz_implock);
|
2005-09-05 00:12:29 +00:00
|
|
|
ISC_LIST_INIT(dlz_implementations);
|
|
|
|
}
|
|
|
|
|
2025-02-04 13:17:31 +01:00
|
|
|
void
|
|
|
|
dns__dlz_shutdown(void) {
|
|
|
|
isc_rwlock_destroy(&dlz_implock);
|
|
|
|
}
|
|
|
|
|
2005-09-05 00:12:29 +00:00
|
|
|
/*%
|
|
|
|
* Searches the dlz_implementations list for a driver matching name.
|
|
|
|
*/
|
2021-10-11 13:43:12 +02:00
|
|
|
static dns_dlzimplementation_t *
|
2005-09-05 00:12:29 +00:00
|
|
|
dlz_impfind(const char *name) {
|
|
|
|
dns_dlzimplementation_t *imp;
|
|
|
|
|
|
|
|
for (imp = ISC_LIST_HEAD(dlz_implementations); imp != NULL;
|
2020-02-13 18:16:57 +01:00
|
|
|
imp = ISC_LIST_NEXT(imp, link))
|
|
|
|
{
|
|
|
|
if (strcasecmp(name, imp->name) == 0) {
|
2005-09-05 00:12:29 +00:00
|
|
|
return imp;
|
2020-02-13 18:16:57 +01:00
|
|
|
}
|
|
|
|
}
|
2005-09-05 00:12:29 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
|
|
*** Basic DLZ Methods
|
|
|
|
***/
|
|
|
|
|
|
|
|
isc_result_t
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_dlzallowzonexfr(dns_view_t *view, const dns_name_t *name,
|
|
|
|
const isc_sockaddr_t *clientaddr, dns_db_t **dbp) {
|
2012-12-06 12:39:52 -08:00
|
|
|
isc_result_t result = ISC_R_NOTFOUND;
|
2005-09-05 00:12:29 +00:00
|
|
|
dns_dlzallowzonexfr_t allowzonexfr;
|
2012-12-06 12:39:52 -08:00
|
|
|
dns_dlzdb_t *dlzdb;
|
2005-09-05 00:12:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Performs checks to make sure data is as we expect it to be.
|
|
|
|
*/
|
|
|
|
REQUIRE(name != NULL);
|
|
|
|
REQUIRE(dbp != NULL && *dbp == NULL);
|
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
/*
|
|
|
|
* Find a driver in which the zone exists and transfer is supported
|
|
|
|
*/
|
|
|
|
for (dlzdb = ISC_LIST_HEAD(view->dlz_searched); dlzdb != NULL;
|
|
|
|
dlzdb = ISC_LIST_NEXT(dlzdb, link))
|
|
|
|
{
|
|
|
|
REQUIRE(DNS_DLZ_VALID(dlzdb));
|
|
|
|
|
|
|
|
allowzonexfr = dlzdb->implementation->methods->allowzonexfr;
|
|
|
|
result = (*allowzonexfr)(dlzdb->implementation->driverarg,
|
|
|
|
dlzdb->dbdata, dlzdb->mctx,
|
|
|
|
view->rdclass, name, clientaddr, dbp);
|
|
|
|
|
|
|
|
/*
|
2019-01-02 17:29:59 +11:00
|
|
|
* In these cases, we found the right database. Non-success
|
|
|
|
* result codes indicate the zone might not transfer.
|
2012-12-06 12:39:52 -08:00
|
|
|
*/
|
2019-01-02 17:29:59 +11:00
|
|
|
switch (result) {
|
|
|
|
case ISC_R_SUCCESS:
|
|
|
|
case ISC_R_NOPERM:
|
|
|
|
case ISC_R_DEFAULT:
|
2012-12-06 12:39:52 -08:00
|
|
|
return result;
|
2019-01-02 17:29:59 +11:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-12-06 12:39:52 -08:00
|
|
|
}
|
2005-09-05 00:12:29 +00:00
|
|
|
|
|
|
|
if (result == ISC_R_NOTIMPLEMENTED) {
|
2012-12-06 12:39:52 -08:00
|
|
|
result = ISC_R_NOTFOUND;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-12-06 12:39:52 -08:00
|
|
|
|
2005-09-05 00:12:29 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
|
|
|
|
unsigned int argc, char *argv[], dns_dlzdb_t **dbp) {
|
|
|
|
dns_dlzimplementation_t *impinfo;
|
|
|
|
isc_result_t result;
|
2013-02-19 07:28:24 +11:00
|
|
|
dns_dlzdb_t *db = NULL;
|
2005-09-05 00:12:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Performs checks to make sure data is as we expect it to be.
|
|
|
|
*/
|
|
|
|
REQUIRE(dbp != NULL && *dbp == NULL);
|
|
|
|
REQUIRE(dlzname != NULL);
|
|
|
|
REQUIRE(drivername != NULL);
|
|
|
|
REQUIRE(mctx != NULL);
|
|
|
|
|
|
|
|
/* write log message */
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
|
|
|
|
"Loading '%s' using driver %s", dlzname, drivername);
|
2005-09-05 00:12:29 +00:00
|
|
|
|
|
|
|
/* lock the dlz_implementations list so we can search it. */
|
|
|
|
RWLOCK(&dlz_implock, isc_rwlocktype_read);
|
|
|
|
|
|
|
|
/* search for the driver implementation */
|
|
|
|
impinfo = dlz_impfind(drivername);
|
|
|
|
if (impinfo == NULL) {
|
|
|
|
RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
|
|
|
|
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
|
|
|
ISC_LOG_ERROR,
|
2005-09-05 00:12:29 +00:00
|
|
|
"unsupported DLZ database driver '%s'."
|
|
|
|
" %s not loaded.",
|
|
|
|
drivername, dlzname);
|
|
|
|
|
|
|
|
return ISC_R_NOTFOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate memory to hold the DLZ database driver */
|
2022-08-26 11:58:51 +02:00
|
|
|
db = isc_mem_get(mctx, sizeof(*db));
|
|
|
|
*db = (dns_dlzdb_t){
|
|
|
|
.implementation = impinfo,
|
|
|
|
};
|
2005-09-05 00:12:29 +00:00
|
|
|
|
2013-02-19 07:28:24 +11:00
|
|
|
ISC_LINK_INIT(db, link);
|
2012-12-06 12:39:52 -08:00
|
|
|
if (dlzname != NULL) {
|
2013-02-19 07:28:24 +11:00
|
|
|
db->dlzname = isc_mem_strdup(mctx, dlzname);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-12-06 12:39:52 -08:00
|
|
|
|
2005-09-05 00:12:29 +00:00
|
|
|
/* Create a new database using implementation 'drivername'. */
|
|
|
|
result = ((impinfo->methods->create)(mctx, dlzname, argc, argv,
|
|
|
|
impinfo->driverarg, &db->dbdata));
|
|
|
|
|
2022-08-26 11:58:51 +02:00
|
|
|
RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
|
2005-09-05 00:12:29 +00:00
|
|
|
/* mark the DLZ driver as valid */
|
2022-08-26 11:58:51 +02:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto failure;
|
2005-09-05 00:12:29 +00:00
|
|
|
}
|
|
|
|
|
2022-08-26 11:58:51 +02:00
|
|
|
db->magic = DNS_DLZ_MAGIC;
|
|
|
|
isc_mem_attach(mctx, &db->mctx);
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
2022-08-26 11:58:51 +02:00
|
|
|
ISC_LOG_DEBUG(2), "DLZ driver loaded successfully.");
|
|
|
|
*dbp = db;
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
failure:
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
2022-08-26 11:58:51 +02:00
|
|
|
ISC_LOG_ERROR, "DLZ driver failed to load.");
|
|
|
|
|
2005-09-05 00:12:29 +00:00
|
|
|
/* impinfo->methods->create failed. */
|
2022-01-04 18:49:20 +00:00
|
|
|
isc_mem_free(mctx, db->dlzname);
|
2022-08-26 11:58:51 +02:00
|
|
|
isc_mem_put(mctx, db, sizeof(*db));
|
2005-09-05 00:12:29 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
dns_dlzdestroy(dns_dlzdb_t **dbp) {
|
|
|
|
dns_dlzdestroy_t destroy;
|
2015-05-28 13:17:07 +10:00
|
|
|
dns_dlzdb_t *db;
|
2005-09-05 00:12:29 +00:00
|
|
|
|
|
|
|
/* Write debugging message to log */
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
2005-09-05 00:12:29 +00:00
|
|
|
ISC_LOG_DEBUG(2), "Unloading DLZ driver.");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Perform checks to make sure data is as we expect it to be.
|
|
|
|
*/
|
|
|
|
REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp));
|
|
|
|
|
2015-05-28 13:17:07 +10:00
|
|
|
db = *dbp;
|
|
|
|
*dbp = NULL;
|
2012-12-06 12:39:52 -08:00
|
|
|
|
2015-05-28 13:17:07 +10:00
|
|
|
if (db->ssutable != NULL) {
|
|
|
|
dns_ssutable_detach(&db->ssutable);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-09-05 00:12:29 +00:00
|
|
|
|
2015-05-28 13:17:07 +10:00
|
|
|
/* call the drivers destroy method */
|
|
|
|
if (db->dlzname != NULL) {
|
|
|
|
isc_mem_free(db->mctx, db->dlzname);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2015-05-28 13:17:07 +10:00
|
|
|
destroy = db->implementation->methods->destroy;
|
|
|
|
(*destroy)(db->implementation->driverarg, db->dbdata);
|
|
|
|
/* return memory and detach */
|
2022-08-26 11:58:51 +02:00
|
|
|
isc_mem_putanddetach(&db->mctx, db, sizeof(*db));
|
2005-09-05 00:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Registers a DLZ driver. This basically just adds the dlz
|
|
|
|
* driver to the list of available drivers in the dlz_implementations list.
|
|
|
|
*/
|
|
|
|
isc_result_t
|
|
|
|
dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods,
|
|
|
|
void *driverarg, isc_mem_t *mctx,
|
|
|
|
dns_dlzimplementation_t **dlzimp) {
|
|
|
|
dns_dlzimplementation_t *dlz_imp;
|
|
|
|
|
|
|
|
/* Write debugging message to log */
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
2005-09-05 00:12:29 +00:00
|
|
|
ISC_LOG_DEBUG(2), "Registering DLZ driver '%s'",
|
|
|
|
drivername);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Performs checks to make sure data is as we expect it to be.
|
|
|
|
*/
|
|
|
|
REQUIRE(drivername != NULL);
|
|
|
|
REQUIRE(methods != NULL);
|
|
|
|
REQUIRE(methods->create != NULL);
|
|
|
|
REQUIRE(methods->destroy != NULL);
|
|
|
|
REQUIRE(methods->findzone != NULL);
|
|
|
|
REQUIRE(mctx != NULL);
|
|
|
|
REQUIRE(dlzimp != NULL && *dlzimp == NULL);
|
|
|
|
|
|
|
|
/* lock the dlz_implementations list so we can modify it. */
|
|
|
|
RWLOCK(&dlz_implock, isc_rwlocktype_write);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* check that another already registered driver isn't using
|
|
|
|
* the same name
|
|
|
|
*/
|
|
|
|
dlz_imp = dlz_impfind(drivername);
|
|
|
|
if (dlz_imp != NULL) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
|
|
|
ISC_LOG_DEBUG(2),
|
2005-09-05 00:12:29 +00:00
|
|
|
"DLZ Driver '%s' already registered", drivername);
|
|
|
|
RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
|
|
|
|
return ISC_R_EXISTS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate memory for a dlz_implementation object. Error if
|
|
|
|
* we cannot.
|
|
|
|
*/
|
2022-08-26 11:58:51 +02:00
|
|
|
dlz_imp = isc_mem_get(mctx, sizeof(*dlz_imp));
|
|
|
|
*dlz_imp = (dns_dlzimplementation_t){
|
|
|
|
.name = drivername,
|
|
|
|
.methods = methods,
|
|
|
|
.driverarg = driverarg,
|
|
|
|
};
|
2005-09-05 00:12:29 +00:00
|
|
|
|
|
|
|
/* attach the new dlz_implementation object to a memory context */
|
|
|
|
isc_mem_attach(mctx, &dlz_imp->mctx);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* prepare the dlz_implementation object to be put in a list,
|
|
|
|
* and append it to the list
|
|
|
|
*/
|
|
|
|
ISC_LINK_INIT(dlz_imp, link);
|
|
|
|
ISC_LIST_APPEND(dlz_implementations, dlz_imp, link);
|
|
|
|
|
|
|
|
/* Unlock the dlz_implementations list. */
|
|
|
|
RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
|
|
|
|
|
|
|
|
/* Pass back the dlz_implementation that we created. */
|
|
|
|
*dlzimp = dlz_imp;
|
|
|
|
|
|
|
|
return ISC_R_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Tokenize the string "s" into whitespace-separated words,
|
|
|
|
* return the number of words in '*argcp' and an array
|
|
|
|
* of pointers to the words in '*argvp'. The caller
|
|
|
|
* must free the array using isc_mem_put(). The string
|
|
|
|
* is modified in-place.
|
|
|
|
*/
|
|
|
|
isc_result_t
|
|
|
|
dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) {
|
2015-09-28 23:12:35 -07:00
|
|
|
return isc_commandline_strtoargv(mctx, s, argcp, argvp, 0);
|
2005-09-05 00:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Unregisters a DLZ driver. This basically just removes the dlz
|
|
|
|
* driver from the list of available drivers in the dlz_implementations list.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
dns_dlzunregister(dns_dlzimplementation_t **dlzimp) {
|
|
|
|
dns_dlzimplementation_t *dlz_imp;
|
|
|
|
|
|
|
|
/* Write debugging message to log */
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
2005-09-05 00:12:29 +00:00
|
|
|
ISC_LOG_DEBUG(2), "Unregistering DLZ driver.");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Performs checks to make sure data is as we expect it to be.
|
|
|
|
*/
|
|
|
|
REQUIRE(dlzimp != NULL && *dlzimp != NULL);
|
|
|
|
|
|
|
|
dlz_imp = *dlzimp;
|
|
|
|
|
|
|
|
/* lock the dlz_implementations list so we can modify it. */
|
|
|
|
RWLOCK(&dlz_implock, isc_rwlocktype_write);
|
|
|
|
|
|
|
|
/* remove the dlz_implementation object from the list */
|
|
|
|
ISC_LIST_UNLINK(dlz_implementations, dlz_imp, link);
|
|
|
|
|
|
|
|
/*
|
2010-12-18 01:56:23 +00:00
|
|
|
* Return the memory back to the available memory pool and
|
2005-09-05 00:12:29 +00:00
|
|
|
* remove it from the memory context.
|
|
|
|
*/
|
2019-07-23 17:16:57 -04:00
|
|
|
isc_mem_putanddetach(&dlz_imp->mctx, dlz_imp, sizeof(*dlz_imp));
|
2005-09-05 00:12:29 +00:00
|
|
|
|
|
|
|
/* Unlock the dlz_implementations list. */
|
|
|
|
RWUNLOCK(&dlz_implock, isc_rwlocktype_write);
|
|
|
|
}
|
2010-12-18 01:56:23 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a writeable DLZ zone. This can be called by DLZ drivers
|
|
|
|
* during configure() to create a zone that can be updated. The zone
|
2021-10-05 11:07:44 +02:00
|
|
|
* type is set to dns_zone_dlz, which is equivalent to a primary zone
|
2010-12-18 01:56:23 +00:00
|
|
|
*
|
|
|
|
* This function uses a callback setup in dns_dlzconfigure() to call
|
|
|
|
* into the server zone code to setup the remaining pieces of server
|
|
|
|
* specific functionality on the zone
|
|
|
|
*/
|
|
|
|
isc_result_t
|
2012-12-06 12:39:52 -08:00
|
|
|
dns_dlz_writeablezone(dns_view_t *view, dns_dlzdb_t *dlzdb,
|
|
|
|
const char *zone_name) {
|
2010-12-18 01:56:23 +00:00
|
|
|
dns_zone_t *zone = NULL;
|
|
|
|
dns_zone_t *dupzone = NULL;
|
|
|
|
isc_result_t result;
|
|
|
|
isc_buffer_t buffer;
|
|
|
|
dns_fixedname_t fixorigin;
|
|
|
|
dns_name_t *origin;
|
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
REQUIRE(DNS_DLZ_VALID(dlzdb));
|
2012-03-05 15:42:52 -08:00
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
REQUIRE(dlzdb->configure_callback != NULL);
|
2010-12-18 01:56:23 +00:00
|
|
|
|
2012-12-08 12:48:57 +11:00
|
|
|
isc_buffer_constinit(&buffer, zone_name, strlen(zone_name));
|
2010-12-18 01:56:23 +00:00
|
|
|
isc_buffer_add(&buffer, strlen(zone_name));
|
|
|
|
dns_fixedname_init(&fixorigin);
|
|
|
|
result = dns_name_fromtext(dns_fixedname_name(&fixorigin), &buffer,
|
2025-02-22 00:11:38 -08:00
|
|
|
dns_rootname, 0);
|
2010-12-18 01:56:23 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-12-18 01:56:23 +00:00
|
|
|
origin = dns_fixedname_name(&fixorigin);
|
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
if (!dlzdb->search) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
|
|
|
ISC_LOG_WARNING,
|
2012-12-06 12:39:52 -08:00
|
|
|
"DLZ %s has 'search no;', but attempted to "
|
|
|
|
"register writeable zone %s.",
|
|
|
|
dlzdb->dlzname, zone_name);
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2010-12-18 01:56:23 +00:00
|
|
|
/* See if the zone already exists */
|
2023-05-31 16:03:56 +10:00
|
|
|
result = dns_view_findzone(view, origin, DNS_ZTFIND_EXACT, &dupzone);
|
2010-12-18 01:56:23 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
dns_zone_detach(&dupzone);
|
|
|
|
result = ISC_R_EXISTS;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
INSIST(dupzone == NULL);
|
|
|
|
|
|
|
|
/* Create it */
|
2023-06-26 11:09:26 +02:00
|
|
|
dns_zone_create(&zone, view->mctx, 0);
|
2025-01-07 19:03:07 -08:00
|
|
|
dns_zone_setorigin(zone, origin);
|
2010-12-18 01:56:23 +00:00
|
|
|
dns_zone_setview(zone, view);
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
dns_zone_setadded(zone, true);
|
2010-12-18 01:56:23 +00:00
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
if (dlzdb->ssutable == NULL) {
|
2021-10-06 13:18:16 +02:00
|
|
|
dns_ssutable_createdlz(dlzdb->mctx, &dlzdb->ssutable, dlzdb);
|
2010-12-18 01:56:23 +00:00
|
|
|
}
|
2012-12-06 12:39:52 -08:00
|
|
|
dns_zone_setssutable(zone, dlzdb->ssutable);
|
2010-12-18 01:56:23 +00:00
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
result = dlzdb->configure_callback(view, dlzdb, zone);
|
2010-12-18 01:56:23 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-12-18 01:56:23 +00:00
|
|
|
|
|
|
|
result = dns_view_addzone(view, zone);
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (zone != NULL) {
|
|
|
|
dns_zone_detach(&zone);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-12-18 01:56:23 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*%
|
|
|
|
* Configure a DLZ driver. This is optional, and if supplied gives
|
|
|
|
* the backend an opportunity to configure parameters related to DLZ.
|
|
|
|
*/
|
|
|
|
isc_result_t
|
2012-12-06 12:39:52 -08:00
|
|
|
dns_dlzconfigure(dns_view_t *view, dns_dlzdb_t *dlzdb,
|
|
|
|
dlzconfigure_callback_t callback) {
|
2010-12-18 01:56:23 +00:00
|
|
|
dns_dlzimplementation_t *impl;
|
|
|
|
isc_result_t result;
|
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
REQUIRE(DNS_DLZ_VALID(dlzdb));
|
|
|
|
REQUIRE(dlzdb->implementation != NULL);
|
2010-12-18 01:56:23 +00:00
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
impl = dlzdb->implementation;
|
2010-12-18 01:56:23 +00:00
|
|
|
|
|
|
|
if (impl->methods->configure == NULL) {
|
|
|
|
return ISC_R_SUCCESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2010-12-18 01:56:23 +00:00
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
dlzdb->configure_callback = callback;
|
2010-12-18 01:56:23 +00:00
|
|
|
|
2012-12-06 12:39:52 -08:00
|
|
|
result = impl->methods->configure(impl->driverarg, dlzdb->dbdata, view,
|
|
|
|
dlzdb);
|
2010-12-18 01:56:23 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
bool
|
2016-12-30 15:45:08 +11:00
|
|
|
dns_dlz_ssumatch(dns_dlzdb_t *dlzdatabase, const dns_name_t *signer,
|
|
|
|
const dns_name_t *name, const isc_netaddr_t *tcpaddr,
|
2012-12-06 12:39:52 -08:00
|
|
|
dns_rdatatype_t type, const dst_key_t *key) {
|
2010-12-18 01:56:23 +00:00
|
|
|
dns_dlzimplementation_t *impl;
|
2018-04-17 08:29:14 -07:00
|
|
|
bool r;
|
2010-12-18 01:56:23 +00:00
|
|
|
|
|
|
|
REQUIRE(dlzdatabase != NULL);
|
|
|
|
REQUIRE(dlzdatabase->implementation != NULL);
|
|
|
|
REQUIRE(dlzdatabase->implementation->methods != NULL);
|
|
|
|
impl = dlzdatabase->implementation;
|
|
|
|
|
|
|
|
if (impl->methods->ssumatch == NULL) {
|
2024-08-13 18:20:26 +02:00
|
|
|
isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ,
|
|
|
|
ISC_LOG_INFO,
|
2010-12-18 01:56:23 +00:00
|
|
|
"No ssumatch method for DLZ database");
|
2018-04-17 08:29:14 -07:00
|
|
|
return false;
|
2010-12-18 01:56:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
r = impl->methods->ssumatch(signer, name, tcpaddr, type, key,
|
|
|
|
impl->driverarg, dlzdatabase->dbdata);
|
|
|
|
return r;
|
|
|
|
}
|