2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 08:05:21 +00:00

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.
This commit is contained in:
Michał Kępień
2018-12-06 11:36:30 +01:00
committed by Evan Hunt
parent f70a84537d
commit 0e12988dd6
5 changed files with 73 additions and 55 deletions

View File

@@ -115,17 +115,17 @@ typedef struct filter_instance {
/* /*
* Forward declarations of functions referenced in install_hooks(). * 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); 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); 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); 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); 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); 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); 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 * retrieve persistent data related to a client query for as long as the
* object persists. * object persists.
*/ */
static bool static ns_hookresult_t
filter_qctx_initialize(void *arg, void *cbdata, isc_result_t *resp) { filter_qctx_initialize(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg; query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata; 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); 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 * the client address family and the settings of filter-aaaa-on-v4 and
* filter-aaaa-on-v6. * filter-aaaa-on-v6.
*/ */
static bool static ns_hookresult_t
filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp) { filter_prep_response_begin(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg; query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata; 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; *resp = ISC_R_UNSET;
if (client_state == NULL) { if (client_state == NULL) {
return (false); return (NS_HOOK_CONTINUE);
} }
if (inst->v4_aaaa != NONE || inst->v6_aaaa != NONE) { 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 * (This version is for processing answers to explicit AAAA queries; ANY
* queries are handled in filter_respond_any_found().) * 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) { filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg; query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata; 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; *resp = ISC_R_UNSET;
if (client_state == NULL) { if (client_state == NULL) {
return (false); return (NS_HOOK_CONTINUE);
} }
if (client_state->mode != BREAK_DNSSEC && 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 && (WANTDNSSEC(qctx->client) && qctx->sigrdataset != NULL &&
dns_rdataset_isassociated(qctx->sigrdataset)))) dns_rdataset_isassociated(qctx->sigrdataset))))
{ {
return (false); return (NS_HOOK_CONTINUE);
} }
if (qctx->qtype == dns_rdatatype_aaaa) { if (qctx->qtype == dns_rdatatype_aaaa) {
@@ -827,17 +827,17 @@ filter_respond_begin(void *arg, void *cbdata, isc_result_t *resp) {
*resp = result; *resp = result;
return (true); return (NS_HOOK_RETURN);
} }
*resp = result; *resp = result;
return (false); return (NS_HOOK_CONTINUE);
} }
/* /*
* When answering an ANY query, remove AAAA if A is present. * 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) { filter_respond_any_found(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg; query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata; 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); 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 * hide NS in the authority section if AAAA was filtered in the answer
* section. * section.
*/ */
static bool static ns_hookresult_t
filter_query_done_send(void *arg, void *cbdata, isc_result_t *resp) { filter_query_done_send(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg; query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata; 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 * If the client is being detached, then we can delete our persistent data
* from hash table and return it to the memory pool. * 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) { filter_qctx_destroy(void *arg, void *cbdata, isc_result_t *resp) {
query_ctx_t *qctx = (query_ctx_t *) arg; query_ctx_t *qctx = (query_ctx_t *) arg;
filter_instance_t *inst = (filter_instance_t *) cbdata; 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; *resp = ISC_R_UNSET;
if (!qctx->detach_client) { if (!qctx->detach_client) {
return (false); return (NS_HOOK_CONTINUE);
} }
client_state_destroy(qctx, inst); client_state_destroy(qctx, inst);
return (false); return (NS_HOOK_CONTINUE);
} }

View File

@@ -64,19 +64,23 @@
* *
* Hook actions are functions which: * Hook actions are functions which:
* *
* - return a boolean value: if true is returned by the hook action, the * - return an ns_hookresult_t value:
* function into which the hook is inserted will return and no further hook * - if NS_HOOK_RETURN is returned by the hook action, the function
* actions at the same hook point will be invoked; if false is returned by * into which the hook is inserted will return and no further hook
* the hook action and there are further hook actions set up at the same * actions at the same hook point will be invoked,
* hook point, they will be processed; if false is returned and there are * - if NS_HOOK_CONTINUE is returned by the hook action and there are
* no further hook actions set up at the same hook point, execution of the * further hook actions set up at the same hook point, they will be
* function into which the hook has been inserted will be resumed, * 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: * - accept three pointers as arguments:
* - a pointer specified by the special call at the hook insertion point, * - 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 specified upon inserting the action into the hook table,
* - a pointer to an isc_result_t value which will be returned by the * - 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 * 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 * action function (along with an optional pointer to action-specific data) has
@@ -106,14 +110,14 @@
* and the following hook action: * and the following hook action:
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* static bool * static ns_hookresult_t
* cause_failure(void *hook_data, void *action_data, isc_result_t *resultp) { * cause_failure(void *hook_data, void *action_data, isc_result_t *resultp) {
* UNUSED(hook_data); * UNUSED(hook_data);
* UNUSED(action_data); * UNUSED(action_data);
* *
* *resultp = ISC_R_FAILURE; * *resultp = ISC_R_FAILURE;
* *
* return (true); * return (NS_HOOK_RETURN);
* } * }
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@@ -127,15 +131,15 @@
* ns_hook_add(..., NS_QUERY_FOO_BEGIN, &foo_fail); * ns_hook_add(..., NS_QUERY_FOO_BEGIN, &foo_fail);
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* then query_foo() would return ISC_R_FAILURE every time it is called due to * then query_foo() would return ISC_R_FAILURE every time it is called due
* the cause_failure() hook action returning true and setting '*resultp' to * to the cause_failure() hook action returning NS_HOOK_RETURN and setting
* ISC_R_FAILURE. query_foo() would also never log the "Lorem ipsum dolor sit * '*resultp' to ISC_R_FAILURE. query_foo() would also never log the
* amet..." message. * "Lorem ipsum dolor sit amet..." message.
* *
* Consider a different hook action: * Consider a different hook action:
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* static bool * static ns_hookresult_t
* log_qtype(void *hook_data, void *action_data, isc_result_t *resultp) { * log_qtype(void *hook_data, void *action_data, isc_result_t *resultp) {
* query_ctx_t *qctx = (query_ctx_t *)hook_data; * query_ctx_t *qctx = (query_ctx_t *)hook_data;
* FILE *stream = (FILE *)action_data; * FILE *stream = (FILE *)action_data;
@@ -144,7 +148,7 @@
* *
* fprintf(stream, "QTYPE=%u\n", qctx->qtype); * 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 * 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 * 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 * '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 * ns_hook_add(). As the hook action returns NS_HOOK_CONTINUE,
* logging the "Lorem ipsum dolor sit amet..." message before returning * query_foo() would also be logging the "Lorem ipsum dolor sit amet..."
* ISC_R_COMPLETE. * message before returning ISC_R_COMPLETE.
*/ */
/*! /*!
@@ -211,7 +215,16 @@ typedef enum {
NS_HOOKPOINTS_COUNT /* MUST BE LAST */ NS_HOOKPOINTS_COUNT /* MUST BE LAST */
} ns_hookpoint_t; } 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); (*ns_hook_action_t)(void *arg, void *data, isc_result_t *resultp);
typedef struct ns_hook { typedef struct ns_hook {

View File

@@ -255,16 +255,16 @@ get_hooktab(query_ctx_t *qctx) {
} }
/* /*
* Call the specified hook function in every configured module that * Call the specified hook function in every configured module that implements
* implements that function. If any hook function returns 'true', we set * that function. If any hook function returns NS_HOOK_RETURN, we
* 'result' and terminate processing by jumping to the 'cleanup' tag. * 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 * (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 * 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 * is a macro instead of an inline function; it needs to be able to use
* 'goto cleanup' regardless of the return value.) * 'goto cleanup' regardless of the return value.)
*/ */
#define CALL_HOOK(_id, _qctx) \ #define CALL_HOOK(_id, _qctx) \
do { \ do { \
isc_result_t _res; \ isc_result_t _res; \
ns_hooktable_t *_tab = get_hooktab(_qctx); \ ns_hooktable_t *_tab = get_hooktab(_qctx); \
@@ -274,11 +274,15 @@ get_hooktab(query_ctx_t *qctx) {
ns_hook_action_t _func = _hook->action; \ ns_hook_action_t _func = _hook->action; \
void *_data = _hook->action_data; \ void *_data = _hook->action_data; \
INSIST(_func != NULL); \ 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; \ result = _res; \
goto cleanup; \ goto cleanup; \
} else { \ default: \
_hook = ISC_LIST_NEXT(_hook, link); \ INSIST(0); \
} \ } \
} \ } \
} while (false) } while (false)

View File

@@ -633,7 +633,7 @@ destroy_message:
* "data". Causes execution to be interrupted at hook insertion * "data". Causes execution to be interrupted at hook insertion
* point. * point.
*/ */
static bool static ns_hookresult_t
extract_qctx(void *arg, void *data, isc_result_t *resultp) { extract_qctx(void *arg, void *data, isc_result_t *resultp) {
query_ctx_t **qctxp; query_ctx_t **qctxp;
query_ctx_t *qctx; query_ctx_t *qctx;
@@ -660,7 +660,7 @@ extract_qctx(void *arg, void *data, isc_result_t *resultp) {
*qctxp = qctx; *qctxp = qctx;
*resultp = ISC_R_UNSET; *resultp = ISC_R_UNSET;
return (true); return (NS_HOOK_RETURN);
} }
/*% /*%
@@ -801,7 +801,7 @@ ns_test_qctx_destroy(query_ctx_t **qctxp) {
*qctxp = NULL; *qctxp = NULL;
} }
bool ns_hookresult_t
ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp) ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp)
{ {
UNUSED(arg); UNUSED(arg);
@@ -809,7 +809,7 @@ ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp)
*resultp = ISC_R_UNSET; *resultp = ISC_R_UNSET;
return (true); return (NS_HOOK_RETURN);
} }
/* /*

View File

@@ -30,6 +30,7 @@
#include <ns/interfacemgr.h> #include <ns/interfacemgr.h>
#include <ns/client.h> #include <ns/client.h>
#include <ns/hooks.h>
typedef struct ns_test_id { typedef struct ns_test_id {
const char *description; 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. * 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); ns_test_hook_catch_call(void *arg, void *data, isc_result_t *resultp);