]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
make hook actions return an enum instead of a bool
authorMichał Kępień <michal@isc.org>
Thu, 6 Dec 2018 10:36:30 +0000 (11:36 +0100)
committerEvan Hunt <each@isc.org>
Thu, 6 Dec 2018 18:36:50 +0000 (10:36 -0800)
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.

bin/plugins/filter-aaaa.c
lib/ns/include/ns/hooks.h
lib/ns/query.c
lib/ns/tests/nstest.c
lib/ns/tests/nstest.h

index 18c1b962b2f7823102b060b9b5c14d650dd1d355..131f412c23f669e73c2c2e1f70cf08c72441d1ce 100644 (file)
@@ -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);
 }
index 0570d225a6068c2fe05bbb16ccf1f7da0f3bc50b..0f6ff88c4c2fa5686f859962d71550216e4786d4 100644 (file)
  *
  * 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
  * 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);
  * }
  * ----------------------------------------------------------------------------
  *
  * 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;
  *
  *     fprintf(stream, "QTYPE=%u\n", qctx->qtype);
  *
- *     return (false);
+ *     return (NS_HOOK_CONTINUE);
  * }
  * ----------------------------------------------------------------------------
  *
  * 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 {
index 191e0dc35aa459a58b3add9f36ba0511b335f966..3608b7d40e3a438abff393d43ddbdbcb056645ee 100644 (file)
@@ -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)
index 9f24f6c4eb656727bb7741c8c25dd48579880c1c..b5e13c6ee12cc8310ab29f21008d371793cb7697 100644 (file)
@@ -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);
 }
 
 /*
index fc69befdc695f00180b9dd60f9926a4c787b3b42..6777149ab541d921707d072e198c0d91cf43d473 100644 (file)
@@ -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);