*/
static bool
filter_qctx_initialize(void *arg, void *cbdata, isc_result_t *resp);
-static ns_hook_t filter_init = {
+static const ns_hook_t filter_init = {
.action = filter_qctx_initialize,
.action_data = &client_ht,
};
static bool
filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp);
-static ns_hook_t filter_respbegin = {
+static const ns_hook_t filter_respbegin = {
.action = filter_respond_begin,
.action_data = &client_ht,
};
static bool
filter_respond_any_found(void *arg, void *cbdata, isc_result_t *resp);
-static ns_hook_t filter_respanyfound = {
+static const ns_hook_t filter_respanyfound = {
.action = filter_respond_any_found,
.action_data = &client_ht,
};
static bool
filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp);
-static ns_hook_t filter_prepresp = {
+static const ns_hook_t filter_prepresp = {
.action = filter_prep_response_begin,
.action_data = &client_ht,
};
static bool
filter_query_done_send(void *arg, void *cbdata, isc_result_t *resp);
-static ns_hook_t filter_donesend = {
+static const ns_hook_t filter_donesend = {
.action = filter_query_done_send,
.action_data = &client_ht,
};
static bool
filter_qctx_destroy(void *arg, void *cbdata, isc_result_t *resp);
-ns_hook_t filter_destroy = {
+static const ns_hook_t filter_destroy = {
.action = filter_qctx_destroy,
.action_data = &client_ht,
};
CHECK(parse_parameters(parameters, cfg, actx, hctx));
}
- ns_hook_add(hooktable, NS_QUERY_QCTX_INITIALIZED, &filter_init);
- ns_hook_add(hooktable, NS_QUERY_RESPOND_BEGIN, &filter_respbegin);
- ns_hook_add(hooktable, NS_QUERY_RESPOND_ANY_FOUND,
+ ns_hook_add(hooktable, hctx->mctx, NS_QUERY_QCTX_INITIALIZED,
+ &filter_init);
+ ns_hook_add(hooktable, hctx->mctx, NS_QUERY_RESPOND_BEGIN,
+ &filter_respbegin);
+ ns_hook_add(hooktable, hctx->mctx, NS_QUERY_RESPOND_ANY_FOUND,
&filter_respanyfound);
- ns_hook_add(hooktable, NS_QUERY_PREP_RESPONSE_BEGIN, &filter_prepresp);
- ns_hook_add(hooktable, NS_QUERY_DONE_SEND, &filter_donesend);
- ns_hook_add(hooktable, NS_QUERY_QCTX_DESTROYED, &filter_destroy);
+ ns_hook_add(hooktable, hctx->mctx, NS_QUERY_PREP_RESPONSE_BEGIN,
+ &filter_prepresp);
+ ns_hook_add(hooktable, hctx->mctx, NS_QUERY_DONE_SEND,
+ &filter_donesend);
+ ns_hook_add(hooktable, hctx->mctx, NS_QUERY_QCTX_DESTROYED,
+ &filter_destroy);
CHECK(isc_mempool_create(hctx->mctx, sizeof(filter_data_t),
&datapool));
load_symbol(void *handle, const char *modpath,
const char *symbol_name, void **symbolp)
{
- void *symbol;
+ void *symbol = NULL;
REQUIRE(handle != NULL);
REQUIRE(symbolp != NULL && *symbolp == NULL);
static void
unload_library(ns_hook_module_t **hmodp) {
- ns_hook_module_t *hmod;
+ ns_hook_module_t *hmod = NULL;
REQUIRE(hmodp != NULL && *hmodp != NULL);
load_symbol(HMODULE handle, const char *modpath,
const char *symbol_name, void **symbolp)
{
- void *symbol;
+ void *symbol = NULL;
REQUIRE(handle != NULL);
REQUIRE(symbolp != NULL && *symbolp == NULL);
static void
unload_library(ns_hook_module_t **hmodp) {
- ns_hook_module_t *hmod;
+ ns_hook_module_t *hmod = NULL;
REQUIRE(hmodp != NULL && *hmodp != NULL);
void
ns_hookmodule_unload_all(void) {
- ns_hook_module_t *hmod, *prev;
+ ns_hook_module_t *hmod = NULL, *prev = NULL;
if (!hook_modules_initialized) {
return;
isc_result_t
ns_hook_createctx(isc_mem_t *mctx, ns_hookctx_t **hctxp) {
- ns_hookctx_t *hctx;
+ ns_hookctx_t *hctx = NULL;
REQUIRE(hctxp != NULL && *hctxp == NULL);
void
ns_hook_destroyctx(ns_hookctx_t **hctxp) {
- ns_hookctx_t *hctx;
+ ns_hookctx_t *hctx = NULL;
REQUIRE(hctxp != NULL && NS_HOOKCTX_VALID(*hctxp));
isc_result_t
ns_hooktable_create(isc_mem_t *mctx, ns_hooktable_t **tablep) {
- ns_hooktable_t *hooktable;
+ ns_hooktable_t *hooktable = NULL;
REQUIRE(tablep != NULL && *tablep == NULL);
void
ns_hooktable_free(isc_mem_t *mctx, void **tablep) {
- ns_hooktable_t *table;
+ ns_hooktable_t *table = NULL;
+ ns_hook_t *hook = NULL, *next = NULL;
+ int i = 0;
REQUIRE(tablep != NULL && *tablep != NULL);
table = *tablep;
*tablep = NULL;
+
+ for (i = 0; i < NS_HOOKPOINTS_COUNT; i++) {
+ for (hook = ISC_LIST_HEAD((*table)[i]);
+ hook != NULL;
+ hook = next)
+ {
+ next = ISC_LIST_NEXT(hook, link);
+ ISC_LIST_UNLINK((*table)[i], hook, link);
+ if (hook->mctx != NULL) {
+ isc_mem_putanddetach(&hook->mctx,
+ hook, sizeof(*hook));
+ }
+ }
+ }
+
isc_mem_put(mctx, table, sizeof(*table));
}
void
-ns_hook_add(ns_hooktable_t *hooktable, ns_hookpoint_t hookpoint,
- ns_hook_t *hook)
+ns_hook_add(ns_hooktable_t *hooktable, isc_mem_t *mctx,
+ ns_hookpoint_t hookpoint, const ns_hook_t *hook)
{
+ ns_hook_t *copy = NULL;
+
+ REQUIRE(hooktable != NULL);
+ REQUIRE(mctx != NULL);
REQUIRE(hookpoint < NS_HOOKPOINTS_COUNT);
REQUIRE(hook != NULL);
- if (hooktable == NULL) {
- hooktable = ns__hook_table;
- }
+ copy = isc_mem_get(mctx, sizeof(*copy));
+ memset(copy, 0, sizeof(*copy));
+
+ copy->action = hook->action;
+ copy->action_data = hook->action_data;
+ isc_mem_attach(mctx, ©->mctx);
- ISC_LINK_INIT(hook, link);
- ISC_LIST_APPEND((*hooktable)[hookpoint], hook, link);
+ ISC_LINK_INIT(copy, link);
+ ISC_LIST_APPEND((*hooktable)[hookpoint], copy, link);
}
(*ns_hook_action_t)(void *arg, void *data, isc_result_t *resultp);
typedef struct ns_hook {
+ isc_mem_t *mctx;
ns_hook_action_t action;
void *action_data;
ISC_LINK(struct ns_hook) link;
*/
void
-ns_hook_add(ns_hooktable_t *hooktable, ns_hookpoint_t hookpoint,
- ns_hook_t *hook);
+ns_hook_add(ns_hooktable_t *hooktable, isc_mem_t *mctx,
+ ns_hookpoint_t hookpoint, const ns_hook_t *hook);
/*%<
- * Append hook function 'hook' to the list of hooks at 'hookpoint' in
- * 'hooktable'.
+ * Allocate (using memory context 'mctx') a copy of the 'hook' structure
+ * describing a hook callback and append it to the list of hooks at 'hookpoint'
+ * in 'hooktable'.
*
* Requires:
- *\li 'hook' is not NULL
+ *\li 'hooktable' is not NULL
+ *
+ *\li 'mctx' is not NULL
*
*\li 'hookpoint' is less than NS_QUERY_HOOKS_COUNT
*
+ *\li 'hook' is not NULL
*/
void
static void
query_addauth(query_ctx_t *qctx);
-/*%
+/*
* Increment query statistics counters.
*/
static inline void
*/
static isc_result_t
create_qctx_for_client(ns_client_t *client, query_ctx_t **qctxp) {
- ns_hooktable_t *saved_hook_table, query_hooks;
- ns_hook_t hook = {
+ ns_hooktable_t *saved_hook_table = NULL, *query_hooks = NULL;
+ const ns_hook_t hook = {
.action = extract_qctx,
.action_data = qctxp,
};
* set hooks.
*/
- ns_hooktable_init(&query_hooks);
- ns_hook_add(&query_hooks, NS_QUERY_SETUP, &hook);
+ ns_hooktable_create(mctx, &query_hooks);
+ ns_hook_add(query_hooks, mctx, NS_QUERY_SETUP, &hook);
saved_hook_table = ns__hook_table;
- ns__hook_table = &query_hooks;
+ ns__hook_table = query_hooks;
ns_query_start(client);
ns__hook_table = saved_hook_table;
+ ns_hooktable_free(mctx, (void **)&query_hooks);
if (*qctxp == NULL) {
return (ISC_R_NOMEMORY);
*/
static void
run_sfcache_test(const ns__query_sfcache_test_params_t *test) {
+ ns_hooktable_t *query_hooks = NULL;
query_ctx_t *qctx = NULL;
isc_result_t result;
- ns_hook_t hook = {
+ const ns_hook_t hook = {
.action = ns_test_hook_catch_call,
};
* Interrupt execution if ns_query_done() is called.
*/
- ns_hooktable_init(ns__hook_table);
- ns_hook_add(ns__hook_table, NS_QUERY_DONE_BEGIN, &hook);
+ ns_hooktable_create(mctx, &query_hooks);
+ ns_hook_add(query_hooks, mctx, NS_QUERY_DONE_BEGIN, &hook);
+ ns__hook_table = query_hooks;
/*
* Construct a query context for a ./NS query with given flags.
* Clean up.
*/
ns_test_qctx_destroy(&qctx);
+ ns_hooktable_free(mctx, (void **)&query_hooks);
}
/* test ns__query_sfcache() */
*/
static void
run_start_test(const ns__query_start_test_params_t *test) {
+ ns_hooktable_t *query_hooks = NULL;
query_ctx_t *qctx = NULL;
isc_result_t result;
- ns_hook_t hook = {
+ const ns_hook_t hook = {
.action = ns_test_hook_catch_call,
};
/*
* Interrupt execution if query_lookup() or ns_query_done() is called.
*/
-
- ns_hooktable_init(ns__hook_table);
- ns_hook_add(ns__hook_table, NS_QUERY_LOOKUP_BEGIN, &hook);
- ns_hook_add(ns__hook_table, NS_QUERY_DONE_BEGIN, &hook);
+ ns_hooktable_create(mctx, &query_hooks);
+ ns_hook_add(query_hooks, mctx, NS_QUERY_LOOKUP_BEGIN, &hook);
+ ns_hook_add(query_hooks, mctx, NS_QUERY_DONE_BEGIN, &hook);
+ ns__hook_table = query_hooks;
/*
* Construct a query context using the supplied parameters.
ns_test_cleanup_zone();
}
ns_test_qctx_destroy(&qctx);
+ ns_hooktable_free(mctx, (void **)&query_hooks);
}
/* test ns__query_start() */