Commit 0e12988d authored by Michał Kępień's avatar Michał Kępień Committed by Evan Hunt
Browse files

make hook actions return an enum instead of a bool

Use an enum instead of a bool for the return type of hook actions in
order to facilitate adding further hook processing models in the future.
parent f70a8453
......@@ -115,17 +115,17 @@ typedef struct filter_instance {
/*
* Forward declarations of functions referenced in install_hooks().
*/
static bool
static ns_hookresult_t
filter_qctx_initialize(void *arg, void *cbdata, isc_result_t *resp);
static bool
static ns_hookresult_t
filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp);
static bool
static ns_hookresult_t
filter_respond_any_found(void *arg, void *cbdata, isc_result_t *resp);
static bool
static ns_hookresult_t
filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp);
static bool
static ns_hookresult_t
filter_query_done_send(void *arg, void *cbdata, isc_result_t *resp);
static bool
static ns_hookresult_t
filter_qctx_destroy(void *arg, void *cbdata, isc_result_t *resp);
/*%
......@@ -673,7 +673,7 @@ process_section(const section_filter_t *filter) {
* retrieve persistent data related to a client query for as long as the
* object persists.
*/
static bool
static ns_hookresult_t
filter_qctx_initialize(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata;
......@@ -686,7 +686,7 @@ filter_qctx_initialize(void *arg, void *cbdata, isc_result_t *resp) {
client_state_create(qctx, inst);
}
return (false);
return (NS_HOOK_CONTINUE);
}
/*
......@@ -694,7 +694,7 @@ filter_qctx_initialize(void *arg, void *cbdata, isc_result_t *resp) {
* the client address family and the settings of filter-aaaa-on-v4 and
* filter-aaaa-on-v6.
*/
static bool
static ns_hookresult_t
filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata;
......@@ -704,7 +704,7 @@ filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp) {
*resp = ISC_R_UNSET;
if (client_state == NULL) {
return (false);
return (NS_HOOK_CONTINUE);
}
if (inst->v4_aaaa != NONE || inst->v6_aaaa != NONE) {
......@@ -723,7 +723,7 @@ filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp) {
}
}
return (false);
return (NS_HOOK_CONTINUE);
}
/*
......@@ -733,7 +733,7 @@ filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp) {
* (This version is for processing answers to explicit AAAA queries; ANY
* queries are handled in filter_respond_any_found().)
*/
static bool
static ns_hookresult_t
filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata;
......@@ -743,7 +743,7 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
*resp = ISC_R_UNSET;
if (client_state == NULL) {
return (false);
return (NS_HOOK_CONTINUE);
}
if (client_state->mode != BREAK_DNSSEC &&
......@@ -751,7 +751,7 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
(WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
dns_rdataset_isassociated(qctx->sigrdataset))))
{
return (false);
return (NS_HOOK_CONTINUE);
}
if (qctx->qtype == dns_rdatatype_aaaa) {
......@@ -827,17 +827,17 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
*resp = result;
return (true);
return (NS_HOOK_RETURN);
}
*resp = result;
return (false);
return (NS_HOOK_CONTINUE);
}
/*
* When answering an ANY query, remove AAAA if A is present.
*/
static bool
static ns_hookresult_t
filter_respond_any_found(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata;
......@@ -864,7 +864,7 @@ filter_respond_any_found(void *arg, void *cbdata, isc_result_t *resp) {
process_section(&filter_answer);
}
return (false);
return (NS_HOOK_CONTINUE);
}
/*
......@@ -872,7 +872,7 @@ filter_respond_any_found(void *arg, void *cbdata, isc_result_t *resp) {
* hide NS in the authority section if AAAA was filtered in the answer
* section.
*/
static bool
static ns_hookresult_t
filter_query_done_send(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata;
......@@ -901,14 +901,14 @@ filter_query_done_send(void *arg, void *cbdata, isc_result_t *resp) {
}
}
return (false);
return (NS_HOOK_CONTINUE);
}
/*
* If the client is being detached, then we can delete our persistent data
* from hash table and return it to the memory pool.
*/
static bool
static ns_hookresult_t
filter_qctx_destroy(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata;
......@@ -916,10 +916,10 @@ filter_qctx_destroy(void *arg, void *cbdata, isc_result_t *resp) {
*resp = ISC_R_UNSET;
if (!qctx->detach_client) {
return (false);
return (NS_HOOK_CONTINUE);
}
client_state_destroy(qctx, inst);
return (false);
return (NS_HOOK_CONTINUE);
}
......@@ -64,19 +64,23 @@
*
* Hook actions are functions which:
*
* - return a boolean value: if true is returned by the hook action, the
* function into which the hook is inserted will return and no further hook
* actions at the same hook point will be invoked; if false is returned by
* the hook action and there are further hook actions set up at the same
* hook point, they will be processed; if false is returned and there are
* no further hook actions set up at the same hook point, execution of the
* function into which the hook has been inserted will be resumed,
* - return an ns_hookresult_t value:
* - if NS_HOOK_RETURN is returned by the hook action, the function
* into which the hook is inserted will return and no further hook
* actions at the same hook point will be invoked,
* - if NS_HOOK_CONTINUE is returned by the hook action and there are
* further hook actions set up at the same hook point, they will be
* processed; if NS_HOOK_CONTINUE is returned and there are no
* further hook actions set up at the same hook point, execution of
* the function into which the hook has been inserted will be
* resumed.
*
* - accept three pointers as arguments:
* - a pointer specified by the special call at the hook insertion point,
* - a pointer specified upon inserting the action into the hook table,
* - a pointer to an isc_result_t value which will be returned by the
* function into which the hook is inserted if the action returns true.
* function into which the hook is inserted if the action returns
* NS_HOOK_RETURN.
*
* In order for a hook action to be called for a given hook, a pointer to that
* action function (along with an optional pointer to action-specific data) has
......@@ -106,14 +110,14 @@
* and the following hook action:
*
* ----------------------------------------------------------------------------
* static bool
* static ns_hookresult_t
* cause_failure(void *hook_data, void *action_data, isc_result_t *resultp) {
* UNUSED(hook_data);
* UNUSED(action_data);
*
* *resultp = ISC_R_FAILURE;
*
* return (true);
* return (NS_HOOK_RETURN);
* }
* ----------------------------------------------------------------------------
*
......@@ -127,15 +131,15 @@
* ns_hook_add(..., NS_QUERY_FOO_BEGIN, &foo_fail);
* ----------------------------------------------------------------------------
*
* then query_foo() would return ISC_R_FAILURE every time it is called due to
* the cause_failure() hook action returning true and setting '*resultp' to
* ISC_R_FAILURE. query_foo() would also never log the "Lorem ipsum dolor sit
* amet..." message.
* then query_foo() would return ISC_R_FAILURE every time it is called due
* to the cause_failure() hook action returning NS_HOOK_RETURN and setting
* '*resultp' to ISC_R_FAILURE. query_foo() would also never log the
* "Lorem ipsum dolor sit amet..." message.
*
* Consider a different hook action:
*
* ----------------------------------------------------------------------------
* static bool
* static ns_hookresult_t
* log_qtype(void *hook_data, void *action_data, isc_result_t *resultp) {
* query_ctx_t *qctx = (query_ctx_t *)hook_data;
* FILE *stream = (FILE *)action_data;
......@@ -144,7 +148,7 @@
*
* fprintf(stream, "QTYPE=%u\n", qctx->qtype);
*
* return (false);
* return (NS_HOOK_CONTINUE);
* }
* ----------------------------------------------------------------------------
*
......@@ -165,9 +169,9 @@
* the hook action in 'hook_data' since it is specified in the CALL_HOOK() call
* inside query_foo() while stderr would be passed to the hook action in
* 'action_data' since it is specified in the ns_hook_t structure passed to
* ns_hook_add(). As the hook action returns false, query_foo() would also be
* logging the "Lorem ipsum dolor sit amet..." message before returning
* ISC_R_COMPLETE.
* ns_hook_add(). As the hook action returns NS_HOOK_CONTINUE,
* query_foo() would also be logging the "Lorem ipsum dolor sit amet..."
* message before returning ISC_R_COMPLETE.
*/
/*!
......@@ -211,7 +215,16 @@ typedef enum {
NS_HOOKPOINTS_COUNT /* MUST BE LAST */
} ns_hookpoint_t;
typedef bool
/*
* Returned by a hook action to indicate how to proceed after it has
* been called: continue processing, or return immediately.
*/
typedef enum {
NS_HOOK_CONTINUE,
NS_HOOK_RETURN,
} ns_hookresult_t;
typedef ns_hookresult_t
(*ns_hook_action_t)(void *arg, void *data, isc_result_t *resultp);
typedef struct ns_hook {
......
......@@ -255,16 +255,16 @@ get_hooktab(query_ctx_t *qctx) {
}
/*
* Call the specified hook function in every configured module that
* implements that function. If any hook function returns 'true', we set
* 'result' and terminate processing by jumping to the 'cleanup' tag.
* Call the specified hook function in every configured module that implements
* that function. If any hook function returns NS_HOOK_RETURN, we
* set 'result' and terminate processing by jumping to the 'cleanup' tag.
*
* (Note that a hook function may set the 'result' to ISC_R_SUCCESS but
* still terminate processing within the calling function. That's why this
* is a macro instead of an inline function; it needs to be able to use
* 'goto cleanup' regardless of the return value.)
*/
#define CALL_HOOK(_id, _qctx) \
#define CALL_HOOK(_id, _qctx) \
do { \
isc_result_t _res; \
ns_hooktable_t *_tab = get_hooktab(_qctx); \
......@@ -274,11 +274,15 @@ get_hooktab(query_ctx_t *qctx) {
ns_hook_action_t _func = _hook->action; \
void *_data = _hook->action_data; \
INSIST(_func != NULL); \
if (_func(_qctx, _data, &_res)) { \
switch (_func(_qctx, _data, &_res)) { \
case NS_HOOK_CONTINUE: \
_hook = ISC_LIST_NEXT(_hook, link); \
break; \
case NS_HOOK_RETURN: \
result = _res; \
goto cleanup; \
} else { \
_hook = ISC_LIST_NEXT(_hook, link); \
default: \
INSIST(0); \
} \
} \
} while (false)
......
......@@ -633,7 +633,7 @@ destroy_message:
* "data". Causes execution to be interrupted at hook insertion
* point.
*/
static bool
static ns_hookresult_t
extract_qctx(void *arg, void *data, isc_result_t *resultp) {
query_ctx_t **qctxp;
query_ctx_t *qctx;
......@@ -660,7 +660,7 @@ extract_qctx(void *arg, void *data, isc_result_t *resultp) {
*qctxp = qctx;
*resultp = ISC_R_UNSET;
return (true);
return (NS_HOOK_RETURN);
}
/*%
......@@ -801,7 +801,7 @@ ns_test_qctx_destroy(query_ctx_t **qctxp) {
*qctxp = NULL;
}
bool
ns_hookresult_t
ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp)
{
UNUSED(arg);
......@@ -809,7 +809,7 @@ ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp)
*resultp = ISC_R_UNSET;
return (true);
return (NS_HOOK_RETURN);
}
/*
......
......@@ -30,6 +30,7 @@
#include <ns/interfacemgr.h>
#include <ns/client.h>
#include <ns/hooks.h>
typedef struct ns_test_id {
const char *description;
......@@ -150,5 +151,5 @@ ns_test_qctx_destroy(query_ctx_t **qctxp);
/*%
* A hook callback interrupting execution at given hook's insertion point.
*/
bool
ns_hookresult_t
ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment