mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-28 21:17:54 +00:00
4376. [experimental] Added support for Catalog Zones, a new method for
provisioning secondary servers in which a list of zones to be served is stored in a DNS zone and can be propagated to slaves via AXFR/IXFR. [RT #41581] 4375. [func] Add support for automatic reallocation of isc_buffer to isc_buffer_put* functions. [RT #42394]
This commit is contained in:
parent
bfe9697f92
commit
7a00d69909
3
.gitignore
vendored
3
.gitignore
vendored
@ -55,3 +55,6 @@ unit/atf-src/test-programs/sh_helpers
|
|||||||
# ccc-analyzer store its results in .plist directories
|
# ccc-analyzer store its results in .plist directories
|
||||||
*.plist/
|
*.plist/
|
||||||
*~
|
*~
|
||||||
|
.project
|
||||||
|
.cproject
|
||||||
|
.settings
|
||||||
|
8
CHANGES
8
CHANGES
@ -1,3 +1,11 @@
|
|||||||
|
4376. [experimental] Added support for Catalog Zones, a new method for
|
||||||
|
provisioning secondary servers in which a list of
|
||||||
|
zones to be served is stored in a DNS zone and can
|
||||||
|
be propagated to slaves via AXFR/IXFR. [RT #41581]
|
||||||
|
|
||||||
|
4375. [func] Add support for automatic reallocation of isc_buffer
|
||||||
|
to isc_buffer_put* functions. [RT #42394]
|
||||||
|
|
||||||
4374. [bug] Use SAVE/RESTORE macros in query.c to reduce the
|
4374. [bug] Use SAVE/RESTORE macros in query.c to reduce the
|
||||||
probability of reference counting errors as seen
|
probability of reference counting errors as seen
|
||||||
in 4365. [RT #42405]
|
in 4365. [RT #42405]
|
||||||
|
@ -576,9 +576,7 @@ get_masters_def(const cfg_obj_t *cctx, const char *name,
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
||||||
isc_mem_t *mctx, isc_sockaddr_t **addrsp,
|
isc_mem_t *mctx, dns_ipkeylist_t *ipkl)
|
||||||
isc_dscp_t **dscpsp, dns_name_t ***keysp,
|
|
||||||
isc_uint32_t *countp)
|
|
||||||
{
|
{
|
||||||
isc_uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0;
|
isc_uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0;
|
||||||
isc_uint32_t listcount = 0, l = 0, j;
|
isc_uint32_t listcount = 0, l = 0, j;
|
||||||
@ -601,10 +599,10 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
|||||||
isc_dscp_t dscp;
|
isc_dscp_t dscp;
|
||||||
} *stack = NULL;
|
} *stack = NULL;
|
||||||
|
|
||||||
REQUIRE(addrsp != NULL && *addrsp == NULL);
|
REQUIRE(ipkl != NULL);
|
||||||
REQUIRE(dscpsp != NULL && *dscpsp == NULL);
|
REQUIRE(ipkl->addrs == NULL);
|
||||||
REQUIRE(keysp != NULL && *keysp == NULL);
|
REQUIRE(ipkl->keys == NULL);
|
||||||
REQUIRE(countp != NULL);
|
REQUIRE(ipkl->dscps == NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get system defaults.
|
* Get system defaults.
|
||||||
@ -857,10 +855,10 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
|||||||
|
|
||||||
INSIST(keycount == addrcount);
|
INSIST(keycount == addrcount);
|
||||||
|
|
||||||
*addrsp = addrs;
|
ipkl->addrs = addrs;
|
||||||
*dscpsp = dscps;
|
ipkl->dscps = dscps;
|
||||||
*keysp = keys;
|
ipkl->keys = keys;
|
||||||
*countp = addrcount;
|
ipkl->count = addrcount;
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
@ -886,37 +884,6 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
|
|
||||||
isc_dscp_t **dscpsp, dns_name_t ***keysp,
|
|
||||||
isc_uint32_t count)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
dns_name_t **keys;
|
|
||||||
|
|
||||||
REQUIRE(addrsp != NULL && *addrsp != NULL);
|
|
||||||
REQUIRE(dscpsp == NULL || *dscpsp != NULL);
|
|
||||||
REQUIRE(keysp != NULL && *keysp != NULL);
|
|
||||||
|
|
||||||
keys = *keysp;
|
|
||||||
|
|
||||||
isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t));
|
|
||||||
if (dscpsp != NULL)
|
|
||||||
isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t));
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
if (keys[i] == NULL)
|
|
||||||
continue;
|
|
||||||
if (dns_name_dynamic(keys[i]))
|
|
||||||
dns_name_free(keys[i], mctx);
|
|
||||||
isc_mem_put(mctx, keys[i], sizeof(dns_name_t));
|
|
||||||
}
|
|
||||||
isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *));
|
|
||||||
*addrsp = NULL;
|
|
||||||
if (dscpsp != NULL)
|
|
||||||
*dscpsp = NULL;
|
|
||||||
*keysp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
ns_config_getport(const cfg_obj_t *config, in_port_t *portp) {
|
ns_config_getport(const cfg_obj_t *config, in_port_t *portp) {
|
||||||
const cfg_obj_t *maps[3];
|
const cfg_obj_t *maps[3];
|
||||||
|
@ -64,14 +64,7 @@ ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
||||||
isc_mem_t *mctx, isc_sockaddr_t **addrsp,
|
isc_mem_t *mctx, dns_ipkeylist_t *ipkl);
|
||||||
isc_dscp_t **dscpp, dns_name_t ***keys,
|
|
||||||
isc_uint32_t *countp);
|
|
||||||
|
|
||||||
void
|
|
||||||
ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
|
|
||||||
isc_dscp_t **dscpsp, dns_name_t ***keys,
|
|
||||||
isc_uint32_t count);
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
ns_config_getport(const cfg_obj_t *config, in_port_t *portp);
|
ns_config_getport(const cfg_obj_t *config, in_port_t *portp);
|
||||||
|
@ -283,6 +283,16 @@ options {
|
|||||||
check-mx-cname ( fail | warn | ignore );
|
check-mx-cname ( fail | warn | ignore );
|
||||||
check-srv-cname ( fail | warn | ignore );
|
check-srv-cname ( fail | warn | ignore );
|
||||||
cache-file <replaceable>quoted_string</replaceable>; // test option
|
cache-file <replaceable>quoted_string</replaceable>; // test option
|
||||||
|
catalog-zones {
|
||||||
|
zone <replaceable>quoted_string</replaceable>
|
||||||
|
<optional> default-masters
|
||||||
|
<optional>port <replaceable>ip_port</replaceable></optional>
|
||||||
|
<optional>dscp <replaceable>ip_dscp</replaceable></optional>
|
||||||
|
{ ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }</optional>
|
||||||
|
<optional>in-memory <replaceable>yes_or_no</replaceable></optional>
|
||||||
|
<optional>min-update-interval <replaceable>interval</replaceable></optional>
|
||||||
|
; ... };
|
||||||
|
;
|
||||||
suppress-initial-notify <replaceable>boolean</replaceable>; // not yet implemented
|
suppress-initial-notify <replaceable>boolean</replaceable>; // not yet implemented
|
||||||
preferred-glue <replaceable>string</replaceable>;
|
preferred-glue <replaceable>string</replaceable>;
|
||||||
dual-stack-servers <optional> port <replaceable>integer</replaceable> </optional> {
|
dual-stack-servers <optional> port <replaceable>integer</replaceable> </optional> {
|
||||||
|
@ -65,11 +65,13 @@
|
|||||||
#include <dns/adb.h>
|
#include <dns/adb.h>
|
||||||
#include <dns/badcache.h>
|
#include <dns/badcache.h>
|
||||||
#include <dns/cache.h>
|
#include <dns/cache.h>
|
||||||
|
#include <dns/catz.h>
|
||||||
#include <dns/db.h>
|
#include <dns/db.h>
|
||||||
#include <dns/dispatch.h>
|
#include <dns/dispatch.h>
|
||||||
#include <dns/dlz.h>
|
#include <dns/dlz.h>
|
||||||
#include <dns/dns64.h>
|
#include <dns/dns64.h>
|
||||||
#include <dns/dyndb.h>
|
#include <dns/dyndb.h>
|
||||||
|
#include <dns/events.h>
|
||||||
#include <dns/forward.h>
|
#include <dns/forward.h>
|
||||||
#include <dns/journal.h>
|
#include <dns/journal.h>
|
||||||
#include <dns/keytable.h>
|
#include <dns/keytable.h>
|
||||||
@ -275,6 +277,19 @@ typedef struct {
|
|||||||
isc_refcount_t refs;
|
isc_refcount_t refs;
|
||||||
} ns_zoneload_t;
|
} ns_zoneload_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ns_server_t *server;
|
||||||
|
} catz_cb_data_t;
|
||||||
|
|
||||||
|
typedef struct catz_chgzone_event {
|
||||||
|
ISC_EVENT_COMMON(struct catz_chgzone_event);
|
||||||
|
dns_catz_entry_t *entry;
|
||||||
|
dns_catz_zone_t *origin;
|
||||||
|
dns_view_t *view;
|
||||||
|
catz_cb_data_t *cbd;
|
||||||
|
isc_boolean_t mod;
|
||||||
|
} catz_chgzone_event_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These zones should not leak onto the Internet.
|
* These zones should not leak onto the Internet.
|
||||||
*/
|
*/
|
||||||
@ -1990,12 +2005,439 @@ configure_rpz(dns_view_t *view, const cfg_obj_t *rpz_obj,
|
|||||||
"updated RPZ policy: version %d",
|
"updated RPZ policy: version %d",
|
||||||
view->rpzs->rpz_ver);
|
view->rpzs->rpz_ver);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pview != NULL)
|
if (pview != NULL)
|
||||||
dns_view_detach(&pview);
|
dns_view_detach(&pview);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) {
|
||||||
|
catz_chgzone_event_t *ev = (catz_chgzone_event_t *) event0;
|
||||||
|
isc_result_t result;
|
||||||
|
isc_buffer_t namebuf;
|
||||||
|
isc_buffer_t *confbuf;
|
||||||
|
char nameb[DNS_NAME_FORMATSIZE];
|
||||||
|
const cfg_obj_t *zlist = NULL;
|
||||||
|
cfg_obj_t *zoneconf = NULL;
|
||||||
|
cfg_obj_t *zoneobj = NULL;
|
||||||
|
ns_cfgctx_t *cfg;
|
||||||
|
dns_zone_t *zone = NULL;
|
||||||
|
|
||||||
|
cfg = (ns_cfgctx_t *) ev->view->new_zone_config;
|
||||||
|
if (cfg == NULL) {
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||||
|
"catz: allow-new-zones statement missing from "
|
||||||
|
"config; cannot add zone from the catalog");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_buffer_init(&namebuf, nameb, DNS_NAME_FORMATSIZE);
|
||||||
|
dns_name_totext(dns_catz_entry_getname(ev->entry), ISC_TRUE, &namebuf);
|
||||||
|
isc_buffer_putuint8(&namebuf, 0);
|
||||||
|
|
||||||
|
/* Zone shouldn't already exist */
|
||||||
|
result = dns_zt_find(ev->view->zonetable,
|
||||||
|
dns_catz_entry_getname(ev->entry), 0, NULL, &zone);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||||
|
"catz: zone \"%s\" already exists", nameb);
|
||||||
|
goto cleanup;
|
||||||
|
} else if (result == DNS_R_PARTIALMATCH) {
|
||||||
|
/* Create our sub-zone anyway */
|
||||||
|
dns_zone_detach(&zone);
|
||||||
|
zone = NULL;
|
||||||
|
} else if (result != ISC_R_NOTFOUND) {
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||||
|
"catz: error \"%s\" while trying to "
|
||||||
|
"add zone \"%s\"",
|
||||||
|
isc_result_totext(result), nameb);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a config for new zone */
|
||||||
|
confbuf = NULL;
|
||||||
|
dns_catz_generate_zonecfg(ev->origin, ev->entry, &confbuf);
|
||||||
|
cfg_parser_reset(cfg->add_parser);
|
||||||
|
result = cfg_parse_buffer2(cfg->add_parser, confbuf, "catz",
|
||||||
|
&cfg_type_addzoneconf, &zoneconf);
|
||||||
|
isc_buffer_free(&confbuf);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||||
|
"catz: error \"%s\" while trying to generate "
|
||||||
|
"config for zone \"%s\"",
|
||||||
|
isc_result_totext(result), nameb);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
CHECK(cfg_map_get(zoneconf, "zone", &zlist));
|
||||||
|
if (!cfg_obj_islist(zlist))
|
||||||
|
CHECK(ISC_R_FAILURE);
|
||||||
|
|
||||||
|
/* For now we only support adding one zone at a time */
|
||||||
|
zoneobj = cfg_listelt_value(cfg_list_first(zlist));
|
||||||
|
|
||||||
|
/* Mark view unfrozen so that zone can be added */
|
||||||
|
|
||||||
|
result = isc_task_beginexclusive(task);
|
||||||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
dns_view_thaw(ev->view);
|
||||||
|
result = configure_zone(cfg->config, zoneobj, cfg->vconfig,
|
||||||
|
ev->cbd->server->mctx, ev->view, NULL,
|
||||||
|
cfg->actx, ISC_TRUE, ISC_FALSE, ev->mod);
|
||||||
|
dns_view_freeze(ev->view);
|
||||||
|
isc_task_endexclusive(task);
|
||||||
|
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||||
|
"catz: failed to configure zone \"%s\" - %d",
|
||||||
|
nameb, result);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is it there yet? */
|
||||||
|
CHECK(dns_zt_find(ev->view->zonetable,
|
||||||
|
dns_catz_entry_getname(ev->entry), 0, NULL, &zone));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the zone from the master file. If this fails, we'll
|
||||||
|
* need to undo the configuration we've done already.
|
||||||
|
*/
|
||||||
|
result = dns_zone_loadnew(zone);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
dns_db_t *dbp = NULL;
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
|
||||||
|
"catz: dns_zone_loadnew() failed "
|
||||||
|
"with %s; reverting.",
|
||||||
|
isc_result_totext(result));
|
||||||
|
|
||||||
|
/* If the zone loaded partially, unload it */
|
||||||
|
if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
|
||||||
|
dns_db_detach(&dbp);
|
||||||
|
dns_zone_unload(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the zone from the zone table */
|
||||||
|
dns_zt_unmount(ev->view->zonetable, zone);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flag the zone as having been added at runtime */
|
||||||
|
dns_zone_setadded(zone, ISC_TRUE);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (zone != NULL)
|
||||||
|
dns_zone_detach(&zone);
|
||||||
|
if (zoneconf != NULL)
|
||||||
|
cfg_obj_destroy(cfg->add_parser, &zoneconf);
|
||||||
|
dns_catz_entry_detach(ev->origin, &ev->entry);
|
||||||
|
dns_catz_zone_detach(&ev->origin);
|
||||||
|
dns_view_detach(&ev->view);
|
||||||
|
isc_event_free(ISC_EVENT_PTR(&ev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
catz_delzone_taskaction(isc_task_t *task, isc_event_t *event0) {
|
||||||
|
catz_chgzone_event_t *ev = (catz_chgzone_event_t *) event0;
|
||||||
|
isc_result_t result;
|
||||||
|
dns_zone_t *zone = NULL;
|
||||||
|
dns_db_t *dbp = NULL;
|
||||||
|
char cname[DNS_NAME_FORMATSIZE];
|
||||||
|
const char * file;
|
||||||
|
|
||||||
|
result = isc_task_beginexclusive(task);
|
||||||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
dns_name_format(dns_catz_entry_getname(ev->entry), cname,
|
||||||
|
DNS_NAME_FORMATSIZE);
|
||||||
|
result = dns_zt_find(ev->view->zonetable,
|
||||||
|
dns_catz_entry_getname(ev->entry), 0, NULL, &zone);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||||
|
"catz: catz_delzone_taskaction: "
|
||||||
|
"zone '%s' not found", cname);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO make other flag for CZ zones */
|
||||||
|
/* TODO2 make sure that we delete only 'own' zones */
|
||||||
|
if (!dns_zone_getadded(zone)) {
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||||
|
"catz: catz_delzone_taskaction: "
|
||||||
|
"zone '%s' is not a dynamically added zone",
|
||||||
|
cname);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop answering for this zone */
|
||||||
|
if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
|
||||||
|
dns_db_detach(&dbp);
|
||||||
|
dns_zone_unload(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(dns_zt_unmount(ev->view->zonetable, zone));
|
||||||
|
file = dns_zone_getfile(zone);
|
||||||
|
isc_file_remove(file);
|
||||||
|
|
||||||
|
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
|
||||||
|
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||||
|
"catz: catz_delzone_taskaction: "
|
||||||
|
"zone '%s' deleted", cname);
|
||||||
|
cleanup:
|
||||||
|
isc_task_endexclusive(task);
|
||||||
|
if (zone != NULL)
|
||||||
|
dns_zone_detach(&zone);
|
||||||
|
dns_catz_entry_detach(ev->origin, &ev->entry);
|
||||||
|
dns_catz_zone_detach(&ev->origin);
|
||||||
|
dns_view_detach(&ev->view);
|
||||||
|
isc_event_free(ISC_EVENT_PTR(&ev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
catz_create_chg_task(dns_catz_entry_t *entry, dns_catz_zone_t *origin,
|
||||||
|
dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata,
|
||||||
|
isc_eventtype_t type)
|
||||||
|
{
|
||||||
|
catz_chgzone_event_t *event;
|
||||||
|
isc_task_t *task;
|
||||||
|
isc_result_t result;
|
||||||
|
isc_taskaction_t action;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case DNS_EVENT_CATZADDZONE:
|
||||||
|
case DNS_EVENT_CATZMODZONE:
|
||||||
|
action = catz_addmodzone_taskaction;
|
||||||
|
break;
|
||||||
|
case DNS_EVENT_CATZDELZONE:
|
||||||
|
action = catz_delzone_taskaction;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
REQUIRE(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
event = (catz_chgzone_event_t *) isc_event_allocate(view->mctx, origin,
|
||||||
|
type, action, NULL,
|
||||||
|
sizeof(*event));
|
||||||
|
if (event == NULL)
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
|
event->cbd = (catz_cb_data_t *) udata;
|
||||||
|
event->entry = NULL;
|
||||||
|
event->origin = NULL;
|
||||||
|
event->view = NULL;
|
||||||
|
event->mod = ISC_TF(type == DNS_EVENT_CATZMODZONE);
|
||||||
|
dns_catz_entry_attach(entry, &event->entry);
|
||||||
|
dns_catz_zone_attach(origin, &event->origin);
|
||||||
|
dns_view_attach(view, &event->view);
|
||||||
|
|
||||||
|
task = NULL;
|
||||||
|
result = isc_taskmgr_excltask(taskmgr, &task);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
isc_task_send(task, ISC_EVENT_PTR(&event));
|
||||||
|
isc_task_detach(&task);
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
catz_addzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin,
|
||||||
|
dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata)
|
||||||
|
{
|
||||||
|
return (catz_create_chg_task(entry, origin, view, taskmgr, udata,
|
||||||
|
DNS_EVENT_CATZADDZONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
catz_delzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin,
|
||||||
|
dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata)
|
||||||
|
{
|
||||||
|
return (catz_create_chg_task(entry, origin, view, taskmgr, udata,
|
||||||
|
DNS_EVENT_CATZDELZONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
catz_modzone(dns_catz_entry_t *entry, dns_catz_zone_t *origin,
|
||||||
|
dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata)
|
||||||
|
{
|
||||||
|
return (catz_create_chg_task(entry, origin, view, taskmgr, udata,
|
||||||
|
DNS_EVENT_CATZMODZONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
configure_catz_zone(dns_view_t *view, const cfg_obj_t *config,
|
||||||
|
const cfg_listelt_t *element)
|
||||||
|
{
|
||||||
|
const cfg_obj_t *catz_obj, *obj;
|
||||||
|
dns_catz_zone_t *zone = NULL;
|
||||||
|
const char *str;
|
||||||
|
isc_result_t result;
|
||||||
|
dns_name_t origin;
|
||||||
|
dns_catz_options_t *opts;
|
||||||
|
dns_view_t *pview = NULL;
|
||||||
|
|
||||||
|
dns_name_init(&origin, NULL);
|
||||||
|
catz_obj = cfg_listelt_value(element);
|
||||||
|
|
||||||
|
str = cfg_obj_asstring(cfg_tuple_get(catz_obj, "zone name"));
|
||||||
|
|
||||||
|
result = dns_name_fromstring(&origin, str, DNS_NAME_DOWNCASE,
|
||||||
|
view->mctx);
|
||||||
|
if (result == ISC_R_SUCCESS && dns_name_equal(&origin, dns_rootname))
|
||||||
|
result = DNS_R_EMPTYLABEL;
|
||||||
|
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL,
|
||||||
|
"catz: invalid zone name '%s'", str);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = dns_catz_add_zone(view->catzs, &origin, &zone);
|
||||||
|
if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
|
||||||
|
cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL,
|
||||||
|
"catz: unable to create catalog zone '%s', "
|
||||||
|
"error %s",
|
||||||
|
str, isc_result_totext(result));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == ISC_R_EXISTS) {
|
||||||
|
isc_ht_iter_t *it = NULL;
|
||||||
|
|
||||||
|
result = dns_viewlist_find(&ns_g_server->viewlist,
|
||||||
|
view->name,
|
||||||
|
view->rdclass, &pview);
|
||||||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xxxwpk todo: reconfigure the zone!!!!
|
||||||
|
*/
|
||||||
|
cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL,
|
||||||
|
"catz: catalog zone '%s' will not be reconfigured",
|
||||||
|
str);
|
||||||
|
/*
|
||||||
|
* We have to walk through all the member zones and attach
|
||||||
|
* them to current view
|
||||||
|
*/
|
||||||
|
result = dns_catz_get_iterator(zone, &it);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
cfg_obj_log(catz_obj, ns_g_lctx, DNS_CATZ_ERROR_LEVEL,
|
||||||
|
"catz: unable to create iterator");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (result = isc_ht_iter_first(it);
|
||||||
|
result == ISC_R_SUCCESS;
|
||||||
|
result = isc_ht_iter_next(it))
|
||||||
|
{
|
||||||
|
dns_name_t *name = NULL;
|
||||||
|
dns_zone_t *dnszone = NULL;
|
||||||
|
dns_catz_entry_t *entry = NULL;
|
||||||
|
isc_result_t tresult;
|
||||||
|
|
||||||
|
isc_ht_iter_current(it, (void **) &entry);
|
||||||
|
name = dns_catz_entry_getname(entry);
|
||||||
|
|
||||||
|
tresult = dns_view_findzone(pview, name, &dnszone);
|
||||||
|
RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
dns_zone_setview(dnszone, view);
|
||||||
|
if (view->acache != NULL)
|
||||||
|
dns_zone_setacache(dnszone, view->acache);
|
||||||
|
dns_view_addzone(view, dnszone);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_ht_iter_destroy(&it);
|
||||||
|
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_catz_zone_resetdefoptions(zone);
|
||||||
|
opts = dns_catz_zone_getdefoptions(zone);
|
||||||
|
|
||||||
|
obj = cfg_tuple_get(catz_obj, "default-masters");
|
||||||
|
if (obj != NULL)
|
||||||
|
result = ns_config_getipandkeylist(config, obj,
|
||||||
|
view->mctx, &opts->masters);
|
||||||
|
|
||||||
|
obj = cfg_tuple_get(catz_obj, "in-memory");
|
||||||
|
if (obj != NULL && cfg_obj_isboolean(obj))
|
||||||
|
opts->in_memory = cfg_obj_asboolean(obj);
|
||||||
|
|
||||||
|
obj = cfg_tuple_get(catz_obj, "min-update-interval");
|
||||||
|
if (obj != NULL && cfg_obj_isuint32(obj))
|
||||||
|
opts->min_update_interval = cfg_obj_asuint32(obj);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (pview != NULL)
|
||||||
|
dns_view_detach(&pview);
|
||||||
|
dns_name_free(&origin, view->mctx);
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static catz_cb_data_t ns_catz_cbdata;
|
||||||
|
static dns_catz_zonemodmethods_t ns_catz_zonemodmethods = {
|
||||||
|
catz_addzone,
|
||||||
|
catz_modzone,
|
||||||
|
catz_delzone,
|
||||||
|
&ns_catz_cbdata
|
||||||
|
};
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
configure_catz(dns_view_t *view, const cfg_obj_t *config,
|
||||||
|
const cfg_obj_t *catz_obj)
|
||||||
|
{
|
||||||
|
const cfg_listelt_t *zone_element;
|
||||||
|
const dns_catz_zones_t *old = NULL;
|
||||||
|
dns_view_t *pview = NULL;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
/* xxxwpk TODO do it cleaner, once, somewhere */
|
||||||
|
ns_catz_cbdata.server = ns_g_server;
|
||||||
|
|
||||||
|
zone_element = cfg_list_first(cfg_tuple_get(catz_obj, "zone list"));
|
||||||
|
if (zone_element == NULL)
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
CHECK(dns_catz_new_zones(&view->catzs, &ns_catz_zonemodmethods,
|
||||||
|
view->mctx, ns_g_taskmgr, ns_g_timermgr));
|
||||||
|
|
||||||
|
result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
|
||||||
|
view->rdclass, &pview);
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
|
old = pview->catzs;
|
||||||
|
|
||||||
|
if (old != NULL) {
|
||||||
|
dns_catz_catzs_detach(&view->catzs);
|
||||||
|
dns_catz_catzs_attach(pview->catzs, &view->catzs);
|
||||||
|
dns_catz_prereconfig(view->catzs);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (zone_element != NULL) {
|
||||||
|
CHECK(configure_catz_zone(view, config, zone_element));
|
||||||
|
zone_element = cfg_list_next(zone_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old != NULL)
|
||||||
|
dns_catz_postreconfig(view->catzs);
|
||||||
|
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (pview != NULL)
|
||||||
|
dns_view_detach(&pview);
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
#define CHECK_RRL(cond, pat, val1, val2) \
|
#define CHECK_RRL(cond, pat, val1, val2) \
|
||||||
do { \
|
do { \
|
||||||
if (!(cond)) { \
|
if (!(cond)) { \
|
||||||
@ -2693,6 +3135,12 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||||||
CHECK(configure_rpz(view, obj, &old_rpz_ok));
|
CHECK(configure_rpz(view, obj, &old_rpz_ok));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj = NULL;
|
||||||
|
if (view->rdclass == dns_rdataclass_in && need_hints &&
|
||||||
|
ns_config_get(maps, "catalog-zones", &obj) == ISC_R_SUCCESS) {
|
||||||
|
CHECK(configure_catz(view, config, obj));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the zones.
|
* Configure the zones.
|
||||||
*/
|
*/
|
||||||
@ -4574,6 +5022,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||||||
dns_rdataclass_t zclass;
|
dns_rdataclass_t zclass;
|
||||||
const char *ztypestr;
|
const char *ztypestr;
|
||||||
dns_rpz_num_t rpz_num;
|
dns_rpz_num_t rpz_num;
|
||||||
|
isc_boolean_t zone_is_catz = ISC_FALSE;
|
||||||
|
|
||||||
options = NULL;
|
options = NULL;
|
||||||
(void)cfg_map_get(config, "options", &options);
|
(void)cfg_map_get(config, "options", &options);
|
||||||
@ -4801,6 +5250,10 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (view->catzs != NULL &&
|
||||||
|
dns_catz_get_zone(view->catzs, origin) != NULL)
|
||||||
|
zone_is_catz = ISC_TRUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See if we can reuse an existing zone. This is
|
* See if we can reuse an existing zone. This is
|
||||||
* only possible if all of these are true:
|
* only possible if all of these are true:
|
||||||
@ -4850,7 +5303,6 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||||||
CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
|
CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
|
||||||
dns_zone_setstats(zone, ns_g_server->zonestats);
|
dns_zone_setstats(zone, ns_g_server->zonestats);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpz_num != DNS_RPZ_INVALID_NUM) {
|
if (rpz_num != DNS_RPZ_INVALID_NUM) {
|
||||||
result = dns_zone_rpz_enable(zone, view->rpzs, rpz_num);
|
result = dns_zone_rpz_enable(zone, view->rpzs, rpz_num);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@ -4864,6 +5316,9 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zone_is_catz)
|
||||||
|
dns_zone_catz_enable(zone, view->catzs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the zone contains a 'forwarders' statement, configure
|
* If the zone contains a 'forwarders' statement, configure
|
||||||
* selective forwarding.
|
* selective forwarding.
|
||||||
@ -4921,6 +5376,18 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||||||
if (!modify)
|
if (!modify)
|
||||||
CHECK(dns_view_addzone(view, zone));
|
CHECK(dns_view_addzone(view, zone));
|
||||||
|
|
||||||
|
if (zone_is_catz) {
|
||||||
|
/*
|
||||||
|
* force catz reload if the zone is loaded;
|
||||||
|
* if it's not it'll get reloaded on zone load
|
||||||
|
*/
|
||||||
|
dns_db_t *db = NULL;
|
||||||
|
|
||||||
|
tresult = dns_zone_getdb(zone, &db);
|
||||||
|
if (tresult == ISC_R_SUCCESS)
|
||||||
|
dns_catz_dbupdate_callback(db, view->catzs);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure that zone keys are reloaded on reconfig
|
* Ensure that zone keys are reloaded on reconfig
|
||||||
*/
|
*/
|
||||||
@ -5684,6 +6151,20 @@ setup_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
|||||||
if (result == ISC_R_SUCCESS)
|
if (result == ISC_R_SUCCESS)
|
||||||
allow = cfg_obj_asboolean(nz);
|
allow = cfg_obj_asboolean(nz);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A non-empty catalog-zones statement implies allow-new-zones
|
||||||
|
*/
|
||||||
|
if (!allow) {
|
||||||
|
const cfg_obj_t *cz = NULL;
|
||||||
|
result = ns_config_get(maps, "catalog-zones", &cz);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
const cfg_listelt_t *e =
|
||||||
|
cfg_list_first(cfg_tuple_get(cz, "zone list"));
|
||||||
|
if (e != NULL)
|
||||||
|
allow = ISC_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!allow) {
|
if (!allow) {
|
||||||
dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
|
dns_view_setnewzones(view, ISC_FALSE, NULL, NULL);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <dns/acl.h>
|
#include <dns/acl.h>
|
||||||
#include <dns/db.h>
|
#include <dns/db.h>
|
||||||
|
#include <dns/ipkeylist.h>
|
||||||
#include <dns/fixedname.h>
|
#include <dns/fixedname.h>
|
||||||
#include <dns/log.h>
|
#include <dns/log.h>
|
||||||
#include <dns/name.h>
|
#include <dns/name.h>
|
||||||
@ -805,9 +806,6 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||||||
const char *filename = NULL;
|
const char *filename = NULL;
|
||||||
const char *dupcheck;
|
const char *dupcheck;
|
||||||
dns_notifytype_t notifytype = dns_notifytype_yes;
|
dns_notifytype_t notifytype = dns_notifytype_yes;
|
||||||
isc_sockaddr_t *addrs;
|
|
||||||
isc_dscp_t *dscps;
|
|
||||||
dns_name_t **keynames;
|
|
||||||
isc_uint32_t count;
|
isc_uint32_t count;
|
||||||
unsigned int dbargc;
|
unsigned int dbargc;
|
||||||
char **dbargv;
|
char **dbargv;
|
||||||
@ -1149,23 +1147,19 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||||||
(notifytype == dns_notifytype_masteronly &&
|
(notifytype == dns_notifytype_masteronly &&
|
||||||
ztype == dns_zone_master)))
|
ztype == dns_zone_master)))
|
||||||
{
|
{
|
||||||
isc_uint32_t addrcount;
|
dns_ipkeylist_t ipkl;
|
||||||
addrs = NULL;
|
ipkl.count = 0;
|
||||||
keynames = NULL;
|
ipkl.addrs = NULL;
|
||||||
dscps = NULL;
|
ipkl.dscps = NULL;
|
||||||
|
ipkl.keys = NULL;
|
||||||
RETERR(ns_config_getipandkeylist(config, obj, mctx,
|
RETERR(ns_config_getipandkeylist(config, obj, mctx,
|
||||||
&addrs, &dscps,
|
&ipkl));
|
||||||
&keynames,
|
result = dns_zone_setalsonotifydscpkeys(zone,
|
||||||
&addrcount));
|
ipkl.addrs,
|
||||||
result = dns_zone_setalsonotifydscpkeys(zone, addrs,
|
ipkl.dscps,
|
||||||
dscps, keynames,
|
ipkl.keys,
|
||||||
addrcount);
|
ipkl.count);
|
||||||
if (addrcount != 0)
|
dns_ipkeylist_clear(mctx, &ipkl);
|
||||||
ns_config_putipandkeylist(mctx, &addrs, &dscps,
|
|
||||||
&keynames, addrcount);
|
|
||||||
else
|
|
||||||
INSIST(addrs == NULL && dscps == NULL &&
|
|
||||||
keynames == NULL);
|
|
||||||
RETERR(result);
|
RETERR(result);
|
||||||
} else
|
} else
|
||||||
RETERR(dns_zone_setalsonotify(zone, NULL, 0));
|
RETERR(dns_zone_setalsonotify(zone, NULL, 0));
|
||||||
@ -1628,19 +1622,19 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||||||
obj = NULL;
|
obj = NULL;
|
||||||
(void)cfg_map_get(zoptions, "masters", &obj);
|
(void)cfg_map_get(zoptions, "masters", &obj);
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
addrs = NULL;
|
dns_ipkeylist_t ipkl;
|
||||||
dscps = NULL;
|
ipkl.count = 0;
|
||||||
keynames = NULL;
|
ipkl.addrs = NULL;
|
||||||
|
ipkl.dscps = NULL;
|
||||||
|
ipkl.keys = NULL;
|
||||||
RETERR(ns_config_getipandkeylist(config, obj, mctx,
|
RETERR(ns_config_getipandkeylist(config, obj, mctx,
|
||||||
&addrs, &dscps,
|
&ipkl));
|
||||||
&keynames, &count));
|
result = dns_zone_setmasterswithkeys(mayberaw,
|
||||||
result = dns_zone_setmasterswithkeys(mayberaw, addrs,
|
ipkl.addrs,
|
||||||
keynames, count);
|
ipkl.keys,
|
||||||
if (count != 0)
|
ipkl.count);
|
||||||
ns_config_putipandkeylist(mctx, &addrs, &dscps,
|
dns_ipkeylist_clear(mctx, &ipkl);
|
||||||
&keynames, count);
|
RETERR(result);
|
||||||
else
|
|
||||||
INSIST(addrs == NULL && keynames == NULL);
|
|
||||||
} else
|
} else
|
||||||
result = dns_zone_setmasters(mayberaw, NULL, 0);
|
result = dns_zone_setmasters(mayberaw, NULL, 0);
|
||||||
RETERR(result);
|
RETERR(result);
|
||||||
|
23
bin/tests/system/catz/clean.sh
Normal file
23
bin/tests/system/catz/clean.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# 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 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.
|
||||||
|
|
||||||
|
rm -f dig.out.*
|
||||||
|
rm -f nsupdate.out.*
|
||||||
|
rm -f ns*/named.memstats
|
||||||
|
rm -f ns*/named.run
|
||||||
|
rm -f ns*/named.lock
|
||||||
|
rm -f ns{1,2}/*dom*example.db
|
||||||
|
rm -f ns{1,2}/catalog.example.db
|
||||||
|
rm -f ns*/*.jnl
|
||||||
|
rm -f ns*/*.nzf
|
3
bin/tests/system/catz/ns1/catalog.example.db.in
Normal file
3
bin/tests/system/catz/ns1/catalog.example.db.in
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@ 3600 SOA . . 1 86400 3600 86400 3600
|
||||||
|
@ 3600 IN NS invalid.
|
||||||
|
version IN TXT "1"
|
43
bin/tests/system/catz/ns1/named.conf
Normal file
43
bin/tests/system/catz/ns1/named.conf
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011, 2013, 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include "../../common/rndc.key";
|
||||||
|
|
||||||
|
controls {
|
||||||
|
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
|
||||||
|
};
|
||||||
|
|
||||||
|
options {
|
||||||
|
query-source address 10.53.0.1;
|
||||||
|
notify-source 10.53.0.1;
|
||||||
|
transfer-source 10.53.0.1;
|
||||||
|
port 5300;
|
||||||
|
allow-new-zones yes;
|
||||||
|
pid-file "named.pid";
|
||||||
|
listen-on { 10.53.0.1; };
|
||||||
|
listen-on-v6 { none; };
|
||||||
|
notify no;
|
||||||
|
recursion no;
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "catalog.example" {
|
||||||
|
type master;
|
||||||
|
file "catalog.example.db";
|
||||||
|
allow-transfer { any; };
|
||||||
|
allow-update { any; };
|
||||||
|
also-notify { 10.53.0.2; };
|
||||||
|
notify explicit;
|
||||||
|
};
|
43
bin/tests/system/catz/ns2/named.conf
Normal file
43
bin/tests/system/catz/ns2/named.conf
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011, 2013, 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include "../../common/rndc.key";
|
||||||
|
|
||||||
|
controls {
|
||||||
|
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
|
||||||
|
};
|
||||||
|
|
||||||
|
options {
|
||||||
|
query-source address 10.53.0.2;
|
||||||
|
notify-source 10.53.0.2;
|
||||||
|
transfer-source 10.53.0.2;
|
||||||
|
port 5300;
|
||||||
|
pid-file "named.pid";
|
||||||
|
listen-on { 10.53.0.2; };
|
||||||
|
listen-on-v6 { none; };
|
||||||
|
notify no;
|
||||||
|
recursion no;
|
||||||
|
serial-query-rate 100;
|
||||||
|
catalog-zones {
|
||||||
|
zone "catalog.example" default-masters { 10.53.0.1; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "catalog.example" {
|
||||||
|
type slave;
|
||||||
|
file "catalog.example.db";
|
||||||
|
masters { 10.53.0.1; };
|
||||||
|
};
|
2
bin/tests/system/catz/ns3/dom4.example.db
Normal file
2
bin/tests/system/catz/ns3/dom4.example.db
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@ 3600 IN SOA . . 1 3600 3600 3600 3600
|
||||||
|
@ IN NS invalid.
|
41
bin/tests/system/catz/ns3/named.conf
Normal file
41
bin/tests/system/catz/ns3/named.conf
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011, 2013, 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include "../../common/rndc.key";
|
||||||
|
|
||||||
|
controls {
|
||||||
|
inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; };
|
||||||
|
};
|
||||||
|
|
||||||
|
options {
|
||||||
|
query-source address 10.53.0.3;
|
||||||
|
notify-source 10.53.0.3;
|
||||||
|
transfer-source 10.53.0.3;
|
||||||
|
port 5300;
|
||||||
|
pid-file "named.pid";
|
||||||
|
listen-on { 10.53.0.3; };
|
||||||
|
listen-on-v6 { none; };
|
||||||
|
notify no;
|
||||||
|
recursion no;
|
||||||
|
};
|
||||||
|
|
||||||
|
zone "dom4.example" {
|
||||||
|
type master;
|
||||||
|
file "dom4.example.db";
|
||||||
|
allow-transfer { any; };
|
||||||
|
allow-update { any; };
|
||||||
|
notify explicit;
|
||||||
|
};
|
22
bin/tests/system/catz/setup.sh
Normal file
22
bin/tests/system/catz/setup.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# 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 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.
|
||||||
|
|
||||||
|
SYSTEMTESTTOP=..
|
||||||
|
. $SYSTEMTESTTOP/conf.sh
|
||||||
|
|
||||||
|
$SHELL clean.sh
|
||||||
|
|
||||||
|
cat ns1/catalog.example.db.in > ns1/catalog.example.db
|
305
bin/tests/system/catz/tests.sh
Normal file
305
bin/tests/system/catz/tests.sh
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
#
|
||||||
|
# Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# 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 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.
|
||||||
|
|
||||||
|
SYSTEMTESTTOP=..
|
||||||
|
. $SYSTEMTESTTOP/conf.sh
|
||||||
|
|
||||||
|
status=0
|
||||||
|
n=0
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom1.example is not served by master ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom1.example @10.53.0.1 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Adding a domain dom1.example to master via RNDC ($n)"
|
||||||
|
ret=0
|
||||||
|
echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom1.example.db
|
||||||
|
echo "@ IN NS invalid." >> ns1/dom1.example.db
|
||||||
|
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom1.example '{type master; file "dom1.example.db";};' || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom1.example is now served by master ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom1.example @10.53.0.1 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Adding domain dom1.example to catalog zone ($n)"
|
||||||
|
ret=0
|
||||||
|
$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
|
||||||
|
server 10.53.0.1 5300
|
||||||
|
update add e721433b6160b450260d4f54b3ec8bab30cb3b83.zones.catalog.example 3600 IN PTR dom1.example.
|
||||||
|
send
|
||||||
|
END
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:waiting for slave to sync up ($n)"
|
||||||
|
ret=1
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom1.example' from catalog 'catalog.example'" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom1.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom1.example is served by slave ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom1.example @10.53.0.2 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Removing domain dom1.example from catalog zone ($n)"
|
||||||
|
ret=0
|
||||||
|
$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
|
||||||
|
server 10.53.0.1 5300
|
||||||
|
update delete e721433b6160b450260d4f54b3ec8bab30cb3b83.zones.catalog.example
|
||||||
|
send
|
||||||
|
END
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:waiting for slave to sync up ($n)"
|
||||||
|
ret=1
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom1.example' from catalog 'catalog.example'" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom1.example is not served by slave ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom1.example @10.53.0.2 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Adding a domain dom2.example to master via RNDC ($n)"
|
||||||
|
ret=0
|
||||||
|
echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom2.example.db
|
||||||
|
echo "@ IN NS invalid." >> ns1/dom2.example.db
|
||||||
|
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom2.example '{type master; file "dom2.example.db";};' || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Adding domains dom2.example, dom3.example and some trash to catalog zone ($n)"
|
||||||
|
ret=0
|
||||||
|
$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
|
||||||
|
server 10.53.0.1 5300
|
||||||
|
update add 636722929740e507aaf27c502812fc395d30fb17.zones.catalog.example 3600 IN PTR dom2.example.
|
||||||
|
update add b901f492f3ebf6c1e5b597e51766f02f0479eb03.zones.catalog.example 3600 IN PTR dom3.example.
|
||||||
|
update add e721433b6160b450260d4f54b3ec8bab30cb3b83.zones.catalog.example 3600 IN NS foo.bar.
|
||||||
|
update add trash.catalog.example 3600 IN A 1.2.3.4
|
||||||
|
update add trash2.foo.catalog.example 3600 IN A 1.2.3.4
|
||||||
|
update add trash3.zones.catalog.example 3600 IN NS a.dom2.example.
|
||||||
|
send
|
||||||
|
END
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom3.example is not served by master ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom3.example @10.53.0.1 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Adding a domain dom3.example to master via RNDC ($n)"
|
||||||
|
ret=0
|
||||||
|
echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom3.example.db
|
||||||
|
echo "@ IN NS invalid." >> ns1/dom3.example.db
|
||||||
|
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom3.example '{type master; file "dom3.example.db"; also-notify { 10.53.0.2; }; };' || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom3.example is served by master ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom2.example @10.53.0.1 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:waiting for slave to sync up ($n)"
|
||||||
|
ret=1
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom3.example' from catalog 'catalog.example'" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom3.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom3.example is served by slave ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom3.example @10.53.0.2 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Adding dom4.example with 'masters' defined and a random label ($n)"
|
||||||
|
ret=0
|
||||||
|
$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
|
||||||
|
server 10.53.0.1 5300
|
||||||
|
update add somerandomlabel.zones.catalog.example 3600 IN PTR dom4.example.
|
||||||
|
update add masters.somerandomlabel.zones.catalog.example 3600 IN A 10.53.0.3
|
||||||
|
send
|
||||||
|
END
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:waiting for slave to sync up ($n)"
|
||||||
|
ret=1
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom4.example' from catalog 'catalog.example'" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom4.example/IN' from 10.53.0.3#5300: Transfer status: success" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom4.example is served by slave ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom4.example @10.53.0.2 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:Removing domain dom2.example from catalog zone ($n)"
|
||||||
|
ret=0
|
||||||
|
$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
|
||||||
|
server 10.53.0.1 5300
|
||||||
|
update delete 636722929740e507aaf27c502812fc395d30fb17.zones.catalog.example
|
||||||
|
send
|
||||||
|
END
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:waiting for slave to sync up ($n)"
|
||||||
|
ret=1
|
||||||
|
try=0
|
||||||
|
while test $try -lt 45
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
sed -n "$cur,"'$p' < ns2/named.run | grep "catz: deleting zone 'dom2.example' from catalog 'catalog.example'" > /dev/null && {
|
||||||
|
ret=0
|
||||||
|
break
|
||||||
|
}
|
||||||
|
try=`expr $try + 1`
|
||||||
|
done
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom2.example is not served by slave ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom2.example @10.53.0.2 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I:checking that dom3.example is still served by slave ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG soa dom3.example @10.53.0.2 -p 5300 > dig.out.test$n
|
||||||
|
grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
echo "I:exit status: $status"
|
||||||
|
exit $status
|
@ -68,7 +68,7 @@ RANDFILE=$TOP/bin/tests/system/random.data
|
|||||||
# load on the machine to make it unusable to other users.
|
# load on the machine to make it unusable to other users.
|
||||||
# v6synth
|
# v6synth
|
||||||
SUBDIRS="acl additional allow_query addzone autosign builtin
|
SUBDIRS="acl additional allow_query addzone autosign builtin
|
||||||
cacheclean case checkconf @CHECKDS@ checknames checkzone
|
cacheclean case catz checkconf @CHECKDS@ checknames checkzone
|
||||||
cookie @COVERAGE@ database digdelv dlv dlvauto dlz dlzexternal
|
cookie @COVERAGE@ database digdelv dlv dlvauto dlz dlzexternal
|
||||||
dname dns64 dnssec dsdigest dscp @DNSTAP@ dyndb ecdsa ednscompliance
|
dname dns64 dnssec dsdigest dscp @DNSTAP@ dyndb ecdsa ednscompliance
|
||||||
emptyzones fetchlimit filter-aaaa formerr forward geoip glue gost
|
emptyzones fetchlimit filter-aaaa formerr forward geoip glue gost
|
||||||
|
@ -2373,6 +2373,8 @@ options {
|
|||||||
|
|
||||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dyndb.xml"/>
|
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dyndb.xml"/>
|
||||||
|
|
||||||
|
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="catz.xml"/>
|
||||||
|
|
||||||
<section xml:id="ipv6"><info><title>IPv6 Support in <acronym>BIND</acronym> 9</title></info>
|
<section xml:id="ipv6"><info><title>IPv6 Support in <acronym>BIND</acronym> 9</title></info>
|
||||||
<para>
|
<para>
|
||||||
<acronym>BIND</acronym> 9 fully supports all currently
|
<acronym>BIND</acronym> 9 fully supports all currently
|
||||||
@ -4674,6 +4676,16 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
|||||||
<optional> qname-wait-recurse <replaceable>yes_or_no</replaceable> </optional>
|
<optional> qname-wait-recurse <replaceable>yes_or_no</replaceable> </optional>
|
||||||
<optional> automatic-interface-scan <replaceable>yes_or_no</replaceable> </optional>
|
<optional> automatic-interface-scan <replaceable>yes_or_no</replaceable> </optional>
|
||||||
; </optional>
|
; </optional>
|
||||||
|
<optional> catalog-zones {
|
||||||
|
zone <replaceable>quoted_string</replaceable>
|
||||||
|
<optional> default-masters
|
||||||
|
<optional>port <replaceable>ip_port</replaceable></optional>
|
||||||
|
<optional>dscp <replaceable>ip_dscp</replaceable></optional>
|
||||||
|
{ ( <replaceable>masters_list</replaceable> | <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> <optional>key <replaceable>key</replaceable></optional> ) ; <optional>...</optional> }</optional>
|
||||||
|
<optional>in-memory <replaceable>yes_or_no</replaceable></optional>
|
||||||
|
<optional>min-update-interval <replaceable>interval</replaceable></optional>
|
||||||
|
; <optional>...</optional> };
|
||||||
|
; </optional>
|
||||||
<optional>v6-bias <replaceable>number</replaceable> ; </optional>
|
<optional>v6-bias <replaceable>number</replaceable> ; </optional>
|
||||||
};
|
};
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
Binary file not shown.
229
doc/arm/catz.xml
Normal file
229
doc/arm/catz.xml
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!--
|
||||||
|
- Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
-
|
||||||
|
- 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 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.
|
||||||
|
-->
|
||||||
|
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="catz-info"><info><title>Catalog Zones</title></info>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A "catalog zone" is a special DNS zone that contains a list of
|
||||||
|
other zones to be served, along with their configuration parameters.
|
||||||
|
Zones listed in a catalog zone are called "member zones".
|
||||||
|
When a catalog zone is loaded or transferred to a slave server
|
||||||
|
which supports this functionality, the slave server will create
|
||||||
|
the member zones automatically. When the catalog zone is updated
|
||||||
|
is updated (for example, to add or delete member zones, or change
|
||||||
|
their configuration aprameters) those changes are immediately put
|
||||||
|
into effect. Because the catalog zone is a normal DNS zone, these
|
||||||
|
configuration changes can be propagated using the standard AXFR/IXFR
|
||||||
|
zone transfer mechanism.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Catalog zones' format and behavior are specified as an internet draft
|
||||||
|
for interoperability among DNS implementations. As of this release, the
|
||||||
|
latest revision of the DNS catalog zones draft can be found here:
|
||||||
|
https://datatracker.ietf.org/doc/draft-muks-dnsop-dns-catalog-zones/
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section><info><title>Principle of Operation</title></info>
|
||||||
|
<para>
|
||||||
|
Normally, if a zone is to be served by a slave server, the
|
||||||
|
<filename>named.conf</filename> file on the server must list the
|
||||||
|
zone, or the zone must be added using <command>rndc addzone</command>.
|
||||||
|
In environments with a large number of slave servers and/or where
|
||||||
|
the zones being served are changing frequently, the overhead involved
|
||||||
|
in maintaining consistent zone configuration on all the slave
|
||||||
|
servers can be significant.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A catalog zone is a way to ease this administrative burden. It is a
|
||||||
|
DNS zone that lists member zones that should be served by slave servers.
|
||||||
|
When a slave server receives an update to the catalog zone, it adds,
|
||||||
|
removes, or reconfigures member zones based on the data received.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
To use a catalog zone, it must first be set up as a normal zone on
|
||||||
|
the master and the on slave servers that will be configured to use
|
||||||
|
it. It must also be added to a <option>catalog-zones</option> list
|
||||||
|
in the <option>options</option> or <option>view</option> statement
|
||||||
|
in <filename>named.conf</filename>. (This is comparable to the way
|
||||||
|
a policy zone is configured as a normal zone and also listed in
|
||||||
|
a <option>response-policy</option> statement.)
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
To use the catalog zone feature to serve a new member zone:
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Set up the the member zone to be served on the master as normal.
|
||||||
|
This could be done by editing <filename>named.conf</filename>,
|
||||||
|
or by running <command>rndc addzone</command>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Add an entry to the catalog zone for the new member zone.
|
||||||
|
This could be done by editing the catalog zone's master file
|
||||||
|
and running <command>rndc reload</command>, or by updating
|
||||||
|
the zone using <command>nsupdate</command>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
The change to the catalog zone will be propagated from the master to all
|
||||||
|
slaves using the normal AXFR/IXFR mechanism. When the slave receives the
|
||||||
|
update to the catalog zone, it will detect the entry for the new member
|
||||||
|
zone, create an instance of of that zone on the slave server, and point
|
||||||
|
that instance to the <option>masters</option> specified in the catalog
|
||||||
|
zone data. The newly created member zone is a normal slave zone, so
|
||||||
|
BIND will immediately initiate a transfer of zone contents from the
|
||||||
|
master. Once complete, the slave will start serving the member zone.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Removing a member zone from a slave server requires nothing more than
|
||||||
|
deleting the member zone's entry in the catalog zone. The change to the
|
||||||
|
catalog cone is propagated to the slave server using the normal AXFR/IXFR
|
||||||
|
transfer mechanism. The slave server, on processing the update, will
|
||||||
|
notice that the member zone has been removed. It will stop serving the
|
||||||
|
zone and remove it froms its list of configured zones. (Removing the
|
||||||
|
member zone from the master server has to be done in the normal way,
|
||||||
|
by editing the configuration file or running
|
||||||
|
<command>rndc delzone</command>.)
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section><info><title>Configuring Catalog Zones</title></info>
|
||||||
|
<para>
|
||||||
|
Catalog zones are configured with a <command>catalog-zones</command>
|
||||||
|
statement in the <literal>options</literal> or <literal>view</literal>
|
||||||
|
section of <filename>named.conf</filename>. For example,
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
catalog-zones {
|
||||||
|
zone "catalog.example" default-masters { 10.53.0.1; } in-memory true min-update-interval 10;
|
||||||
|
};
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
This statement specifies that the zone
|
||||||
|
<literal>catalog.example</literal> is a catalog zone. This zone must be
|
||||||
|
properly configured in the same view. In most configurations, it would
|
||||||
|
be a slave zone.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The <option>default-masters</option> option defines the default masters
|
||||||
|
for member zones listed in a catalog zone. This can be overriden by
|
||||||
|
options within a catalog zone. If no such options are included, then
|
||||||
|
member zones will transfer their contents from the servers listed in
|
||||||
|
this option.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The <option>in-memory</option> option, if set to <literal>yes</literal>,
|
||||||
|
causes member zones to be stored only in memory. This is functionally
|
||||||
|
equivalent to configuring a slave zone without a <option>file</option>.
|
||||||
|
option. The default is <literal>no</literal>; member zones' content
|
||||||
|
will be stored locally in a file whose name is automatically generated
|
||||||
|
from the view name, catalog zone name, and member zone name.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The <option>min-update-interval</option> option sets the minimum
|
||||||
|
interval between processing of updates to catalog zones, in seconds.
|
||||||
|
If an update to a catalog zone (for example, via IXFR) happens less
|
||||||
|
than <option>min-update-interval</option> seconds after the most
|
||||||
|
recent update, then the changes will not be carried out until this
|
||||||
|
interval has elapsed. The default is <literal>5</literal> seconds.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Catalog zones are defined on a per-view basis. Configuring a non-empty
|
||||||
|
<option>catalog-zones</option> statement in a view will automatically
|
||||||
|
turn on <option>allow-new-zones</option> for that view. (Note: this
|
||||||
|
means <command>rndc addzone</command> and <command>rndc delzone</command>
|
||||||
|
will also work in any view that supports catalog zones.)
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section><info><title>Catalog Zone format</title></info>
|
||||||
|
<para>
|
||||||
|
A catalog zone is a regular DNS zone; therefore, it has to have a
|
||||||
|
single <literal>SOA</literal> and at least one <literal>NS</literal>
|
||||||
|
record.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A record stating the version of the catalog zone format is
|
||||||
|
also required. If the version number listed is not supported by
|
||||||
|
the server, then a catalog zone may not be used by that server.
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
catalog.example. IN SOA . . 2016022901 900 600 86400 1
|
||||||
|
catalog.example. IN NS nsexample.
|
||||||
|
version.catalog.example. IN TXT "1"
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
Note that this record must have the domain name
|
||||||
|
version.<replaceable>catalog-zone-name</replaceable>. This illustrates
|
||||||
|
how the meaning of data stored in a catalog zone is indicated by the
|
||||||
|
the domain name label immediately before the catalog zone domain.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Catalog zones can contain a set of global options that are applied to
|
||||||
|
all member zones, overriding the settings for the catalog zone
|
||||||
|
in the configuration file. Currently only the "masters" option
|
||||||
|
is supported:
|
||||||
|
<!-- TODO masters IN MX (with TSIG), allow-query, allow-tranfer -->
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
masters.catalog.example IN A 192.0.2.1
|
||||||
|
masters.catalog.example IN AAAA 2001:db8::1
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
(Note that if more than one server is defined, the order in which
|
||||||
|
they are used is undefined. The above example could correspond to
|
||||||
|
a zone configured with
|
||||||
|
<option>masters { 192.0.2.1; 2001:db8::1; };</option>
|
||||||
|
or with
|
||||||
|
<option>masters { 2001:db8::1; 192.0.2.1; };</option>.
|
||||||
|
There is currently no way to force a particular ordering.)
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A member zone is added by including a <literal>PTR</literal>
|
||||||
|
resource record in the <literal>zones</literal> sub-domain of the
|
||||||
|
catalog zone. The record label is a <literal>SHA-1</literal> hash
|
||||||
|
of the member zone name in wire format. The target of the PTR
|
||||||
|
record is the member zone name. For example, to add the member
|
||||||
|
zone <literal>domain.example</literal>:
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example IN PTR domain.example.
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
The hash is necessary to identify options for a specific member
|
||||||
|
zone. The member zone-specific options are defined the same way as
|
||||||
|
global options, but in the member zone subdomain:
|
||||||
|
</para>
|
||||||
|
<screen>
|
||||||
|
masters.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example IN A 192.0.2.2
|
||||||
|
masters.5960775ba382e7a4e09263fc06e7c00569b6a05c.zones.catalog.example IN AAAA 2001:db8::2
|
||||||
|
</screen>
|
||||||
|
<para>
|
||||||
|
As would be expected, options defined for a specific zone override
|
||||||
|
the global options defined in the catalog zone. These in turn override
|
||||||
|
the global options defined in the <literal>catalog-zones</literal>
|
||||||
|
statement in the configuration file.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
(Note that none of the global records an option will be inherited if
|
||||||
|
any records are defined for that option for the specific zone. For
|
||||||
|
example, if the zone had a <literal>masters</literal> record of type
|
||||||
|
A but not AAAA, then it would <emphasis>not</emphasis> inherit the
|
||||||
|
type AAAA record from the global option.)
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
@ -54,6 +54,35 @@
|
|||||||
|
|
||||||
<section xml:id="relnotes_features"><info><title>New Features</title></info>
|
<section xml:id="relnotes_features"><info><title>New Features</title></info>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A new method of provisioning secondary servers called
|
||||||
|
"Catalog Zones" has been added. This is an implementation of
|
||||||
|
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://datatracker.ietf.org/doc/draft-muks-dnsop-dns-catalog-zones/">
|
||||||
|
draft-muks-dnsop-dns-catalog-zones/
|
||||||
|
</link>.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
A catalog zone is a regular DNS zone which contains a list
|
||||||
|
of "member zones", along with the configuration options for
|
||||||
|
each of those zones. When a server is configured to use a
|
||||||
|
catalog zone, all the zones listed in the catalog zone are
|
||||||
|
added to the local server as slave zones. When the catalog
|
||||||
|
zone is updated (e.g., by adding or removing zones, or
|
||||||
|
changing configuration options for existing zones) those
|
||||||
|
changes will be put into effect. Since the catalog zone is
|
||||||
|
itself a DNS zone, this means configuration changes can be
|
||||||
|
propagated to slaves using the standard AXFR/IXFR update
|
||||||
|
mechanism.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This feature should be considered experimental. It currently
|
||||||
|
supports only basic features; more advanced features such as
|
||||||
|
ACLs and TSIG keys are not yet supported. Example catalog
|
||||||
|
zone configurations can be found in the Chapter 9 of the
|
||||||
|
BIND Administrator Reference Manual.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Added rndc python module.
|
Added rndc python module.
|
||||||
|
@ -65,11 +65,11 @@ DNSTAPOBJS = dnstap.@O@ dnstap.pb-c.@O@
|
|||||||
|
|
||||||
# Alphabetically
|
# Alphabetically
|
||||||
DNSOBJS = acache.@O@ acl.@O@ adb.@O@ badcache.@O@ byaddr.@O@ \
|
DNSOBJS = acache.@O@ acl.@O@ adb.@O@ badcache.@O@ byaddr.@O@ \
|
||||||
cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \
|
cache.@O@ callbacks.@O@ catz.@O@ clientinfo.@O@ compress.@O@ \
|
||||||
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
|
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
|
||||||
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ forward.@O@ \
|
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ forward.@O@ \
|
||||||
iptable.@O@ journal.@O@ keydata.@O@ keytable.@O@ \
|
ipkeylist.@O@ iptable.@O@ journal.@O@ keydata.@O@ \
|
||||||
lib.@O@ log.@O@ lookup.@O@ \
|
keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \
|
||||||
master.@O@ masterdump.@O@ message.@O@ \
|
master.@O@ masterdump.@O@ message.@O@ \
|
||||||
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ nta.@O@ \
|
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ nta.@O@ \
|
||||||
order.@O@ peer.@O@ portlist.@O@ private.@O@ \
|
order.@O@ peer.@O@ portlist.@O@ private.@O@ \
|
||||||
@ -108,8 +108,8 @@ DNSSRCS = acache.c acl.c adb.c badcache. byaddr.c \
|
|||||||
cache.c callbacks.c clientinfo.c compress.c \
|
cache.c callbacks.c clientinfo.c compress.c \
|
||||||
db.c dbiterator.c dbtable.c diff.c dispatch.c \
|
db.c dbiterator.c dbtable.c diff.c dispatch.c \
|
||||||
dlz.c dns64.c dnssec.c ds.c dyndb.c forward.c \
|
dlz.c dns64.c dnssec.c ds.c dyndb.c forward.c \
|
||||||
iptable.c journal.c keydata.c keytable.c lib.c log.c \
|
ipkeylist.c iptable.c journal.c keydata.c keytable.c lib.c \
|
||||||
lookup.c master.c masterdump.c message.c \
|
log.c lookup.c master.c masterdump.c message.c \
|
||||||
name.c ncache.c nsec.c nsec3.c nta.c \
|
name.c ncache.c nsec.c nsec3.c nta.c \
|
||||||
order.c peer.c portlist.c \
|
order.c peer.c portlist.c \
|
||||||
rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \
|
rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \
|
||||||
|
@ -583,7 +583,7 @@ initialize_action(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called via isc_radix_walk() to find IP table nodes that are
|
* Called via isc_radix_process() to find IP table nodes that are
|
||||||
* insecure.
|
* insecure.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
1474
lib/dns/catz.c
Normal file
1474
lib/dns/catz.c
Normal file
File diff suppressed because it is too large
Load Diff
72
lib/dns/db.c
72
lib/dns/db.c
@ -15,8 +15,6 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@ -307,6 +305,8 @@ dns_db_beginload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
||||||
|
dns_dbonupdatelistener_t *listener;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finish loading 'db'.
|
* Finish loading 'db'.
|
||||||
*/
|
*/
|
||||||
@ -315,6 +315,11 @@ dns_db_endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
|
|||||||
REQUIRE(DNS_CALLBACK_VALID(callbacks));
|
REQUIRE(DNS_CALLBACK_VALID(callbacks));
|
||||||
REQUIRE(callbacks->add_private != NULL);
|
REQUIRE(callbacks->add_private != NULL);
|
||||||
|
|
||||||
|
for (listener = ISC_LIST_HEAD(db->update_listeners);
|
||||||
|
listener != NULL;
|
||||||
|
listener = ISC_LIST_NEXT(listener, link))
|
||||||
|
listener->onupdate(db, listener->onupdate_arg);
|
||||||
|
|
||||||
return ((db->methods->endload)(db, callbacks));
|
return ((db->methods->endload)(db, callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +335,8 @@ dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format) {
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format,
|
dns_db_load3(dns_db_t *db, const char *filename, dns_masterformat_t format,
|
||||||
unsigned int options) {
|
unsigned int options)
|
||||||
|
{
|
||||||
isc_result_t result, eresult;
|
isc_result_t result, eresult;
|
||||||
dns_rdatacallbacks_t callbacks;
|
dns_rdatacallbacks_t callbacks;
|
||||||
|
|
||||||
@ -445,6 +451,7 @@ void
|
|||||||
dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
|
dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
|
||||||
isc_boolean_t commit)
|
isc_boolean_t commit)
|
||||||
{
|
{
|
||||||
|
dns_dbonupdatelistener_t *listener;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close version '*versionp'.
|
* Close version '*versionp'.
|
||||||
@ -456,6 +463,13 @@ dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
|
|||||||
|
|
||||||
(db->methods->closeversion)(db, versionp, commit);
|
(db->methods->closeversion)(db, versionp, commit);
|
||||||
|
|
||||||
|
if (commit == ISC_TRUE) {
|
||||||
|
for (listener = ISC_LIST_HEAD(db->update_listeners);
|
||||||
|
listener != NULL;
|
||||||
|
listener = ISC_LIST_NEXT(listener, link))
|
||||||
|
listener->onupdate(db, listener->onupdate_arg);
|
||||||
|
}
|
||||||
|
|
||||||
ENSURE(*versionp == NULL);
|
ENSURE(*versionp == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1043,3 +1057,55 @@ dns_db_rpz_ready(dns_db_t *db) {
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
return ((db->methods->rpz_ready)(db));
|
return ((db->methods->rpz_ready)(db));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a notify-on-update function the database
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
dns_db_updatenotify_register(dns_db_t *db,
|
||||||
|
dns_dbupdate_callback_t fn,
|
||||||
|
void *fn_arg)
|
||||||
|
{
|
||||||
|
dns_dbonupdatelistener_t *listener;
|
||||||
|
|
||||||
|
REQUIRE(db != NULL);
|
||||||
|
REQUIRE(fn != NULL);
|
||||||
|
|
||||||
|
listener = isc_mem_get(db->mctx, sizeof(dns_dbonupdatelistener_t));
|
||||||
|
if (listener == NULL)
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
|
listener->onupdate = fn;
|
||||||
|
listener->onupdate_arg = fn_arg;
|
||||||
|
|
||||||
|
ISC_LINK_INIT(listener, link);
|
||||||
|
ISC_LIST_APPEND(db->update_listeners, listener, link);
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_db_updatenotify_unregister(dns_db_t *db,
|
||||||
|
dns_dbupdate_callback_t fn,
|
||||||
|
void *fn_arg)
|
||||||
|
{
|
||||||
|
dns_dbonupdatelistener_t *listener;
|
||||||
|
|
||||||
|
REQUIRE(db != NULL);
|
||||||
|
|
||||||
|
for (listener = ISC_LIST_HEAD(db->update_listeners);
|
||||||
|
listener != NULL;
|
||||||
|
listener = ISC_LIST_NEXT(listener, link))
|
||||||
|
{
|
||||||
|
if ((listener->onupdate == fn) &&
|
||||||
|
(listener->onupdate_arg == fn_arg))
|
||||||
|
{
|
||||||
|
ISC_LIST_UNLINK(db->update_listeners, listener, link);
|
||||||
|
isc_mem_put(db->mctx, listener,
|
||||||
|
sizeof(dns_dbonupdatelistener_t));
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_NOTFOUND);
|
||||||
|
}
|
||||||
|
465
lib/dns/include/dns/catz.h
Normal file
465
lib/dns/include/dns/catz.h
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DNS_CATZ_H
|
||||||
|
#define DNS_CATZ_H 1
|
||||||
|
|
||||||
|
#include <isc/ht.h>
|
||||||
|
#include <isc/lang.h>
|
||||||
|
#include <isc/refcount.h>
|
||||||
|
#include <isc/rwlock.h>
|
||||||
|
#include <isc/time.h>
|
||||||
|
#include <isc/timer.h>
|
||||||
|
|
||||||
|
#include <dns/db.h>
|
||||||
|
#include <dns/fixedname.h>
|
||||||
|
#include <dns/ipkeylist.h>
|
||||||
|
#include <dns/rdata.h>
|
||||||
|
#include <dns/types.h>
|
||||||
|
|
||||||
|
ISC_LANG_BEGINDECLS
|
||||||
|
|
||||||
|
#define DNS_CATZ_ERROR_LEVEL ISC_LOG_WARNING
|
||||||
|
#define DNS_CATZ_INFO_LEVEL ISC_LOG_INFO
|
||||||
|
#define DNS_CATZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
|
||||||
|
#define DNS_CATZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
|
||||||
|
#define DNS_CATZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
|
||||||
|
#define DNS_CATZ_DEBUG_QUIET (DNS_CATZ_DEBUG_LEVEL3+1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Catalog Zones functions and structures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Options for a member zone in a catalog
|
||||||
|
*/
|
||||||
|
struct dns_catz_entry_options {
|
||||||
|
/*
|
||||||
|
* Options that can be overriden in catalog zone
|
||||||
|
*/
|
||||||
|
/* masters definition */
|
||||||
|
dns_ipkeylist_t masters;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Options that are only set in named.conf
|
||||||
|
*/
|
||||||
|
/* zone should not be stored on disk (no 'file' statement in def */
|
||||||
|
isc_boolean_t in_memory;
|
||||||
|
/*
|
||||||
|
* Minimal interval between catalog zone updates, if a new version
|
||||||
|
* of catalog zone is received before this time the update will be
|
||||||
|
* postponed. This is a global option for the whole catalog zone.
|
||||||
|
*/
|
||||||
|
isc_uint32_t min_update_interval;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_options_init(dns_catz_options_t *options);
|
||||||
|
/*%<
|
||||||
|
* Initialize 'options' to NULL values.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li options to be non NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_options_free(dns_catz_options_t *options, isc_mem_t *mctx);
|
||||||
|
/*%<
|
||||||
|
* Free 'options' contents into 'mctx'. ('options' itself is not freed.)
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li options to be non NULL
|
||||||
|
* \li mctx to be a valid memory context
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_options_copy(isc_mem_t *mctx, const dns_catz_options_t *opts,
|
||||||
|
dns_catz_options_t *nopts);
|
||||||
|
/*%<
|
||||||
|
* Duplicate 'opts' into 'nopts', allocating space from 'mctx'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li 'mctx' to be a valid memory context
|
||||||
|
* \li 'options' to be non NULL and valid options
|
||||||
|
* \li 'nopts' to be non NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_options_setdefault(isc_mem_t *mctx, const dns_catz_options_t *defaults,
|
||||||
|
dns_catz_options_t *opts);
|
||||||
|
/*%<
|
||||||
|
* Replace empty values in 'opts' with values from 'defaults'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li mctx to be a valid memory context
|
||||||
|
* \li defaults to be non NULL and valid options
|
||||||
|
* \li opts to be non NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_name_t *
|
||||||
|
dns_catz_entry_getname(dns_catz_entry_t *entry);
|
||||||
|
/*%<
|
||||||
|
* Get domain name for 'entry'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li entry to be non NULL
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li domain name for entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_entry_new(isc_mem_t *mctx, const dns_name_t *domain,
|
||||||
|
dns_catz_entry_t **nentryp);
|
||||||
|
/*%<
|
||||||
|
* Allocate a new catz_entry on 'mctx', with the name 'domain'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li mctx to be a valid memory context
|
||||||
|
* \li domain to be valid dns_name or NULL
|
||||||
|
* \li nentryp to be non NULL, *nentryp to be NULL
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li ISC_R_SUCCESS on success
|
||||||
|
* \li ISC_R_NOMEMORY on allocation failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_entry_copy(dns_catz_zone_t *zone, const dns_catz_entry_t *entry,
|
||||||
|
dns_catz_entry_t **nentryp);
|
||||||
|
/*%<
|
||||||
|
* Allocate a new catz_entry and deep copy 'entry' into 'nentryp'.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li mctx to be a valid memory context
|
||||||
|
* \li entry to be non NULL
|
||||||
|
* \li nentryp to be non NULL, *nentryp to be NULL
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li ISC_R_SUCCESS on success
|
||||||
|
* \li ISC_R_NOMEMORY on allocation failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_entry_attach(dns_catz_entry_t *entry, dns_catz_entry_t **entryp);
|
||||||
|
/*%<
|
||||||
|
* Attach an entry
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li entry is not NULL
|
||||||
|
* \li entryp is not NULL, *entryp is NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_entry_detach(dns_catz_zone_t *zone, dns_catz_entry_t **entryp);
|
||||||
|
/*%<
|
||||||
|
* Detach an entry, free if no further references
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zone is not NULL
|
||||||
|
* \li entryp is not NULL, *entryp is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_entry_validate(const dns_catz_entry_t *entry);
|
||||||
|
/*%<
|
||||||
|
* Validate whether entry is correct.
|
||||||
|
* (NOT YET IMPLEMENTED: always returns true)
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_boolean_t
|
||||||
|
dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb);
|
||||||
|
/*%<
|
||||||
|
* Deep compare two entries
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li ea is not NULL
|
||||||
|
* \li eb is not NULL
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li ISC_TRUE if entries are the same
|
||||||
|
* \li ISC_FALSE if the entries differ
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_zone_attach(dns_catz_zone_t *zone, dns_catz_zone_t **zonep);
|
||||||
|
/*%<
|
||||||
|
* Attach a catzone
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zone is not NULL
|
||||||
|
* \li zonep is not NULL, *zonep is NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_zone_detach(dns_catz_zone_t** zonep);
|
||||||
|
/*%<
|
||||||
|
* Detach a zone, free if no further references
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zonep is not NULL, *zonep is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep,
|
||||||
|
const dns_name_t *name);
|
||||||
|
/*%<
|
||||||
|
* Allocate a new catz zone on catzs mctx
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
* \li zonep is not NULL, *zonep is NULL
|
||||||
|
* \li name is not NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_name_t *
|
||||||
|
dns_catz_zone_getname(dns_catz_zone_t *zone);
|
||||||
|
/*%<
|
||||||
|
* Get catalog zone name
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zone is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_catz_options_t *
|
||||||
|
dns_catz_zone_getdefoptions(dns_catz_zone_t *zone);
|
||||||
|
/*%<
|
||||||
|
* Get default member zone options for catalog zone 'zone'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zone is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_zone_resetdefoptions(dns_catz_zone_t *zone);
|
||||||
|
/*%<
|
||||||
|
* Reset the default member zone options for catalog zone 'zone' to
|
||||||
|
* the default values.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zone is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone);
|
||||||
|
/*%<
|
||||||
|
* Merge 'newzone' into 'target', calling addzone/delzone/modzone
|
||||||
|
* (from zone->catzs->zmm) for appropriate member zones.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li orig is not NULL
|
||||||
|
* \li newzone is not NULL, *newzone is not NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_update_process(dns_catz_zones_t *catzs, dns_catz_zone_t *zone,
|
||||||
|
dns_name_t *src_name, dns_rdataset_t *rdataset);
|
||||||
|
/*%<
|
||||||
|
* Process a single rdataset from a catalog zone 'zone' update, src_name is the
|
||||||
|
* record name.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
* \li zone is not NULL
|
||||||
|
* \li src_name is not NULL
|
||||||
|
* \li rdataset is valid
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_generate_masterfilename(dns_catz_zone_t *zone, dns_catz_entry_t *entry,
|
||||||
|
isc_buffer_t **buffer);
|
||||||
|
/*%<
|
||||||
|
* Generate master file name and put it into *buffer (might be reallocated).
|
||||||
|
* The general format of the file name is:
|
||||||
|
* __catz__catalog.zone.name__member_zone_name.db
|
||||||
|
* But if it's too long it's shortened to:
|
||||||
|
* __catz__unique_hash_generated_from_the_above.db
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zone is not NULL
|
||||||
|
* \li entry is not NULL
|
||||||
|
* \li buffer is not NULL and *buffer is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry,
|
||||||
|
isc_buffer_t **buf);
|
||||||
|
/*%<
|
||||||
|
* Generate a zone config entry (in text form) from dns_catz_entry and puts
|
||||||
|
* it into *buf. buf might be reallocated.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li zone is not NULL
|
||||||
|
* \li entry is not NULL
|
||||||
|
* \li buf is not NULL
|
||||||
|
* \li *buf is NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Methods provided by named to dynamically modify the member zones */
|
||||||
|
/* xxxwpk TODO config! */
|
||||||
|
struct dns_catz_zonemodmethods {
|
||||||
|
isc_result_t (*addzone)(dns_catz_entry_t *entry, dns_catz_zone_t *origin,
|
||||||
|
dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata);
|
||||||
|
isc_result_t (*modzone)(dns_catz_entry_t *entry, dns_catz_zone_t *origin,
|
||||||
|
dns_view_t *view, isc_taskmgr_t *taskmgr, void *udata);
|
||||||
|
isc_result_t (*delzone)(dns_catz_entry_t *entry, dns_catz_zone_t *origin,
|
||||||
|
dns_view_t *view, isc_taskmgr_t *task, void *udata);
|
||||||
|
void * udata;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
|
||||||
|
isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
|
||||||
|
isc_timermgr_t *timermgr);
|
||||||
|
/*%<
|
||||||
|
* Allocate a new catz_zones object, a collection storing all catalog zones
|
||||||
|
* for a view.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzsp is not NULL, *catzsp is NULL
|
||||||
|
* \li zmm is not NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_add_zone(dns_catz_zones_t *catzs, const dns_name_t *name,
|
||||||
|
dns_catz_zone_t **catzp);
|
||||||
|
/*%<
|
||||||
|
* Allocate a new catz named 'name' and put it in 'catzs' collection.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
* \li name is not NULL
|
||||||
|
* \li zonep is not NULL, *zonep is NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_catz_zone_t *
|
||||||
|
dns_catz_get_zone(dns_catz_zones_t *catzs, const dns_name_t *name);
|
||||||
|
/*%<
|
||||||
|
* Returns a zone named 'name' from collection 'catzs'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
* \li name is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_catzs_attach(dns_catz_zones_t *catzs, dns_catz_zones_t **catzsp);
|
||||||
|
/*%<
|
||||||
|
* Attach 'catzs' to 'catzsp'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
* \li catzsp is not NULL, *catzsp is NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_catzs_detach(dns_catz_zones_t **catzsp);
|
||||||
|
/*%<
|
||||||
|
* Detach 'catzsp', free if no further references
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzsp is not NULL, *catzsp is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_catzs_set_view(dns_catz_zones_t *catzs, dns_view_t *view);
|
||||||
|
/*%<
|
||||||
|
* Set a view for catzs
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
* \li catzs->view is NULL or catzs->view == view
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg);
|
||||||
|
/*%<
|
||||||
|
* Callback for update of catalog zone database.
|
||||||
|
* If there was no catalog zone update recently it launches an
|
||||||
|
* update_taskaction immediately.
|
||||||
|
* If there was an update recently it schedules update_taskaction for some time
|
||||||
|
* in the future.
|
||||||
|
* If there is an update scheduled it replaces old db version with a new one.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li db is a valid database
|
||||||
|
* \li fn_arg is not NULL (casted to dns_catz_zones_t*)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_update_taskaction(isc_task_t *task, isc_event_t *event);
|
||||||
|
/*%<
|
||||||
|
* Task that launches dns_catz_update_from_db
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li event is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_update_from_db(dns_db_t *db, dns_catz_zones_t *catzs);
|
||||||
|
/*%<
|
||||||
|
* Process an updated database for a catalog zone.
|
||||||
|
* It creates a new catz, iterates over database to fill it with content, and
|
||||||
|
* then merges new catz into old catz.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li db is a valid DB
|
||||||
|
* \li catzs is not NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_prereconfig(dns_catz_zones_t *catzs);
|
||||||
|
/*%<
|
||||||
|
* Called before reconfig, clears 'active' flag on all the zones in set
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_catz_postreconfig(dns_catz_zones_t *catzs);
|
||||||
|
/*%<
|
||||||
|
* Called after reconfig, walks through all zones in set, removes those
|
||||||
|
* inactive and force reload of those with changed configuration.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li catzs is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_catz_get_iterator(dns_catz_zone_t *catz, isc_ht_iter_t **itp);
|
||||||
|
/*%<
|
||||||
|
* Get the hashtable iterator on catalog zone members, point '*itp' to it.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li #ISC_R_SUCCESS -- success
|
||||||
|
* \li Any other value -- failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
ISC_LANG_ENDDECLS
|
||||||
|
|
||||||
|
#endif /* DNS_CATZ_H_ */
|
@ -203,6 +203,9 @@ typedef isc_result_t
|
|||||||
unsigned int argc, char *argv[], void *driverarg,
|
unsigned int argc, char *argv[], void *driverarg,
|
||||||
dns_db_t **dbp);
|
dns_db_t **dbp);
|
||||||
|
|
||||||
|
typedef isc_result_t
|
||||||
|
(*dns_dbupdate_callback_t)(dns_db_t *db, void *fn_arg);
|
||||||
|
|
||||||
#define DNS_DB_MAGIC ISC_MAGIC('D','N','S','D')
|
#define DNS_DB_MAGIC ISC_MAGIC('D','N','S','D')
|
||||||
#define DNS_DB_VALID(db) ISC_MAGIC_VALID(db, DNS_DB_MAGIC)
|
#define DNS_DB_VALID(db) ISC_MAGIC_VALID(db, DNS_DB_MAGIC)
|
||||||
|
|
||||||
@ -224,11 +227,18 @@ struct dns_db {
|
|||||||
dns_name_t origin;
|
dns_name_t origin;
|
||||||
isc_ondestroy_t ondest;
|
isc_ondestroy_t ondest;
|
||||||
isc_mem_t * mctx;
|
isc_mem_t * mctx;
|
||||||
|
ISC_LIST(dns_dbonupdatelistener_t) update_listeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DNS_DBATTR_CACHE 0x01
|
#define DNS_DBATTR_CACHE 0x01
|
||||||
#define DNS_DBATTR_STUB 0x02
|
#define DNS_DBATTR_STUB 0x02
|
||||||
|
|
||||||
|
struct dns_dbonupdatelistener {
|
||||||
|
dns_dbupdate_callback_t onupdate;
|
||||||
|
void * onupdate_arg;
|
||||||
|
ISC_LINK(dns_dbonupdatelistener_t) link;
|
||||||
|
};
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/*%
|
/*%
|
||||||
* Options that can be specified for dns_db_find().
|
* Options that can be specified for dns_db_find().
|
||||||
@ -1624,6 +1634,35 @@ dns_db_rpz_ready(dns_db_t *db);
|
|||||||
* Finish loading a response policy zone.
|
* Finish loading a response policy zone.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_db_updatenotify_register(dns_db_t *db,
|
||||||
|
dns_dbupdate_callback_t fn,
|
||||||
|
void *fn_arg);
|
||||||
|
/*%<
|
||||||
|
* Register a notify-on-update callback function to a database.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* \li 'db' is a valid database
|
||||||
|
* \li 'db' does not have an update callback registered
|
||||||
|
* \li 'fn' is not NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_db_updatenotify_unregister(dns_db_t *db,
|
||||||
|
dns_dbupdate_callback_t fn,
|
||||||
|
void *fn_arg);
|
||||||
|
/*%<
|
||||||
|
* Unregister a notify-on-update callback.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* \li 'db' is a valid database
|
||||||
|
* \li 'db' has update callback registered
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
ISC_LANG_ENDDECLS
|
ISC_LANG_ENDDECLS
|
||||||
|
|
||||||
#endif /* DNS_DB_H */
|
#endif /* DNS_DB_H */
|
||||||
|
@ -80,6 +80,10 @@
|
|||||||
#define DNS_EVENT_KEYDONE (ISC_EVENTCLASS_DNS + 50)
|
#define DNS_EVENT_KEYDONE (ISC_EVENTCLASS_DNS + 50)
|
||||||
#define DNS_EVENT_SETNSEC3PARAM (ISC_EVENTCLASS_DNS + 51)
|
#define DNS_EVENT_SETNSEC3PARAM (ISC_EVENTCLASS_DNS + 51)
|
||||||
#define DNS_EVENT_SETSERIAL (ISC_EVENTCLASS_DNS + 52)
|
#define DNS_EVENT_SETSERIAL (ISC_EVENTCLASS_DNS + 52)
|
||||||
|
#define DNS_EVENT_CATZUPDATED (ISC_EVENTCLASS_DNS + 53)
|
||||||
|
#define DNS_EVENT_CATZADDZONE (ISC_EVENTCLASS_DNS + 54)
|
||||||
|
#define DNS_EVENT_CATZMODZONE (ISC_EVENTCLASS_DNS + 55)
|
||||||
|
#define DNS_EVENT_CATZDELZONE (ISC_EVENTCLASS_DNS + 56)
|
||||||
|
|
||||||
#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0)
|
#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0)
|
||||||
#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)
|
#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535)
|
||||||
|
61
lib/dns/include/dns/ipkeylist.h
Normal file
61
lib/dns/include/dns/ipkeylist.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DNS_IPKEYLIST_H
|
||||||
|
#define DNS_IPKEYLIST_H 1
|
||||||
|
|
||||||
|
#include <isc/types.h>
|
||||||
|
#include <dns/types.h>
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* A structure holding a list of addresses, dscps and keys. Used to
|
||||||
|
* store masters for a slave zone, created by parsing config options.
|
||||||
|
*/
|
||||||
|
struct dns_ipkeylist {
|
||||||
|
isc_sockaddr_t *addrs;
|
||||||
|
isc_dscp_t *dscps;
|
||||||
|
dns_name_t **keys;
|
||||||
|
isc_uint32_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl);
|
||||||
|
/*%<
|
||||||
|
* Free `ipkl` contents using `mctx`.
|
||||||
|
*
|
||||||
|
* After this call, `ipkl` is a freshly cleared structure with all
|
||||||
|
* pointers set to `NULL` and count set to 0.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*\li 'mctx' to be a valid memory context.
|
||||||
|
*\li 'ipkl' to be non NULL and have its members `addrs` and `keys`
|
||||||
|
* allocated. 'dscps' might be NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src,
|
||||||
|
dns_ipkeylist_t *dst);
|
||||||
|
/*%<
|
||||||
|
* Deep copy `src` into empty `dst`, allocating `dst`'s contents.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*\li 'mctx' to be a valid memory context.
|
||||||
|
*\li 'src' to be non NULL
|
||||||
|
*\li 'dst' to be non NULL and point to an empty \ref dns_ipkeylist_t
|
||||||
|
* with all pointers set to `NULL` and count set to 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
@ -391,7 +391,7 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options,
|
dns_rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options,
|
||||||
dns_name_t *foundname, void **data);
|
dns_name_t *foundname, void **data);
|
||||||
/*%<
|
/*%<
|
||||||
* Get the data pointer associated with 'name'.
|
* Get the data pointer associated with 'name'.
|
||||||
@ -430,7 +430,7 @@ dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
|
dns_rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
|
||||||
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
|
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
|
||||||
unsigned int options, dns_rbtfindcallback_t callback,
|
unsigned int options, dns_rbtfindcallback_t callback,
|
||||||
void *callback_arg);
|
void *callback_arg);
|
||||||
|
@ -45,6 +45,12 @@ typedef struct dns_adbfind dns_adbfind_t;
|
|||||||
typedef ISC_LIST(dns_adbfind_t) dns_adbfindlist_t;
|
typedef ISC_LIST(dns_adbfind_t) dns_adbfindlist_t;
|
||||||
typedef struct dns_badcache dns_badcache_t;
|
typedef struct dns_badcache dns_badcache_t;
|
||||||
typedef struct dns_byaddr dns_byaddr_t;
|
typedef struct dns_byaddr dns_byaddr_t;
|
||||||
|
typedef struct dns_catz_zonemodmethods dns_catz_zonemodmethods_t;
|
||||||
|
typedef struct dns_catz_entry_options dns_catz_options_t;
|
||||||
|
typedef struct dns_catz_entry dns_catz_entry_t;
|
||||||
|
typedef struct dns_catz_zone dns_catz_zone_t;
|
||||||
|
typedef struct dns_catz_changed dns_catz_changed_t;
|
||||||
|
typedef struct dns_catz_zones dns_catz_zones_t;
|
||||||
typedef struct dns_client dns_client_t;
|
typedef struct dns_client dns_client_t;
|
||||||
typedef void dns_clientrestrans_t;
|
typedef void dns_clientrestrans_t;
|
||||||
typedef void dns_clientreqtrans_t;
|
typedef void dns_clientreqtrans_t;
|
||||||
@ -57,6 +63,7 @@ typedef struct dns_dbimplementation dns_dbimplementation_t;
|
|||||||
typedef struct dns_dbiterator dns_dbiterator_t;
|
typedef struct dns_dbiterator dns_dbiterator_t;
|
||||||
typedef void dns_dbload_t;
|
typedef void dns_dbload_t;
|
||||||
typedef void dns_dbnode_t;
|
typedef void dns_dbnode_t;
|
||||||
|
typedef struct dns_dbonupdatelistener dns_dbonupdatelistener_t;
|
||||||
typedef struct dns_dbtable dns_dbtable_t;
|
typedef struct dns_dbtable dns_dbtable_t;
|
||||||
typedef void dns_dbversion_t;
|
typedef void dns_dbversion_t;
|
||||||
typedef struct dns_dlzimplementation dns_dlzimplementation_t;
|
typedef struct dns_dlzimplementation dns_dlzimplementation_t;
|
||||||
@ -146,6 +153,7 @@ typedef struct dns_zone dns_zone_t;
|
|||||||
typedef ISC_LIST(dns_zone_t) dns_zonelist_t;
|
typedef ISC_LIST(dns_zone_t) dns_zonelist_t;
|
||||||
typedef struct dns_zonemgr dns_zonemgr_t;
|
typedef struct dns_zonemgr dns_zonemgr_t;
|
||||||
typedef struct dns_zt dns_zt_t;
|
typedef struct dns_zt dns_zt_t;
|
||||||
|
typedef struct dns_ipkeylist dns_ipkeylist_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are not using GSSAPI, define the types we use as opaque types here.
|
* If we are not using GSSAPI, define the types we use as opaque types here.
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
#include <isc/stdtime.h>
|
#include <isc/stdtime.h>
|
||||||
|
|
||||||
#include <dns/acl.h>
|
#include <dns/acl.h>
|
||||||
|
#include <dns/catz.h>
|
||||||
#include <dns/clientinfo.h>
|
#include <dns/clientinfo.h>
|
||||||
#include <dns/dnstap.h>
|
#include <dns/dnstap.h>
|
||||||
#include <dns/fixedname.h>
|
#include <dns/fixedname.h>
|
||||||
@ -178,6 +179,7 @@ struct dns_view {
|
|||||||
dns_dns64list_t dns64;
|
dns_dns64list_t dns64;
|
||||||
unsigned int dns64cnt;
|
unsigned int dns64cnt;
|
||||||
dns_rpz_zones_t *rpzs;
|
dns_rpz_zones_t *rpzs;
|
||||||
|
dns_catz_zones_t *catzs;
|
||||||
dns_dlzdblist_t dlz_searched;
|
dns_dlzdblist_t dlz_searched;
|
||||||
dns_dlzdblist_t dlz_unsearched;
|
dns_dlzdblist_t dlz_unsearched;
|
||||||
isc_uint32_t fail_ttl;
|
isc_uint32_t fail_ttl;
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#ifndef DNS_ZONE_H
|
#ifndef DNS_ZONE_H
|
||||||
#define DNS_ZONE_H 1
|
#define DNS_ZONE_H 1
|
||||||
|
|
||||||
@ -32,6 +30,7 @@
|
|||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
#include <isc/rwlock.h>
|
#include <isc/rwlock.h>
|
||||||
|
|
||||||
|
#include <dns/catz.h>
|
||||||
#include <dns/master.h>
|
#include <dns/master.h>
|
||||||
#include <dns/masterdump.h>
|
#include <dns/masterdump.h>
|
||||||
#include <dns/rdatastruct.h>
|
#include <dns/rdatastruct.h>
|
||||||
@ -2393,6 +2392,30 @@ dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db);
|
|||||||
dns_rpz_num_t
|
dns_rpz_num_t
|
||||||
dns_zone_get_rpz_num(dns_zone_t *zone);
|
dns_zone_get_rpz_num(dns_zone_t *zone);
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs);
|
||||||
|
/*%<
|
||||||
|
* Enable zone as catalog zone.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* \li 'zone' is a valid zone object
|
||||||
|
* \li 'catzs' is not NULL
|
||||||
|
* \li prior to calling, zone->catzs is NULL or is equal to 'catzs'
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db);
|
||||||
|
/*%<
|
||||||
|
* If 'zone' is a catalog zone, then set up a notify-on-update trigger
|
||||||
|
* in its database. (If not a catalog zone, this function has no effect.)
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
* \li 'zone' is a valid zone object
|
||||||
|
* \li 'db' is not NULL
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level);
|
dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level);
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options,
|
dns_zt_find(dns_zt_t *zt, const dns_name_t *name, unsigned int options,
|
||||||
dns_name_t *foundname, dns_zone_t **zone);
|
dns_name_t *foundname, dns_zone_t **zone);
|
||||||
/*%<
|
/*%<
|
||||||
* Find the best match for 'name' in 'zt'. If foundname is non NULL
|
* Find the best match for 'name' in 'zt'. If foundname is non NULL
|
||||||
|
92
lib/dns/ipkeylist.c
Normal file
92
lib/dns/ipkeylist.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <isc/mem.h>
|
||||||
|
#include <isc/sockaddr.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include <dns/ipkeylist.h>
|
||||||
|
#include <dns/name.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl) {
|
||||||
|
isc_uint32_t i;
|
||||||
|
|
||||||
|
REQUIRE(ipkl != NULL);
|
||||||
|
REQUIRE(ipkl->addrs != NULL);
|
||||||
|
REQUIRE(ipkl->keys != NULL);
|
||||||
|
|
||||||
|
if (ipkl->count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
isc_mem_put(mctx, ipkl->addrs, ipkl->count * sizeof(isc_sockaddr_t));
|
||||||
|
if (ipkl->dscps != NULL)
|
||||||
|
isc_mem_put(mctx, ipkl->dscps,
|
||||||
|
ipkl->count * sizeof(isc_dscp_t));
|
||||||
|
for (i = 0; i < ipkl->count; i++) {
|
||||||
|
if (ipkl->keys[i] == NULL)
|
||||||
|
continue;
|
||||||
|
if (dns_name_dynamic(ipkl->keys[i]))
|
||||||
|
dns_name_free(ipkl->keys[i], mctx);
|
||||||
|
isc_mem_put(mctx, ipkl->keys[i], sizeof(dns_name_t));
|
||||||
|
}
|
||||||
|
isc_mem_put(mctx, ipkl->keys, ipkl->count * sizeof(dns_name_t *));
|
||||||
|
ipkl->count = 0;
|
||||||
|
ipkl->addrs = NULL;
|
||||||
|
ipkl->dscps = NULL;
|
||||||
|
ipkl->keys = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src,
|
||||||
|
dns_ipkeylist_t *dst)
|
||||||
|
{
|
||||||
|
isc_uint32_t i;
|
||||||
|
|
||||||
|
REQUIRE(dst != NULL);
|
||||||
|
REQUIRE(dst->count == 0 &&
|
||||||
|
dst->addrs == NULL && dst->keys == NULL && dst->dscps == NULL);
|
||||||
|
|
||||||
|
if (src->count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dst->count = src->count;
|
||||||
|
|
||||||
|
dst->addrs = isc_mem_get(mctx,
|
||||||
|
src->count * sizeof(isc_sockaddr_t));
|
||||||
|
memmove(dst->addrs, src->addrs,
|
||||||
|
src->count * sizeof(isc_sockaddr_t));
|
||||||
|
|
||||||
|
if (src->dscps != NULL) {
|
||||||
|
dst->dscps = isc_mem_get(mctx,
|
||||||
|
src->count * sizeof(isc_dscp_t));
|
||||||
|
memmove(dst->dscps, src->dscps,
|
||||||
|
src->count * sizeof(isc_dscp_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->keys != NULL) {
|
||||||
|
dst->keys = isc_mem_get(mctx, src->count * sizeof(dns_name_t *));
|
||||||
|
for (i = 0; i < src->count; i++) {
|
||||||
|
if (src->keys[i] != NULL) {
|
||||||
|
dst->keys[i] = isc_mem_get(mctx,
|
||||||
|
sizeof(dns_name_t));
|
||||||
|
dns_name_dup(src->keys[i], mctx, dst->keys[i]);
|
||||||
|
} else {
|
||||||
|
dst->keys[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1566,9 +1566,13 @@ dns_name_totext2(const dns_name_t *name, unsigned int options,
|
|||||||
if (nlen != 0 && trem == 0)
|
if (nlen != 0 && trem == 0)
|
||||||
return (ISC_R_NOSPACE);
|
return (ISC_R_NOSPACE);
|
||||||
|
|
||||||
if (!saw_root || omit_final_dot)
|
if (!saw_root || omit_final_dot) {
|
||||||
trem++;
|
trem++;
|
||||||
|
tdata--;
|
||||||
|
}
|
||||||
|
if (trem > 0) {
|
||||||
|
*tdata = 0;
|
||||||
|
}
|
||||||
isc_buffer_add(target, tlen - trem);
|
isc_buffer_add(target, tlen - trem);
|
||||||
|
|
||||||
#ifdef ISC_PLATFORM_USETHREADS
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
@ -1457,7 +1457,7 @@ dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data) {
|
|||||||
* Find the node for "name" in the tree of trees.
|
* Find the node for "name" in the tree of trees.
|
||||||
*/
|
*/
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
|
dns_rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
|
||||||
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
|
dns_rbtnode_t **node, dns_rbtnodechain_t *chain,
|
||||||
unsigned int options, dns_rbtfindcallback_t callback,
|
unsigned int options, dns_rbtfindcallback_t callback,
|
||||||
void *callback_arg)
|
void *callback_arg)
|
||||||
@ -1988,7 +1988,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname,
|
|||||||
* Get the data pointer associated with 'name'.
|
* Get the data pointer associated with 'name'.
|
||||||
*/
|
*/
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options,
|
dns_rbt_findname(dns_rbt_t *rbt, const dns_name_t *name, unsigned int options,
|
||||||
dns_name_t *foundname, void **data) {
|
dns_name_t *foundname, void **data) {
|
||||||
dns_rbtnode_t *node = NULL;
|
dns_rbtnode_t *node = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
@ -1159,6 +1159,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
|
|||||||
char buf[DNS_NAME_FORMATSIZE];
|
char buf[DNS_NAME_FORMATSIZE];
|
||||||
dns_rbt_t **treep;
|
dns_rbt_t **treep;
|
||||||
isc_time_t start;
|
isc_time_t start;
|
||||||
|
dns_dbonupdatelistener_t *listener, *listener_next;
|
||||||
|
|
||||||
if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in)
|
if (IS_CACHE(rbtdb) && rbtdb->common.rdclass == dns_rdataclass_in)
|
||||||
overmem((dns_db_t *)rbtdb, (isc_boolean_t)-1);
|
overmem((dns_db_t *)rbtdb, (isc_boolean_t)-1);
|
||||||
@ -1317,6 +1318,16 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
|
|||||||
isc_file_munmap(rbtdb->mmap_location,
|
isc_file_munmap(rbtdb->mmap_location,
|
||||||
(size_t) rbtdb->mmap_size);
|
(size_t) rbtdb->mmap_size);
|
||||||
|
|
||||||
|
for (listener = ISC_LIST_HEAD(rbtdb->common.update_listeners);
|
||||||
|
listener != NULL;
|
||||||
|
listener = listener_next)
|
||||||
|
{
|
||||||
|
listener_next = ISC_LIST_NEXT(listener, link);
|
||||||
|
ISC_LIST_UNLINK(rbtdb->common.update_listeners, listener, link);
|
||||||
|
isc_mem_put(rbtdb->common.mctx, listener,
|
||||||
|
sizeof(dns_dbonupdatelistener_t));
|
||||||
|
}
|
||||||
|
|
||||||
isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb));
|
isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb));
|
||||||
isc_ondestroy_notify(&ondest, rbtdb);
|
isc_ondestroy_notify(&ondest, rbtdb);
|
||||||
}
|
}
|
||||||
@ -8166,6 +8177,8 @@ dns_rbtdb_create
|
|||||||
rbtdb->common.rdclass = rdclass;
|
rbtdb->common.rdclass = rdclass;
|
||||||
rbtdb->common.mctx = NULL;
|
rbtdb->common.mctx = NULL;
|
||||||
|
|
||||||
|
ISC_LIST_INIT(rbtdb->common.update_listeners);
|
||||||
|
|
||||||
result = RBTDB_INITLOCK(&rbtdb->lock);
|
result = RBTDB_INITLOCK(&rbtdb->lock);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto cleanup_rbtdb;
|
goto cleanup_rbtdb;
|
||||||
|
@ -229,6 +229,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||||||
view->v6_aaaa = dns_aaaa_ok;
|
view->v6_aaaa = dns_aaaa_ok;
|
||||||
view->aaaa_acl = NULL;
|
view->aaaa_acl = NULL;
|
||||||
view->rpzs = NULL;
|
view->rpzs = NULL;
|
||||||
|
view->catzs = NULL;
|
||||||
dns_fixedname_init(&view->dlv_fixed);
|
dns_fixedname_init(&view->dlv_fixed);
|
||||||
view->managed_keys = NULL;
|
view->managed_keys = NULL;
|
||||||
view->redirect = NULL;
|
view->redirect = NULL;
|
||||||
@ -379,6 +380,8 @@ destroy(dns_view_t *view) {
|
|||||||
dns_rrl_view_destroy(view);
|
dns_rrl_view_destroy(view);
|
||||||
if (view->rpzs != NULL)
|
if (view->rpzs != NULL)
|
||||||
dns_rpz_detach_rpzs(&view->rpzs);
|
dns_rpz_detach_rpzs(&view->rpzs);
|
||||||
|
if (view->catzs != NULL)
|
||||||
|
dns_catz_catzs_detach(&view->catzs);
|
||||||
for (dlzdb = ISC_LIST_HEAD(view->dlz_searched);
|
for (dlzdb = ISC_LIST_HEAD(view->dlz_searched);
|
||||||
dlzdb != NULL;
|
dlzdb != NULL;
|
||||||
dlzdb = ISC_LIST_HEAD(view->dlz_searched)) {
|
dlzdb = ISC_LIST_HEAD(view->dlz_searched)) {
|
||||||
@ -578,6 +581,9 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
|
|||||||
if (view->flush)
|
if (view->flush)
|
||||||
dns_zone_flush(rdzone);
|
dns_zone_flush(rdzone);
|
||||||
}
|
}
|
||||||
|
if (view->catzs != NULL) {
|
||||||
|
dns_catz_catzs_detach(&view->catzs);
|
||||||
|
}
|
||||||
done = all_done(view);
|
done = all_done(view);
|
||||||
UNLOCK(&view->lock);
|
UNLOCK(&view->lock);
|
||||||
|
|
||||||
|
@ -109,6 +109,28 @@ dns_cache_setcachesize
|
|||||||
dns_cache_setcleaninginterval
|
dns_cache_setcleaninginterval
|
||||||
dns_cache_setfilename
|
dns_cache_setfilename
|
||||||
dns_cache_updatestats
|
dns_cache_updatestats
|
||||||
|
dns_catz_catzs_attach
|
||||||
|
dns_catz_catzs_detach
|
||||||
|
dns_catz_catzs_set_view
|
||||||
|
dns_catz_dbupdate_callback
|
||||||
|
dns_catz_entry_attach
|
||||||
|
dns_catz_entry_cmp
|
||||||
|
dns_catz_entry_detach
|
||||||
|
dns_catz_entry_getname
|
||||||
|
dns_catz_entry_validate
|
||||||
|
dns_catz_get_iterator
|
||||||
|
dns_catz_get_zone
|
||||||
|
dns_catz_options_clear
|
||||||
|
dns_catz_options_init
|
||||||
|
dns_catz_postreconfig
|
||||||
|
dns_catz_prereconfig
|
||||||
|
dns_catz_update_from_db
|
||||||
|
dns_catz_update_taskaction
|
||||||
|
dns_catz_zone_attach
|
||||||
|
dns_catz_zone_detach
|
||||||
|
dns_catz_zone_getdefoptions
|
||||||
|
dns_catz_zone_getname
|
||||||
|
dns_catz_zones_merge
|
||||||
dns_cert_fromtext
|
dns_cert_fromtext
|
||||||
dns_cert_totext
|
dns_cert_totext
|
||||||
dns_client_addtrustedkey
|
dns_client_addtrustedkey
|
||||||
@ -209,6 +231,8 @@ dns_db_settask
|
|||||||
dns_db_subtractrdataset
|
dns_db_subtractrdataset
|
||||||
dns_db_transfernode
|
dns_db_transfernode
|
||||||
dns_db_unregister
|
dns_db_unregister
|
||||||
|
dns_db_updatenotify_register
|
||||||
|
dns_db_updatenotify_unregister
|
||||||
dns_dbiterator_current
|
dns_dbiterator_current
|
||||||
dns_dbiterator_destroy
|
dns_dbiterator_destroy
|
||||||
dns_dbiterator_first
|
dns_dbiterator_first
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
#include <dns/callbacks.h>
|
#include <dns/callbacks.h>
|
||||||
|
#include <dns/catz.h>
|
||||||
#include <dns/db.h>
|
#include <dns/db.h>
|
||||||
#include <dns/diff.h>
|
#include <dns/diff.h>
|
||||||
#include <dns/events.h>
|
#include <dns/events.h>
|
||||||
@ -279,8 +280,10 @@ axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
|
|||||||
xfr->rdclass,
|
xfr->rdclass,
|
||||||
0, NULL, /* XXX guess */
|
0, NULL, /* XXX guess */
|
||||||
dbp);
|
dbp);
|
||||||
if (result == ISC_R_SUCCESS)
|
if (result == ISC_R_SUCCESS) {
|
||||||
dns_zone_rpz_enable_db(xfr->zone, *dbp);
|
dns_zone_rpz_enable_db(xfr->zone, *dbp);
|
||||||
|
dns_zone_catz_enable_db(xfr->zone, *dbp);
|
||||||
|
}
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include <dns/acl.h>
|
#include <dns/acl.h>
|
||||||
#include <dns/adb.h>
|
#include <dns/adb.h>
|
||||||
#include <dns/callbacks.h>
|
#include <dns/callbacks.h>
|
||||||
|
#include <dns/catz.h>
|
||||||
#include <dns/db.h>
|
#include <dns/db.h>
|
||||||
#include <dns/dbiterator.h>
|
#include <dns/dbiterator.h>
|
||||||
#include <dns/dlz.h>
|
#include <dns/dlz.h>
|
||||||
@ -380,6 +381,11 @@ struct dns_zone {
|
|||||||
dns_rpz_zones_t *rpzs;
|
dns_rpz_zones_t *rpzs;
|
||||||
dns_rpz_num_t rpz_num;
|
dns_rpz_num_t rpz_num;
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* catalog zone data
|
||||||
|
*/
|
||||||
|
dns_catz_zones_t *catzs;
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Serial number update method.
|
* Serial number update method.
|
||||||
*/
|
*/
|
||||||
@ -1036,6 +1042,9 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||||||
zone->automatic = ISC_FALSE;
|
zone->automatic = ISC_FALSE;
|
||||||
zone->rpzs = NULL;
|
zone->rpzs = NULL;
|
||||||
zone->rpz_num = DNS_RPZ_INVALID_NUM;
|
zone->rpz_num = DNS_RPZ_INVALID_NUM;
|
||||||
|
|
||||||
|
zone->catzs = NULL;
|
||||||
|
|
||||||
ISC_LIST_INIT(zone->forwards);
|
ISC_LIST_INIT(zone->forwards);
|
||||||
zone->raw = NULL;
|
zone->raw = NULL;
|
||||||
zone->secure = NULL;
|
zone->secure = NULL;
|
||||||
@ -1170,6 +1179,9 @@ zone_free(dns_zone_t *zone) {
|
|||||||
dns_rpz_detach_rpzs(&zone->rpzs);
|
dns_rpz_detach_rpzs(&zone->rpzs);
|
||||||
zone->rpz_num = DNS_RPZ_INVALID_NUM;
|
zone->rpz_num = DNS_RPZ_INVALID_NUM;
|
||||||
}
|
}
|
||||||
|
if (zone->catzs != NULL) {
|
||||||
|
dns_catz_catzs_detach(&zone->catzs);
|
||||||
|
}
|
||||||
zone_freedbargs(zone);
|
zone_freedbargs(zone);
|
||||||
RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
|
RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
|
||||||
== ISC_R_SUCCESS);
|
== ISC_R_SUCCESS);
|
||||||
@ -1748,6 +1760,34 @@ dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
|
||||||
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
REQUIRE(catzs != NULL);
|
||||||
|
|
||||||
|
LOCK_ZONE(zone);
|
||||||
|
INSIST(zone->catzs == NULL || zone->catzs == catzs);
|
||||||
|
dns_catz_catzs_set_view(catzs, zone->view);
|
||||||
|
if (zone->catzs == NULL)
|
||||||
|
dns_catz_catzs_attach(catzs, &zone->catzs);
|
||||||
|
UNLOCK_ZONE(zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a zone is a catalog zone, attach it to update notification in database.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
|
||||||
|
REQUIRE(DNS_ZONE_VALID(zone));
|
||||||
|
REQUIRE(db != NULL);
|
||||||
|
|
||||||
|
if (zone->catzs != NULL) {
|
||||||
|
dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
|
||||||
|
zone->catzs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static isc_boolean_t
|
static isc_boolean_t
|
||||||
zone_touched(dns_zone_t *zone) {
|
zone_touched(dns_zone_t *zone) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@ -2344,6 +2384,7 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
|
|||||||
unsigned int options;
|
unsigned int options;
|
||||||
|
|
||||||
dns_zone_rpz_enable_db(zone, db);
|
dns_zone_rpz_enable_db(zone, db);
|
||||||
|
dns_zone_catz_enable_db(zone, db);
|
||||||
options = get_master_options(zone);
|
options = get_master_options(zone);
|
||||||
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
|
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
|
||||||
options |= DNS_MASTER_MANYERRORS;
|
options |= DNS_MASTER_MANYERRORS;
|
||||||
|
@ -155,7 +155,7 @@ dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options,
|
dns_zt_find(dns_zt_t *zt, const dns_name_t *name, unsigned int options,
|
||||||
dns_name_t *foundname, dns_zone_t **zonep)
|
dns_name_t *foundname, dns_zone_t **zonep)
|
||||||
{
|
{
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
@ -57,8 +57,8 @@ OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \
|
|||||||
aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
|
aes.@O@ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
|
||||||
bind9.@O@ buffer.@O@ bufferlist.@O@ \
|
bind9.@O@ buffer.@O@ bufferlist.@O@ \
|
||||||
commandline.@O@ counter.@O@ crc64.@O@ error.@O@ event.@O@ \
|
commandline.@O@ counter.@O@ crc64.@O@ error.@O@ event.@O@ \
|
||||||
hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
|
hash.@O@ ht.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ \
|
||||||
httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
|
hmacsha.@O@ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
|
||||||
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
|
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
|
||||||
md5.@O@ mem.@O@ mutexblock.@O@ \
|
md5.@O@ mem.@O@ mutexblock.@O@ \
|
||||||
netaddr.@O@ netscope.@O@ pool.@O@ ondestroy.@O@ \
|
netaddr.@O@ netscope.@O@ pool.@O@ ondestroy.@O@ \
|
||||||
@ -77,8 +77,8 @@ CHACHASRCS = chacha_private.h
|
|||||||
SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \
|
SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \
|
||||||
aes.c assertions.c backtrace.c base32.c base64.c bind9.c \
|
aes.c assertions.c backtrace.c base32.c base64.c bind9.c \
|
||||||
buffer.c bufferlist.c commandline.c counter.c crc64.c \
|
buffer.c bufferlist.c commandline.c counter.c crc64.c \
|
||||||
error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \
|
error.c event.c hash.c ht.c heap.c hex.c hmacmd5.c \
|
||||||
httpd.c inet_aton.c iterated_hash.c \
|
hmacsha.c httpd.c inet_aton.c iterated_hash.c \
|
||||||
lex.c lfsr.c lib.c log.c \
|
lex.c lfsr.c lib.c log.c \
|
||||||
md5.c mem.c mutexblock.c \
|
md5.c mem.c mutexblock.c \
|
||||||
netaddr.c netscope.c pool.c ondestroy.c \
|
netaddr.c netscope.c pool.c ondestroy.c \
|
||||||
|
@ -60,6 +60,7 @@ isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) {
|
|||||||
*/
|
*/
|
||||||
REQUIRE(b->length <= length);
|
REQUIRE(b->length <= length);
|
||||||
REQUIRE(base != NULL);
|
REQUIRE(base != NULL);
|
||||||
|
REQUIRE(b->autore = ISC_FALSE);
|
||||||
|
|
||||||
(void)memmove(base, b->base, b->length);
|
(void)memmove(base, b->base, b->length);
|
||||||
b->base = base;
|
b->base = base;
|
||||||
@ -79,6 +80,13 @@ isc__buffer_invalidate(isc_buffer_t *b) {
|
|||||||
ISC__BUFFER_INVALIDATE(b);
|
ISC__BUFFER_INVALIDATE(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_buffer_setautorealloc(isc_buffer_t *b, isc_boolean_t enable) {
|
||||||
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
|
REQUIRE(b->mctx != NULL);
|
||||||
|
b->autore = enable;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
isc__buffer_region(isc_buffer_t *b, isc_region_t *r) {
|
isc__buffer_region(isc_buffer_t *b, isc_region_t *r) {
|
||||||
/*
|
/*
|
||||||
@ -279,8 +287,13 @@ isc_buffer_getuint8(isc_buffer_t *b) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) {
|
isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) {
|
||||||
|
isc_result_t result;
|
||||||
REQUIRE(ISC_BUFFER_VALID(b));
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
REQUIRE(b->used + 1 <= b->length);
|
if (b->autore) {
|
||||||
|
result = isc_buffer_reserve(&b, 1);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
REQUIRE(isc_buffer_availablelength(b) >= 1);
|
||||||
|
|
||||||
ISC__BUFFER_PUTUINT8(b, val);
|
ISC__BUFFER_PUTUINT8(b, val);
|
||||||
}
|
}
|
||||||
@ -308,16 +321,26 @@ isc_buffer_getuint16(isc_buffer_t *b) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) {
|
isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) {
|
||||||
|
isc_result_t result;
|
||||||
REQUIRE(ISC_BUFFER_VALID(b));
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
REQUIRE(b->used + 2 <= b->length);
|
if (b->autore) {
|
||||||
|
result = isc_buffer_reserve(&b, 2);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
REQUIRE(isc_buffer_availablelength(b) >= 2);
|
||||||
|
|
||||||
ISC__BUFFER_PUTUINT16(b, val);
|
ISC__BUFFER_PUTUINT16(b, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) {
|
isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) {
|
||||||
|
isc_result_t result;
|
||||||
REQUIRE(ISC_BUFFER_VALID(b));
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
REQUIRE(b->used + 3 <= b->length);
|
if (b->autore) {
|
||||||
|
result = isc_buffer_reserve(&b, 3);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
REQUIRE(isc_buffer_availablelength(b) >= 3);
|
||||||
|
|
||||||
ISC__BUFFER_PUTUINT24(b, val);
|
ISC__BUFFER_PUTUINT24(b, val);
|
||||||
}
|
}
|
||||||
@ -347,8 +370,13 @@ isc_buffer_getuint32(isc_buffer_t *b) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
|
isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
|
||||||
|
isc_result_t result;
|
||||||
REQUIRE(ISC_BUFFER_VALID(b));
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
REQUIRE(b->used + 4 <= b->length);
|
if (b->autore == ISC_TRUE) {
|
||||||
|
result = isc_buffer_reserve(&b, 4);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
REQUIRE(isc_buffer_availablelength(b) >= 4);
|
||||||
|
|
||||||
ISC__BUFFER_PUTUINT32(b, val);
|
ISC__BUFFER_PUTUINT32(b, val);
|
||||||
}
|
}
|
||||||
@ -380,11 +408,16 @@ isc_buffer_getuint48(isc_buffer_t *b) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
|
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
|
||||||
|
isc_result_t result;
|
||||||
isc_uint16_t valhi;
|
isc_uint16_t valhi;
|
||||||
isc_uint32_t vallo;
|
isc_uint32_t vallo;
|
||||||
|
|
||||||
REQUIRE(ISC_BUFFER_VALID(b));
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
REQUIRE(b->used + 6 <= b->length);
|
if (b->autore == ISC_TRUE) {
|
||||||
|
result = isc_buffer_reserve(&b, 6);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
REQUIRE(isc_buffer_availablelength(b) >= 6);
|
||||||
|
|
||||||
valhi = (isc_uint16_t)(val >> 32);
|
valhi = (isc_uint16_t)(val >> 32);
|
||||||
vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
|
vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
|
||||||
@ -396,8 +429,13 @@ void
|
|||||||
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
|
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
|
||||||
unsigned int length)
|
unsigned int length)
|
||||||
{
|
{
|
||||||
|
isc_result_t result;
|
||||||
REQUIRE(ISC_BUFFER_VALID(b));
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
REQUIRE(b->used + length <= b->length);
|
if (b->autore == ISC_TRUE) {
|
||||||
|
result = isc_buffer_reserve(&b, length);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
REQUIRE(isc_buffer_availablelength(b) >= length);
|
||||||
|
|
||||||
ISC__BUFFER_PUTMEM(b, base, length);
|
ISC__BUFFER_PUTMEM(b, base, length);
|
||||||
}
|
}
|
||||||
@ -406,6 +444,7 @@ void
|
|||||||
isc__buffer_putstr(isc_buffer_t *b, const char *source) {
|
isc__buffer_putstr(isc_buffer_t *b, const char *source) {
|
||||||
unsigned int l;
|
unsigned int l;
|
||||||
unsigned char *cp;
|
unsigned char *cp;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
REQUIRE(ISC_BUFFER_VALID(b));
|
REQUIRE(ISC_BUFFER_VALID(b));
|
||||||
REQUIRE(source != NULL);
|
REQUIRE(source != NULL);
|
||||||
@ -414,8 +453,11 @@ isc__buffer_putstr(isc_buffer_t *b, const char *source) {
|
|||||||
* Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once.
|
* Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once.
|
||||||
*/
|
*/
|
||||||
l = strlen(source);
|
l = strlen(source);
|
||||||
|
if (b->autore == ISC_TRUE) {
|
||||||
REQUIRE(l <= isc_buffer_availablelength(b));
|
result = isc_buffer_reserve(&b, l);
|
||||||
|
REQUIRE(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
REQUIRE(isc_buffer_availablelength(b) >= l);
|
||||||
|
|
||||||
cp = isc_buffer_used(b);
|
cp = isc_buffer_used(b);
|
||||||
memmove(cp, source, l);
|
memmove(cp, source, l);
|
||||||
@ -448,16 +490,21 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
|
|||||||
unsigned int length)
|
unsigned int length)
|
||||||
{
|
{
|
||||||
isc_buffer_t *dbuf;
|
isc_buffer_t *dbuf;
|
||||||
|
unsigned char * bdata;
|
||||||
REQUIRE(dynbuffer != NULL);
|
REQUIRE(dynbuffer != NULL);
|
||||||
REQUIRE(*dynbuffer == NULL);
|
REQUIRE(*dynbuffer == NULL);
|
||||||
|
|
||||||
dbuf = isc_mem_get(mctx, length + sizeof(isc_buffer_t));
|
dbuf = isc_mem_get(mctx, sizeof(isc_buffer_t));
|
||||||
if (dbuf == NULL)
|
if (dbuf == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t),
|
bdata = isc_mem_get(mctx, length);
|
||||||
length);
|
if (bdata == NULL) {
|
||||||
|
isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t));
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_buffer_init(dbuf, bdata, length);
|
||||||
dbuf->mctx = mctx;
|
dbuf->mctx = mctx;
|
||||||
|
|
||||||
ENSURE(ISC_BUFFER_VALID(dbuf));
|
ENSURE(ISC_BUFFER_VALID(dbuf));
|
||||||
@ -469,7 +516,7 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
|
|||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) {
|
isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) {
|
||||||
isc_buffer_t *dbuf;
|
unsigned char *bdata;
|
||||||
|
|
||||||
REQUIRE(dynbuffer != NULL);
|
REQUIRE(dynbuffer != NULL);
|
||||||
REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
|
REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
|
||||||
@ -483,18 +530,16 @@ isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) {
|
|||||||
* it doesn't remap pages, but does ordinary copy. So is
|
* it doesn't remap pages, but does ordinary copy. So is
|
||||||
* isc_mem_reallocate(), which has additional issues.
|
* isc_mem_reallocate(), which has additional issues.
|
||||||
*/
|
*/
|
||||||
dbuf = isc_mem_get((*dynbuffer)->mctx, length + sizeof(isc_buffer_t));
|
bdata = isc_mem_get((*dynbuffer)->mctx, length);
|
||||||
if (dbuf == NULL)
|
if (bdata == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
memmove(dbuf, *dynbuffer, (*dynbuffer)->length + sizeof(isc_buffer_t));
|
memmove(bdata, (*dynbuffer)->base, (*dynbuffer)->length);
|
||||||
isc_mem_put(dbuf->mctx, *dynbuffer,
|
isc_mem_put((*dynbuffer)->mctx, (*dynbuffer)->base,
|
||||||
(*dynbuffer)->length + sizeof(isc_buffer_t));
|
(*dynbuffer)->length);
|
||||||
|
|
||||||
dbuf->base = ((unsigned char *)dbuf) + sizeof(isc_buffer_t);
|
(*dynbuffer)->base = bdata;
|
||||||
dbuf->length = length;
|
(*dynbuffer)->length = length;
|
||||||
|
|
||||||
*dynbuffer = dbuf;
|
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@ -530,7 +575,6 @@ isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
isc_buffer_free(isc_buffer_t **dynbuffer) {
|
isc_buffer_free(isc_buffer_t **dynbuffer) {
|
||||||
unsigned int real_length;
|
|
||||||
isc_buffer_t *dbuf;
|
isc_buffer_t *dbuf;
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
|
|
||||||
@ -540,11 +584,10 @@ isc_buffer_free(isc_buffer_t **dynbuffer) {
|
|||||||
|
|
||||||
dbuf = *dynbuffer;
|
dbuf = *dynbuffer;
|
||||||
*dynbuffer = NULL; /* destroy external reference */
|
*dynbuffer = NULL; /* destroy external reference */
|
||||||
|
|
||||||
real_length = dbuf->length + sizeof(isc_buffer_t);
|
|
||||||
mctx = dbuf->mctx;
|
mctx = dbuf->mctx;
|
||||||
dbuf->mctx = NULL;
|
dbuf->mctx = NULL;
|
||||||
isc_buffer_invalidate(dbuf);
|
|
||||||
|
|
||||||
isc_mem_put(mctx, dbuf, real_length);
|
isc_mem_put(mctx, dbuf->base, dbuf->length);
|
||||||
|
isc_buffer_invalidate(dbuf);
|
||||||
|
isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t));
|
||||||
}
|
}
|
||||||
|
339
lib/isc/ht.c
Normal file
339
lib/isc/ht.c
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <isc/hash.h>
|
||||||
|
#include <isc/ht.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
#include <isc/magic.h>
|
||||||
|
#include <isc/mem.h>
|
||||||
|
#include <isc/result.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct isc_ht_node isc_ht_node_t;
|
||||||
|
|
||||||
|
#define ISC_HT_MAGIC ISC_MAGIC('H', 'T', 'a', 'b')
|
||||||
|
#define ISC_HT_VALID(ht) ISC_MAGIC_VALID(ht, ISC_HT_MAGIC)
|
||||||
|
|
||||||
|
struct isc_ht_node {
|
||||||
|
void *value;
|
||||||
|
isc_ht_node_t *next;
|
||||||
|
size_t keysize;
|
||||||
|
unsigned char key[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct isc_ht {
|
||||||
|
unsigned int magic;
|
||||||
|
isc_mem_t *mctx;
|
||||||
|
size_t size;
|
||||||
|
size_t mask;
|
||||||
|
unsigned int count;
|
||||||
|
isc_ht_node_t **table;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct isc_ht_iter {
|
||||||
|
isc_ht_t *ht;
|
||||||
|
isc_uint32_t i;
|
||||||
|
isc_ht_node_t *cur;
|
||||||
|
};
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, isc_uint8_t bits) {
|
||||||
|
isc_ht_t *ht = NULL;
|
||||||
|
isc_uint32_t i;
|
||||||
|
|
||||||
|
REQUIRE(htp != NULL && *htp == NULL);
|
||||||
|
REQUIRE(mctx != NULL);
|
||||||
|
REQUIRE(bits >= 1 && bits <= (sizeof(size_t)*8 - 1));
|
||||||
|
|
||||||
|
ht = isc_mem_get(mctx, sizeof(struct isc_ht));
|
||||||
|
if (ht == NULL) {
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
ht->mctx = NULL;
|
||||||
|
isc_mem_attach(mctx, &ht->mctx);
|
||||||
|
|
||||||
|
ht->size = (1<<bits);
|
||||||
|
ht->mask = (1<<bits)-1;
|
||||||
|
ht->count = 0;
|
||||||
|
|
||||||
|
ht->table = isc_mem_get(ht->mctx, ht->size * sizeof(isc_ht_node_t*));
|
||||||
|
if (ht->table == NULL) {
|
||||||
|
isc_mem_putanddetach(&ht->mctx, ht, sizeof(struct isc_ht));
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ht->size; i++) {
|
||||||
|
ht->table[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ht->magic = ISC_HT_MAGIC;
|
||||||
|
|
||||||
|
*htp = ht;
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_ht_destroy(isc_ht_t **htp) {
|
||||||
|
isc_ht_t *ht;
|
||||||
|
isc_uint32_t i;
|
||||||
|
|
||||||
|
REQUIRE(htp != NULL);
|
||||||
|
|
||||||
|
ht = *htp;
|
||||||
|
REQUIRE(ISC_HT_VALID(ht));
|
||||||
|
|
||||||
|
ht->magic = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ht->size; i++) {
|
||||||
|
isc_ht_node_t *node = ht->table[i];
|
||||||
|
while (node != NULL) {
|
||||||
|
isc_ht_node_t *next = node->next;
|
||||||
|
ht->count--;
|
||||||
|
isc_mem_put(ht->mctx, node,
|
||||||
|
sizeof(isc_ht_node_t) + node->keysize);
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INSIST(ht->count == 0);
|
||||||
|
|
||||||
|
isc_mem_put(ht->mctx, ht->table, ht->size * sizeof(isc_ht_node_t*));
|
||||||
|
isc_mem_putanddetach(&ht->mctx, ht, sizeof(struct isc_ht));
|
||||||
|
|
||||||
|
*htp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_add(isc_ht_t *ht, const unsigned char *key,
|
||||||
|
isc_uint32_t keysize, void *value)
|
||||||
|
{
|
||||||
|
isc_ht_node_t *node;
|
||||||
|
isc_uint32_t hash;
|
||||||
|
|
||||||
|
REQUIRE(ISC_HT_VALID(ht));
|
||||||
|
REQUIRE(key != NULL && keysize > 0);
|
||||||
|
|
||||||
|
hash = isc_hash_function(key, keysize, ISC_TRUE, NULL);
|
||||||
|
node = ht->table[hash & ht->mask];
|
||||||
|
while (node != NULL) {
|
||||||
|
if (keysize == node->keysize &&
|
||||||
|
memcmp(key, node->key, keysize) == 0)
|
||||||
|
{
|
||||||
|
return (ISC_R_EXISTS);
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = isc_mem_get(ht->mctx, sizeof(isc_ht_node_t) + keysize);
|
||||||
|
if (node == NULL) {
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove(node->key, key, keysize);
|
||||||
|
node->keysize = keysize;
|
||||||
|
node->next = ht->table[hash & ht->mask];
|
||||||
|
node->value = value;
|
||||||
|
|
||||||
|
ht->count++;
|
||||||
|
ht->table[hash & ht->mask] = node;
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_find(const isc_ht_t *ht, const unsigned char *key,
|
||||||
|
isc_uint32_t keysize, void **valuep)
|
||||||
|
{
|
||||||
|
isc_ht_node_t *node;
|
||||||
|
isc_uint32_t hash;
|
||||||
|
|
||||||
|
REQUIRE(ISC_HT_VALID(ht));
|
||||||
|
REQUIRE(key != NULL && keysize > 0);
|
||||||
|
REQUIRE(valuep != NULL);
|
||||||
|
|
||||||
|
hash = isc_hash_function(key, keysize, ISC_TRUE, NULL);
|
||||||
|
node = ht->table[hash & ht->mask];
|
||||||
|
while (node != NULL) {
|
||||||
|
if (keysize == node->keysize &&
|
||||||
|
memcmp(key, node->key, keysize) == 0)
|
||||||
|
{
|
||||||
|
*valuep = node->value;
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_NOTFOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_delete(isc_ht_t *ht, const unsigned char *key, isc_uint32_t keysize) {
|
||||||
|
isc_ht_node_t *node, *prev;
|
||||||
|
isc_uint32_t hash;
|
||||||
|
|
||||||
|
REQUIRE(ISC_HT_VALID(ht));
|
||||||
|
REQUIRE(key != NULL && keysize > 0);
|
||||||
|
|
||||||
|
prev = NULL;
|
||||||
|
hash = isc_hash_function(key, keysize, ISC_TRUE, NULL);
|
||||||
|
node = ht->table[hash & ht->mask];
|
||||||
|
while (node != NULL) {
|
||||||
|
if (keysize == node->keysize &&
|
||||||
|
memcmp(key, node->key, keysize) == 0)
|
||||||
|
{
|
||||||
|
if (prev == NULL) {
|
||||||
|
ht->table[hash & ht->mask] = node->next;
|
||||||
|
} else {
|
||||||
|
prev->next = node->next;
|
||||||
|
}
|
||||||
|
isc_mem_put(ht->mctx, node,
|
||||||
|
sizeof(isc_ht_node_t) + node->keysize);
|
||||||
|
ht->count--;
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = node;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
return (ISC_R_NOTFOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_iter_create(isc_ht_t *ht, isc_ht_iter_t **itp) {
|
||||||
|
isc_ht_iter_t *it;
|
||||||
|
|
||||||
|
REQUIRE(ISC_HT_VALID(ht));
|
||||||
|
REQUIRE(itp != NULL && *itp == NULL);
|
||||||
|
|
||||||
|
if (ht->count == 0)
|
||||||
|
return (ISC_R_NOMORE);
|
||||||
|
|
||||||
|
it = isc_mem_get(ht->mctx, sizeof(isc_ht_iter_t));
|
||||||
|
if (it == NULL)
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
|
it->ht = ht;
|
||||||
|
it->i = 0;
|
||||||
|
it->cur = NULL;
|
||||||
|
|
||||||
|
*itp = it;
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_ht_iter_destroy(isc_ht_iter_t **itp) {
|
||||||
|
isc_ht_iter_t *it;
|
||||||
|
isc_ht_t *ht;
|
||||||
|
|
||||||
|
REQUIRE(itp != NULL && *itp != NULL);
|
||||||
|
|
||||||
|
it = *itp;
|
||||||
|
ht = it->ht;
|
||||||
|
isc_mem_put(ht->mctx, it, sizeof(isc_ht_iter_t));
|
||||||
|
|
||||||
|
*itp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_iter_first(isc_ht_iter_t *it) {
|
||||||
|
REQUIRE(it != NULL);
|
||||||
|
|
||||||
|
it->i = 0;
|
||||||
|
while (it->i < it->ht->size && it->ht->table[it->i] == NULL)
|
||||||
|
it->i++;
|
||||||
|
|
||||||
|
if(it->i == it->ht->size)
|
||||||
|
return (ISC_R_NOMORE);
|
||||||
|
|
||||||
|
it->cur = it->ht->table[it->i];
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_iter_next(isc_ht_iter_t *it) {
|
||||||
|
REQUIRE(it != NULL);
|
||||||
|
REQUIRE(it->cur != NULL);
|
||||||
|
|
||||||
|
it->cur = it->cur->next;
|
||||||
|
if (it->cur == NULL) {
|
||||||
|
while (it->i < it->ht->size && it->ht->table[it->i] == NULL)
|
||||||
|
it->i++;
|
||||||
|
if (it->i < it->ht->size)
|
||||||
|
return (ISC_R_NOMORE);
|
||||||
|
it->cur = it->ht->table[it->i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_ht_iter_current(isc_ht_iter_t *it, void **valuep) {
|
||||||
|
REQUIRE(it != NULL);
|
||||||
|
REQUIRE(it->cur != NULL);
|
||||||
|
*valuep = it->cur->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
isc_ht_count(isc_ht_t *ht) {
|
||||||
|
REQUIRE(ISC_HT_VALID(ht));
|
||||||
|
|
||||||
|
return(ht->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_walk(isc_ht_t *ht, isc_ht_walkfn walkfn, void *udata) {
|
||||||
|
isc_uint32_t i;
|
||||||
|
isc_result_t res;
|
||||||
|
|
||||||
|
REQUIRE(ISC_HT_VALID(ht));
|
||||||
|
|
||||||
|
for (i = 0; i < ht->size; i++) {
|
||||||
|
isc_ht_node_t *cur = ht->table[i];
|
||||||
|
isc_ht_node_t *prev = NULL;
|
||||||
|
while (cur != NULL) {
|
||||||
|
if (walkfn == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res = walkfn(udata, cur->key, cur->keysize, cur->value);
|
||||||
|
if (res != ISC_R_SUCCESS && res != ISC_R_EXISTS) {
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
if (res == ISC_R_EXISTS) { /* remove this node */
|
||||||
|
isc_ht_node_t *tmp = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
if (prev == NULL) {
|
||||||
|
ht->table[i] = cur;
|
||||||
|
} else {
|
||||||
|
prev->next = cur;
|
||||||
|
}
|
||||||
|
isc_mem_put(ht->mctx, tmp,
|
||||||
|
sizeof(isc_ht_node_t) + tmp->keysize);
|
||||||
|
ht->count--;
|
||||||
|
} else {
|
||||||
|
prev = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
@ -184,6 +184,8 @@ struct isc_buffer {
|
|||||||
ISC_LINK(isc_buffer_t) link;
|
ISC_LINK(isc_buffer_t) link;
|
||||||
/*! private internal elements */
|
/*! private internal elements */
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
|
/* automatically realloc buffer at put* */
|
||||||
|
isc_boolean_t autore;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@ -316,6 +318,16 @@ isc__buffer_invalidate(isc_buffer_t *b);
|
|||||||
* calling isc_buffer_init() on it will cause an assertion failure.
|
* calling isc_buffer_init() on it will cause an assertion failure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
isc_buffer_setautorealloc(isc_buffer_t *b, isc_boolean_t enable);
|
||||||
|
/*!<
|
||||||
|
* \brief Enable or disable autoreallocation on 'b'.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*\li 'b' is a valid dynamic buffer (b->mctx != NULL).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
|
isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
|
||||||
/*!<
|
/*!<
|
||||||
@ -530,7 +542,8 @@ isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val);
|
|||||||
* Requires:
|
* Requires:
|
||||||
*\li 'b' is a valid buffer.
|
*\li 'b' is a valid buffer.
|
||||||
*
|
*
|
||||||
*\li The length of the unused region of 'b' is at least 1.
|
*\li The length of the unused region of 'b' is at least 1
|
||||||
|
* or the buffer has autoreallocation enabled.
|
||||||
*
|
*
|
||||||
* Ensures:
|
* Ensures:
|
||||||
*\li The used pointer in 'b' is advanced by 1.
|
*\li The used pointer in 'b' is advanced by 1.
|
||||||
@ -546,7 +559,8 @@ isc_buffer_getuint16(isc_buffer_t *b);
|
|||||||
*
|
*
|
||||||
*\li 'b' is a valid buffer.
|
*\li 'b' is a valid buffer.
|
||||||
*
|
*
|
||||||
*\li The length of the available region of 'b' is at least 2.
|
*\li The length of the available region of 'b' is at least 2
|
||||||
|
* or the buffer has autoreallocation enabled.
|
||||||
*
|
*
|
||||||
* Ensures:
|
* Ensures:
|
||||||
*
|
*
|
||||||
@ -566,7 +580,8 @@ isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val);
|
|||||||
* Requires:
|
* Requires:
|
||||||
*\li 'b' is a valid buffer.
|
*\li 'b' is a valid buffer.
|
||||||
*
|
*
|
||||||
*\li The length of the unused region of 'b' is at least 2.
|
*\li The length of the unused region of 'b' is at least 2
|
||||||
|
* or the buffer has autoreallocation enabled.
|
||||||
*
|
*
|
||||||
* Ensures:
|
* Ensures:
|
||||||
*\li The used pointer in 'b' is advanced by 2.
|
*\li The used pointer in 'b' is advanced by 2.
|
||||||
@ -602,7 +617,8 @@ isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val);
|
|||||||
* Requires:
|
* Requires:
|
||||||
*\li 'b' is a valid buffer.
|
*\li 'b' is a valid buffer.
|
||||||
*
|
*
|
||||||
*\li The length of the unused region of 'b' is at least 4.
|
*\li The length of the unused region of 'b' is at least 4
|
||||||
|
* or the buffer has autoreallocation enabled.
|
||||||
*
|
*
|
||||||
* Ensures:
|
* Ensures:
|
||||||
*\li The used pointer in 'b' is advanced by 4.
|
*\li The used pointer in 'b' is advanced by 4.
|
||||||
@ -638,7 +654,8 @@ isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val);
|
|||||||
* Requires:
|
* Requires:
|
||||||
*\li 'b' is a valid buffer.
|
*\li 'b' is a valid buffer.
|
||||||
*
|
*
|
||||||
*\li The length of the unused region of 'b' is at least 6.
|
*\li The length of the unused region of 'b' is at least 6
|
||||||
|
* or the buffer has autoreallocation enabled.
|
||||||
*
|
*
|
||||||
* Ensures:
|
* Ensures:
|
||||||
*\li The used pointer in 'b' is advanced by 6.
|
*\li The used pointer in 'b' is advanced by 6.
|
||||||
@ -653,7 +670,8 @@ isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val);
|
|||||||
* Requires:
|
* Requires:
|
||||||
*\li 'b' is a valid buffer.
|
*\li 'b' is a valid buffer.
|
||||||
*
|
*
|
||||||
* The length of the unused region of 'b' is at least 3.
|
* The length of the unused region of 'b' is at least 3
|
||||||
|
* or the buffer has autoreallocation enabled.
|
||||||
*
|
*
|
||||||
* Ensures:
|
* Ensures:
|
||||||
*\li The used pointer in 'b' is advanced by 3.
|
*\li The used pointer in 'b' is advanced by 3.
|
||||||
@ -666,7 +684,8 @@ isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
|
|||||||
* \brief Copy 'length' bytes of memory at 'base' into 'b'.
|
* \brief Copy 'length' bytes of memory at 'base' into 'b'.
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*\li 'b' is a valid buffer.
|
*\li 'b' is a valid buffer, and it has at least 'length'
|
||||||
|
* or the buffer has autoreallocation enabled.
|
||||||
*
|
*
|
||||||
*\li 'base' points to 'length' bytes of valid memory.
|
*\li 'base' points to 'length' bytes of valid memory.
|
||||||
*
|
*
|
||||||
@ -682,7 +701,7 @@ isc__buffer_putstr(isc_buffer_t *b, const char *source);
|
|||||||
*
|
*
|
||||||
*\li 'source' to be a valid NULL terminated string.
|
*\li 'source' to be a valid NULL terminated string.
|
||||||
*
|
*
|
||||||
*\li strlen(source) <= isc_buffer_available(b)
|
*\li strlen(source) <= isc_buffer_available(b) || b->mctx != NULL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@ -738,6 +757,7 @@ ISC_LANG_ENDDECLS
|
|||||||
(_b)->mctx = NULL; \
|
(_b)->mctx = NULL; \
|
||||||
ISC_LINK_INIT(_b, link); \
|
ISC_LINK_INIT(_b, link); \
|
||||||
(_b)->magic = ISC_BUFFER_MAGIC; \
|
(_b)->magic = ISC_BUFFER_MAGIC; \
|
||||||
|
(_b)->autore = ISC_FALSE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)
|
#define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define ISC_HASH_H 1
|
#define ISC_HASH_H 1
|
||||||
|
|
||||||
#include <isc/types.h>
|
#include <isc/types.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
/*****
|
/*****
|
||||||
***** Module Info
|
***** Module Info
|
||||||
@ -105,7 +106,8 @@ isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp);
|
isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp)
|
||||||
|
ISC_DEPRECATED;
|
||||||
/*!<
|
/*!<
|
||||||
* \brief Attach to a hash object.
|
* \brief Attach to a hash object.
|
||||||
*
|
*
|
||||||
@ -113,7 +115,8 @@ isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_hash_ctxdetach(isc_hash_t **hctxp);
|
isc_hash_ctxdetach(isc_hash_t **hctxp)
|
||||||
|
ISC_DEPRECATED;
|
||||||
/*!<
|
/*!<
|
||||||
* \brief Detach from a hash object.
|
* \brief Detach from a hash object.
|
||||||
*
|
*
|
||||||
@ -158,10 +161,12 @@ isc_hash_init(void);
|
|||||||
/*@{*/
|
/*@{*/
|
||||||
unsigned int
|
unsigned int
|
||||||
isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key,
|
isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key,
|
||||||
unsigned int keylen, isc_boolean_t case_sensitive);
|
unsigned int keylen, isc_boolean_t case_sensitive)
|
||||||
|
ISC_DEPRECATED;
|
||||||
unsigned int
|
unsigned int
|
||||||
isc_hash_calc(const unsigned char *key, unsigned int keylen,
|
isc_hash_calc(const unsigned char *key, unsigned int keylen,
|
||||||
isc_boolean_t case_sensitive);
|
isc_boolean_t case_sensitive)
|
||||||
|
ISC_DEPRECATED;
|
||||||
/*!<
|
/*!<
|
||||||
* \brief Calculate a hash value.
|
* \brief Calculate a hash value.
|
||||||
*
|
*
|
||||||
@ -183,7 +188,8 @@ isc_hash_calc(const unsigned char *key, unsigned int keylen,
|
|||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc__hash_setvec(const isc_uint16_t *vec);
|
isc__hash_setvec(const isc_uint16_t *vec)
|
||||||
|
ISC_DEPRECATED;
|
||||||
|
|
||||||
/*!<
|
/*!<
|
||||||
* \brief Set the contents of the random vector used in hashing.
|
* \brief Set the contents of the random vector used in hashing.
|
||||||
|
167
lib/isc/include/isc/ht.h
Normal file
167
lib/isc/include/isc/ht.h
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ! \file */
|
||||||
|
|
||||||
|
#ifndef ISC_HT_H
|
||||||
|
#define ISC_HT_H 1
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
#include <isc/result.h>
|
||||||
|
|
||||||
|
typedef struct isc_ht isc_ht_t;
|
||||||
|
typedef struct isc_ht_iter isc_ht_iter_t;
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Initialize hashtable at *htp, using memory context and size of (1<<bits)
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*\li htp is not NULL
|
||||||
|
*\li *htp is NULL
|
||||||
|
*\li mctx is a valid memory context
|
||||||
|
*\li bits >=1 && bits <=32
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*\li #ISC_R_NOMEMORY -- not enough memory to create pool
|
||||||
|
*\li #ISC_R_SUCCESS -- all is well.
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_init(isc_ht_t **htp, isc_mem_t *mctx, isc_uint8_t bits);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Destroy hashtable, freeing everything
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li *htp is valid hashtable
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
isc_ht_destroy(isc_ht_t **htp);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Add a node to hashtable, pointed by binary key 'key' of size 'keysize';
|
||||||
|
* set its value to 'value'
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*\li ht is a valid hashtable
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*\li #ISC_R_NOMEMORY -- not enough memory to create pool
|
||||||
|
*\li #ISC_R_EXISTS -- node of the same key already exists
|
||||||
|
*\li #ISC_R_SUCCESS -- all is well.
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_add(isc_ht_t *ht, const unsigned char *key, isc_uint32_t keysize,
|
||||||
|
void *value);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Find a node matching 'key'/'keysize' in hashtable 'ht';
|
||||||
|
* if found, set 'value' to its value
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li 'ht' is a valid hashtable
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li #ISC_R_SUCCESS -- success
|
||||||
|
* \li #ISC_R_NOTFOUND -- key not found
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_find(const isc_ht_t *ht, const unsigned char *key,
|
||||||
|
isc_uint32_t keysize, void **valuep);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Delete node from hashtable
|
||||||
|
* Requires:
|
||||||
|
*\li ht is a valid hashtable
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
*\li #ISC_R_NOTFOUND -- key not found
|
||||||
|
*\li #ISC_R_SUCCESS -- all is well
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_delete(isc_ht_t *ht, const unsigned char *key, isc_uint32_t keysize);
|
||||||
|
|
||||||
|
|
||||||
|
typedef isc_result_t (*isc_ht_walkfn)(void *udata, const unsigned char *key,
|
||||||
|
isc_uint32_t keysize, void *data);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Create an iterator for the hashtable; point '*itp' to it.
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_iter_create(isc_ht_t *ht, isc_ht_iter_t **itp);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Destroy the iterator '*itp', set it to NULL
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
isc_ht_iter_destroy(isc_ht_iter_t **itp);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Set an iterator to the first entry.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li #ISC_R_SUCCESS -- success
|
||||||
|
* \li #ISC_R_NOMORE -- no data in the hashtable
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_iter_first(isc_ht_iter_t *it);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Set an iterator to the next entry.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li #ISC_R_SUCCESS -- success
|
||||||
|
* \li #ISC_R_NOMORE -- end of hashtable reached
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_iter_next(isc_ht_iter_t *it);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Set 'value' to the current value under the iterator
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
isc_ht_iter_current(isc_ht_iter_t *it, void **valuep);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Walks the hashtable, calling 'walkfn' on each node
|
||||||
|
*
|
||||||
|
* \li If 'walkfn' returns ISC_R_SUCCESS, walk is continued
|
||||||
|
* \li If 'walkfn' returns ISC_R_EXISTS, walk is continued but the
|
||||||
|
* node is removed
|
||||||
|
* \li If 'walkfn' returns anything else, walk is aborted and function returns
|
||||||
|
* this value
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
* \li 'ht' is a valid hashtable
|
||||||
|
* \li 'walkfn' is not NULL
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* \li #ISC_R_SUCCESS -- all is well
|
||||||
|
* \li Any other, as returned by 'walkfn'
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
isc_ht_walk(isc_ht_t *ht, isc_ht_walkfn walkfn, void *udata);
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Returns the number of items in the hashtable.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*\li 'ht' is a valid hashtable
|
||||||
|
*/
|
||||||
|
unsigned int
|
||||||
|
isc_ht_count(isc_ht_t *ht);
|
||||||
|
#endif
|
@ -248,4 +248,13 @@
|
|||||||
*/
|
*/
|
||||||
#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
|
#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Misc.
|
||||||
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define ISC_DEPRECATED __attribute__((deprecated))
|
||||||
|
#else
|
||||||
|
#define ISC_DEPRECATED /* none */
|
||||||
|
#endif /* __GNUC __ */
|
||||||
|
|
||||||
#endif /* ISC_UTIL_H */
|
#endif /* ISC_UTIL_H */
|
||||||
|
@ -675,7 +675,6 @@ mem_getunlocked(isc__mem_t *ctx, size_t size) {
|
|||||||
new_size = size;
|
new_size = size;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there are no blocks in the free list for this size, get a chunk
|
* If there are no blocks in the free list for this size, get a chunk
|
||||||
* of memory and then break it up into "new_size"-sized blocks, adding
|
* of memory and then break it up into "new_size"-sized blocks, adding
|
||||||
@ -687,9 +686,11 @@ mem_getunlocked(isc__mem_t *ctx, size_t size) {
|
|||||||
/*
|
/*
|
||||||
* The free list uses the "rounded-up" size "new_size".
|
* The free list uses the "rounded-up" size "new_size".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = ctx->freelists[new_size];
|
ret = ctx->freelists[new_size];
|
||||||
ctx->freelists[new_size] = ctx->freelists[new_size]->next;
|
ctx->freelists[new_size] = ctx->freelists[new_size]->next;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The stats[] uses the _actual_ "size" requested by the
|
* The stats[] uses the _actual_ "size" requested by the
|
||||||
* caller, with the caveat (in the code above) that "size" >= the
|
* caller, with the caveat (in the code above) that "size" >= the
|
||||||
|
@ -1723,7 +1723,10 @@ isc__task_beginexclusive(isc_task_t *task0) {
|
|||||||
isc__taskmgr_t *manager = task->manager;
|
isc__taskmgr_t *manager = task->manager;
|
||||||
|
|
||||||
REQUIRE(task->state == task_state_running);
|
REQUIRE(task->state == task_state_running);
|
||||||
/* XXX: Require task == manager->excl? */
|
/*
|
||||||
|
* TODO REQUIRE(task == task->manager->excl);
|
||||||
|
* it should be here, it fails on shutdown server->task
|
||||||
|
*/
|
||||||
|
|
||||||
LOCK(&manager->lock);
|
LOCK(&manager->lock);
|
||||||
if (manager->exclusive_requested) {
|
if (manager->exclusive_requested) {
|
||||||
|
@ -41,7 +41,7 @@ SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \
|
|||||||
parse_test.c pool_test.c print_test.c regex_test.c \
|
parse_test.c pool_test.c print_test.c regex_test.c \
|
||||||
socket_test.c safe_test.c time_test.c aes_test.c \
|
socket_test.c safe_test.c time_test.c aes_test.c \
|
||||||
file_test.c buffer_test.c counter_test.c mem_test.c \
|
file_test.c buffer_test.c counter_test.c mem_test.c \
|
||||||
result_test.c
|
result_test.c ht_test.c
|
||||||
|
|
||||||
SUBDIRS =
|
SUBDIRS =
|
||||||
TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
|
TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
|
||||||
@ -51,7 +51,7 @@ TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
|
|||||||
print_test@EXEEXT@ regex_test@EXEEXT@ socket_test@EXEEXT@ \
|
print_test@EXEEXT@ regex_test@EXEEXT@ socket_test@EXEEXT@ \
|
||||||
safe_test@EXEEXT@ time_test@EXEEXT@ aes_test@EXEEXT@ \
|
safe_test@EXEEXT@ time_test@EXEEXT@ aes_test@EXEEXT@ \
|
||||||
file_test@EXEEXT@ buffer_test@EXEEXT@ counter_test@EXEEXT@ \
|
file_test@EXEEXT@ buffer_test@EXEEXT@ counter_test@EXEEXT@ \
|
||||||
mem_test@EXEEXT@ result_test@EXEEXT@
|
mem_test@EXEEXT@ result_test@EXEEXT@ ht_test@EXEEXT@
|
||||||
|
|
||||||
@BIND9_MAKE_RULES@
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
@ -144,6 +144,10 @@ result_test@EXEEXT@: result_test.@O@ ${ISCDEPLIBS}
|
|||||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||||
result_test.@O@ ${ISCLIBS} ${LIBS}
|
result_test.@O@ ${ISCLIBS} ${LIBS}
|
||||||
|
|
||||||
|
ht_test@EXEEXT@: ht_test.@O@ ${ISCDEPLIBS}
|
||||||
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
|
||||||
|
ht_test.@O@ ${ISCLIBS} ${LIBS}
|
||||||
|
|
||||||
unit::
|
unit::
|
||||||
sh ${top_srcdir}/unit/unittest.sh
|
sh ${top_srcdir}/unit/unittest.sh
|
||||||
|
|
||||||
|
@ -135,11 +135,74 @@ ATF_TC_BODY(isc_buffer_reallocate, tc) {
|
|||||||
isc_test_end();
|
isc_test_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ATF_TC(isc_buffer_dynamic);
|
||||||
|
ATF_TC_HEAD(isc_buffer_dynamic, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "dynamic buffer automatic reallocation");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_buffer_dynamic, tc) {
|
||||||
|
isc_result_t result;
|
||||||
|
isc_buffer_t *b;
|
||||||
|
size_t last_length = 10;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
result = isc_test_begin(NULL, ISC_TRUE);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
b = NULL;
|
||||||
|
result = isc_buffer_allocate(mctx, &b, last_length);
|
||||||
|
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE(b != NULL);
|
||||||
|
ATF_CHECK_EQ(b->length, last_length);
|
||||||
|
|
||||||
|
isc_buffer_setautorealloc(b, ISC_TRUE);
|
||||||
|
|
||||||
|
isc_buffer_putuint8(b, 1);
|
||||||
|
|
||||||
|
for (i = 0; i < 1000; i++) {
|
||||||
|
isc_buffer_putstr(b, "thisisa24charslongstring");
|
||||||
|
}
|
||||||
|
ATF_CHECK(b->length-last_length >= 1000*24);
|
||||||
|
last_length+=1000*24;
|
||||||
|
|
||||||
|
for (i = 0; i < 10000; i++) {
|
||||||
|
isc_buffer_putuint8(b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_CHECK(b->length-last_length >= 10000*1);
|
||||||
|
last_length += 10000*1;
|
||||||
|
|
||||||
|
for (i = 0; i < 10000; i++) {
|
||||||
|
isc_buffer_putuint16(b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_CHECK(b->length-last_length >= 10000*2);
|
||||||
|
|
||||||
|
last_length += 10000*2;
|
||||||
|
for (i = 0; i < 10000; i++) {
|
||||||
|
isc_buffer_putuint24(b, 1);
|
||||||
|
}
|
||||||
|
ATF_CHECK(b->length-last_length >= 10000*3);
|
||||||
|
|
||||||
|
last_length+=10000*3;
|
||||||
|
|
||||||
|
for (i = 0; i < 10000; i++) {
|
||||||
|
isc_buffer_putuint32(b, 1);
|
||||||
|
}
|
||||||
|
ATF_CHECK(b->length-last_length >= 10000*4);
|
||||||
|
|
||||||
|
|
||||||
|
isc_buffer_free(&b);
|
||||||
|
|
||||||
|
isc_test_end();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main
|
* Main
|
||||||
*/
|
*/
|
||||||
ATF_TP_ADD_TCS(tp) {
|
ATF_TP_ADD_TCS(tp) {
|
||||||
ATF_TP_ADD_TC(tp, isc_buffer_reserve);
|
ATF_TP_ADD_TC(tp, isc_buffer_reserve);
|
||||||
ATF_TP_ADD_TC(tp, isc_buffer_reallocate);
|
ATF_TP_ADD_TC(tp, isc_buffer_reallocate);
|
||||||
|
ATF_TP_ADD_TC(tp, isc_buffer_dynamic);
|
||||||
return (atf_no_error());
|
return (atf_no_error());
|
||||||
}
|
}
|
||||||
|
327
lib/isc/tests/ht_test.c
Normal file
327
lib/isc/tests/ht_test.c
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* 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 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ! \file */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <atf-c.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <isc/hash.h>
|
||||||
|
#include <isc/ht.h>
|
||||||
|
#include <isc/mem.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
static void *
|
||||||
|
default_memalloc(void *arg, size_t size) {
|
||||||
|
UNUSED(arg);
|
||||||
|
if (size == 0U)
|
||||||
|
size = 1;
|
||||||
|
return (malloc(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
default_memfree(void *arg, void *ptr) {
|
||||||
|
UNUSED(arg);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_ht_full(int bits, int count) {
|
||||||
|
isc_ht_t *ht = NULL;
|
||||||
|
isc_result_t result;
|
||||||
|
isc_mem_t *mctx = NULL;
|
||||||
|
isc_int64_t i;
|
||||||
|
|
||||||
|
result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
|
||||||
|
NULL, &mctx, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
isc_ht_init(&ht, mctx, bits);
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
/*
|
||||||
|
* Note that the string we're snprintfing is always > 16 bytes
|
||||||
|
* so we are always filling the key.
|
||||||
|
*/
|
||||||
|
unsigned char key[16];
|
||||||
|
snprintf((char *)key, 16, "%lld key of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_add(ht, key, 16, (void *) i);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
unsigned char key[16];
|
||||||
|
void *f = NULL;
|
||||||
|
snprintf((char *)key, 16, "%lld key of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_find(ht, key, 16, &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE_EQ(i, (isc_int64_t) f);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
unsigned char key[16];
|
||||||
|
snprintf((char *)key, 16, "%lld key of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_add(ht, key, 16, (void *) i);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
char key[64];
|
||||||
|
snprintf((char *)key, 64, "%lld key of a str hashtable!!", i);
|
||||||
|
result = isc_ht_add(ht, (const unsigned char *) key,
|
||||||
|
strlen(key), (void *) i);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
unsigned char key[16];
|
||||||
|
void *f = NULL;
|
||||||
|
snprintf((char *)key, 16, "%lld KEY of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_find(ht, key, 16, &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
|
||||||
|
ATF_REQUIRE_EQ(f, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
char key[64];
|
||||||
|
void *f = NULL;
|
||||||
|
snprintf((char *)key, 64, "%lld key of a str hashtable!!", i);
|
||||||
|
result = isc_ht_find(ht, (const unsigned char *) key,
|
||||||
|
strlen(key), &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE_EQ(f, (void *) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
unsigned char key[16];
|
||||||
|
void *f = NULL;
|
||||||
|
snprintf((char *)key, 16, "%lld key of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_delete(ht, key, 16);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
result = isc_ht_find(ht, key, 16, &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
|
||||||
|
ATF_REQUIRE_EQ(f, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
unsigned char key[16];
|
||||||
|
snprintf((char *)key, 16, "%lld KEY of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_add(ht, key, 16, (void *) i);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
char key[64];
|
||||||
|
void *f = NULL;
|
||||||
|
snprintf((char *)key, 64, "%lld key of a str hashtable!!", i);
|
||||||
|
result = isc_ht_delete(ht, (const unsigned char *) key,
|
||||||
|
strlen(key));
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
result = isc_ht_find(ht, (const unsigned char *) key,
|
||||||
|
strlen(key), &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
|
||||||
|
ATF_REQUIRE_EQ(f, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
unsigned char key[16];
|
||||||
|
void *f = NULL;
|
||||||
|
snprintf((char *)key, 16, "%lld KEY of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_find(ht, key, 16, &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE_EQ(i, (isc_int64_t) f);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < count; i++) {
|
||||||
|
unsigned char key[16];
|
||||||
|
void *f = NULL;
|
||||||
|
snprintf((char *)key, 16, "%lld key of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_find(ht, key, 16, &f);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
|
||||||
|
ATF_REQUIRE_EQ(f, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_ht_destroy(&ht);
|
||||||
|
ATF_REQUIRE_EQ(ht, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_uint32_t walked = 0;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
REGULAR,
|
||||||
|
ERASEEVEN,
|
||||||
|
ERASEODD,
|
||||||
|
CRASH
|
||||||
|
} walkmode_t;
|
||||||
|
|
||||||
|
static isc_result_t walker(void *udata, const unsigned char *key,
|
||||||
|
isc_uint32_t keysize, void *data)
|
||||||
|
{
|
||||||
|
char mykey[16];
|
||||||
|
isc_uint64_t ii = (isc_uint64_t) data;
|
||||||
|
walkmode_t mode = (isc_uint64_t) udata;
|
||||||
|
ATF_REQUIRE_EQ(keysize, 16);
|
||||||
|
|
||||||
|
snprintf(mykey, 16, "%lld key of a raw hashtable!!", ii);
|
||||||
|
ATF_REQUIRE_EQ(memcmp(mykey, key, 16), 0);
|
||||||
|
|
||||||
|
walked++;
|
||||||
|
switch (mode) {
|
||||||
|
case REGULAR:
|
||||||
|
break;
|
||||||
|
case ERASEEVEN:
|
||||||
|
if (ii % 2 == 0) {
|
||||||
|
return (ISC_R_EXISTS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ERASEODD:
|
||||||
|
if (ii % 2 != 0) {
|
||||||
|
return (ISC_R_EXISTS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CRASH:
|
||||||
|
if (walked == 100) {
|
||||||
|
/* something as odd as possible */
|
||||||
|
return (ISC_R_HOSTUNREACH);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ht_walk() {
|
||||||
|
isc_ht_t *ht = NULL;
|
||||||
|
isc_result_t result;
|
||||||
|
isc_mem_t *mctx = NULL;
|
||||||
|
isc_int64_t i;
|
||||||
|
isc_uint32_t count = 10000;
|
||||||
|
|
||||||
|
result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
|
||||||
|
NULL, &mctx, 0);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
result = isc_ht_init(&ht, mctx, 16);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE(ht != NULL);
|
||||||
|
for (i = 1; i <= count; i++) {
|
||||||
|
/*
|
||||||
|
* Note that the string we're snprintfing is always > 16 bytes
|
||||||
|
* so we are always filling the key.
|
||||||
|
*/
|
||||||
|
unsigned char key[16];
|
||||||
|
snprintf((char *)key, 16, "%lld key of a raw hashtable!!", i);
|
||||||
|
result = isc_ht_add(ht, key, 16, (void *) i);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
walked = 0;
|
||||||
|
result = isc_ht_walk(ht, walker, (void *) REGULAR);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE_EQ(walked, count);
|
||||||
|
|
||||||
|
walked = 0;
|
||||||
|
result = isc_ht_walk(ht, walker, (void *) CRASH);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_HOSTUNREACH);
|
||||||
|
ATF_REQUIRE_EQ(walked, 100);
|
||||||
|
|
||||||
|
walked = 0;
|
||||||
|
result = isc_ht_walk(ht, walker, (void *) ERASEODD);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE_EQ(walked, count);
|
||||||
|
|
||||||
|
walked = 0;
|
||||||
|
result = isc_ht_walk(ht, walker, (void *) ERASEEVEN);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE_EQ(walked, count/2);
|
||||||
|
|
||||||
|
walked = 0;
|
||||||
|
result = isc_ht_walk(ht, walker, (void *) REGULAR);
|
||||||
|
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
|
||||||
|
ATF_REQUIRE_EQ(walked, 0);
|
||||||
|
|
||||||
|
isc_ht_destroy(&ht);
|
||||||
|
ATF_REQUIRE_EQ(ht, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(isc_ht_20);
|
||||||
|
ATF_TC_HEAD(isc_ht_20, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "20 bit, 2M elements test");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_ht_20, tc) {
|
||||||
|
UNUSED(tc);
|
||||||
|
test_ht_full(20, 2000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ATF_TC(isc_ht_8);
|
||||||
|
ATF_TC_HEAD(isc_ht_8, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "8 bit, 20000 elements crowded test");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_ht_8, tc) {
|
||||||
|
UNUSED(tc);
|
||||||
|
test_ht_full(8, 20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(isc_ht_1);
|
||||||
|
ATF_TC_HEAD(isc_ht_1, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "1 bit, 100 elements corner case test");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_ht_1, tc) {
|
||||||
|
UNUSED(tc);
|
||||||
|
test_ht_full(1, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(isc_ht_32);
|
||||||
|
ATF_TC_HEAD(isc_ht_32, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "32 bit, 10000 elements corner case test");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_ht_32, tc) {
|
||||||
|
UNUSED(tc);
|
||||||
|
test_ht_full(32, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC(isc_ht_walk);
|
||||||
|
ATF_TC_HEAD(isc_ht_walk, tc) {
|
||||||
|
atf_tc_set_md_var(tc, "descr", "hashtable walking");
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_BODY(isc_ht_walk, tc) {
|
||||||
|
UNUSED(tc);
|
||||||
|
test_ht_walk();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main
|
||||||
|
*/
|
||||||
|
ATF_TP_ADD_TCS(tp) {
|
||||||
|
ATF_TP_ADD_TC(tp, isc_ht_20);
|
||||||
|
ATF_TP_ADD_TC(tp, isc_ht_8);
|
||||||
|
ATF_TP_ADD_TC(tp, isc_ht_1);
|
||||||
|
ATF_TP_ADD_TC(tp, isc_ht_32);
|
||||||
|
ATF_TP_ADD_TC(tp, isc_ht_walk);
|
||||||
|
return (atf_no_error());
|
||||||
|
}
|
||||||
|
|
@ -308,6 +308,13 @@ isc_hmacsha512_invalidate
|
|||||||
isc_hmacsha512_sign
|
isc_hmacsha512_sign
|
||||||
isc_hmacsha512_update
|
isc_hmacsha512_update
|
||||||
isc_hmacsha512_verify
|
isc_hmacsha512_verify
|
||||||
|
isc_ht_init
|
||||||
|
isc_ht_destroy
|
||||||
|
isc_ht_find
|
||||||
|
isc_ht_delete
|
||||||
|
isc_ht_iter_get
|
||||||
|
isc_ht_iter_inc
|
||||||
|
isc_ht_iter_value
|
||||||
isc_httpd_addheader
|
isc_httpd_addheader
|
||||||
isc_httpd_addheaderuint
|
isc_httpd_addheaderuint
|
||||||
isc_httpd_response
|
isc_httpd_response
|
||||||
|
@ -1472,6 +1472,42 @@ static cfg_type_t cfg_type_rpz = {
|
|||||||
rpz_fields
|
rpz_fields
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Catalog zones
|
||||||
|
*/
|
||||||
|
static cfg_type_t cfg_type_catz_zone = {
|
||||||
|
"zone", parse_keyvalue, print_keyvalue,
|
||||||
|
doc_keyvalue, &cfg_rep_string,
|
||||||
|
&zone_kw
|
||||||
|
};
|
||||||
|
|
||||||
|
static cfg_tuplefielddef_t catz_zone_fields[] = {
|
||||||
|
{ "zone name", &cfg_type_catz_zone, 0 },
|
||||||
|
{ "default-masters", &cfg_type_namesockaddrkeylist, 0 },
|
||||||
|
{ "in-memory", &cfg_type_boolean, 0 },
|
||||||
|
{ "min-update-interval", &cfg_type_uint32, 0 },
|
||||||
|
{ NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
static cfg_type_t cfg_type_catz_tuple = {
|
||||||
|
"catz tuple", cfg_parse_kv_tuple,
|
||||||
|
cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
|
||||||
|
catz_zone_fields
|
||||||
|
};
|
||||||
|
static cfg_type_t cfg_type_catz_list = {
|
||||||
|
"zone list", cfg_parse_bracketed_list, cfg_print_bracketed_list,
|
||||||
|
cfg_doc_bracketed_list, &cfg_rep_list,
|
||||||
|
&cfg_type_catz_tuple
|
||||||
|
};
|
||||||
|
static cfg_tuplefielddef_t catz_fields[] = {
|
||||||
|
{ "zone list", &cfg_type_catz_list, 0 },
|
||||||
|
{ NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
static cfg_type_t cfg_type_catz = {
|
||||||
|
"catz", cfg_parse_kv_tuple, cfg_print_kv_tuple,
|
||||||
|
cfg_doc_kv_tuple, &cfg_rep_tuple, catz_fields
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rate-limit
|
* rate-limit
|
||||||
@ -1627,6 +1663,7 @@ view_clauses[] = {
|
|||||||
{ "attach-cache", &cfg_type_astring, 0 },
|
{ "attach-cache", &cfg_type_astring, 0 },
|
||||||
{ "auth-nxdomain", &cfg_type_boolean, CFG_CLAUSEFLAG_NEWDEFAULT },
|
{ "auth-nxdomain", &cfg_type_boolean, CFG_CLAUSEFLAG_NEWDEFAULT },
|
||||||
{ "cache-file", &cfg_type_qstring, 0 },
|
{ "cache-file", &cfg_type_qstring, 0 },
|
||||||
|
{ "catalog-zones", &cfg_type_catz, 0 },
|
||||||
{ "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI },
|
{ "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI },
|
||||||
{ "cleaning-interval", &cfg_type_uint32, 0 },
|
{ "cleaning-interval", &cfg_type_uint32, 0 },
|
||||||
{ "clients-per-query", &cfg_type_uint32, 0 },
|
{ "clients-per-query", &cfg_type_uint32, 0 },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user