From: Colin Vidal Date: Tue, 19 Aug 2025 12:38:36 +0000 (+0200) Subject: add plugin_register param telling the source X-Git-Tag: v9.21.14~56^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=260bbc24c941e2585e196bb91f3e810c52280e21;p=thirdparty%2Fbind9.git add plugin_register param telling the source The plugin `plugin_register` API has a new parameter `source` indicating whether the plugin is loaded from a view or a zone. This extra parameter enables the plugin to fail early during initialization if a plugin written to be used in a zone exclusively is loaded at a view level, or vice versa. --- diff --git a/bin/named/server.c b/bin/named/server.c index e92ef449629..8448b3d7154 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -5417,7 +5417,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, } if (plugin_list != NULL) { - ns_hook_data_t hookdata = {}; + ns_hook_data_t hookdata = { .source = NS_HOOKSOURCE_VIEW }; INSIST(view->hooktable == NULL); ns_hooktable_create(view->mctx, &hookdata.hooktable); diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 729c3e8c59b..e4a4cf4b429 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -2125,7 +2125,7 @@ named_zone_loadplugins(dns_zone_t *zone, const cfg_obj_t *config, } if (tpluginlist != NULL || zpluginlist != NULL) { - ns_hook_data_t hookdata = {}; + ns_hook_data_t hookdata = { .source = NS_HOOKSOURCE_ZONE }; isc_mem_t *zmctx = dns_zone_getmctx(zone); ns_hooktable_create(zmctx, &hookdata.hooktable); diff --git a/bin/plugins/filter-a.c b/bin/plugins/filter-a.c index 2f684a2a45e..7ff8048cde6 100644 --- a/bin/plugins/filter-a.c +++ b/bin/plugins/filter-a.c @@ -326,10 +326,13 @@ cleanup: isc_result_t plugin_register(const char *parameters, const void *cfg, const char *cfg_file, unsigned long cfg_line, isc_mem_t *mctx, void *actx, - ns_hooktable_t *hooktable, void **instp) { + ns_hooktable_t *hooktable, ns_hooksource_t source, + void **instp) { filter_instance_t *inst = NULL; isc_result_t result = ISC_R_SUCCESS; + UNUSED(source); + isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_INFO, "registering 'filter-a' " "module from %s:%lu, %s parameters", diff --git a/bin/plugins/filter-aaaa.c b/bin/plugins/filter-aaaa.c index d24a6ca80bc..b5d58a56409 100644 --- a/bin/plugins/filter-aaaa.c +++ b/bin/plugins/filter-aaaa.c @@ -329,10 +329,13 @@ cleanup: isc_result_t plugin_register(const char *parameters, const void *cfg, const char *cfg_file, unsigned long cfg_line, isc_mem_t *mctx, void *actx, - ns_hooktable_t *hooktable, void **instp) { + ns_hooktable_t *hooktable, ns_hooksource_t source, + void **instp) { filter_instance_t *inst = NULL; isc_result_t result = ISC_R_SUCCESS; + UNUSED(source); + isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_INFO, "registering 'filter-aaaa' " "module from %s:%lu, %s parameters", diff --git a/lib/ns/hooks.c b/lib/ns/hooks.c index 9c7957e8189..7e6b307cfa9 100644 --- a/lib/ns/hooks.c +++ b/lib/ns/hooks.c @@ -239,8 +239,10 @@ ns_plugin_register(const char *modpath, const char *parameters, const void *cfg, isc_log_write(NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_INFO, "registering plugin '%s'", modpath); + INSIST(hookdata->source != NS_HOOKSOURCE_UNDEFINED); CHECK(plugin->register_func(parameters, cfg, cfg_file, cfg_line, mctx, - actx, hookdata->hooktable, &plugin->inst)); + actx, hookdata->hooktable, hookdata->source, + &plugin->inst)); ISC_LIST_APPEND(*hookdata->plugins, plugin, link); diff --git a/lib/ns/include/ns/hooks.h b/lib/ns/include/ns/hooks.h index 98508938567..363e1ac3a52 100644 --- a/lib/ns/include/ns/hooks.h +++ b/lib/ns/include/ns/hooks.h @@ -59,10 +59,11 @@ * contains a function pointer to a hook action and a pointer to data which is * to be passed to the action function when it is called. * - * Each view has its own separate hook table, populated by loading plugin - * modules specified in the "plugin" statements in named.conf. There is also a - * special, global hook table (ns__hook_table) that is only used by libns unit - * tests and whose existence can be safely ignored by plugin modules. + * Each view and zone has its own separate hook table, populated by loading + * plugin modules specified in the "plugin" statements in named.conf. (See + * `ZONE-SPECIFIC PLUGINS` section below.) There is also a special, global + * hook table (ns__hook_table) that is only used by libns unit tests and + * whose existence can be safely ignored by plugin modules. * * Hook actions are functions which: * @@ -366,6 +367,14 @@ * looked up. `NS_QUERY_DONE_BEGIN` could be called if an * authoritative zone has been used, but in some flows (for * instance, bad cookie handling), it would be skipped. + * + * The `plugin_register` function (defined by each plugin and called + * when the plugin is loaded) has a `ns_hooksource_t source` parameter. + * It indicates whether the plugin has been loaded at the zone level + * (`NS_HOOKSOURCE_ZONE`) or at the view level (`NS_HOOKSOURCE_VIEW`). + * While this can be ignored if it doesn't matter where the plugin is + * loaded, it can also be checked to enforce that the plugin is loaded + * only at the zone or view level. */ /*! @@ -476,9 +485,16 @@ typedef struct ns_hook_resume { * Wrapper struct holding hook/plugins owning data structures used and owned by * zones and views having registered plugins. */ +typedef enum { + NS_HOOKSOURCE_UNDEFINED, + NS_HOOKSOURCE_VIEW, + NS_HOOKSOURCE_ZONE +} ns_hooksource_t; + typedef struct ns_hook_data { ns_hooktable_t *hooktable; ns_plugins_t *plugins; + ns_hooksource_t source; } ns_hook_data_t; /* @@ -497,7 +513,8 @@ typedef struct ns_hook_data { typedef isc_result_t ns_plugin_register_t(const char *parameters, const void *cfg, const char *file, unsigned long line, isc_mem_t *mctx, void *actx, - ns_hooktable_t *hooktable, void **instp); + ns_hooktable_t *hooktable, ns_hooksource_t source, + void **instp); /*%< * Called when registering a new plugin. *