From a335e601e42ea90d0bb9a028734ab45d263efd45 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 3 Jul 2024 13:53:44 +0200 Subject: [PATCH] ipset-pf-support, move startup and destartup to the front of the module func block functions, modstack call deinit function names, and detect module change when no startup functions are needed. --- cachedb/cachedb.c | 2 +- daemon/daemon.c | 19 ++++++++++++------- daemon/daemon.h | 2 ++ dns64/dns64.c | 2 +- dynlibmod/dynlibmod.c | 2 +- edns-subnet/subnetmod.c | 2 +- ipsecmod/ipsecmod.c | 2 +- ipset/ipset.c | 2 +- iterator/iterator.c | 2 +- libunbound/context.c | 4 ++-- libunbound/libunbound.c | 15 +++++++++------ pythonmod/pythonmod.c | 2 +- respip/respip.c | 2 +- services/modstack.c | 42 +++++++++++++++++++++++++++++------------ services/modstack.h | 18 ++++++++++++------ testcode/unitzonemd.c | 9 +++++---- util/module.h | 36 +++++++++++++++++------------------ validator/validator.c | 2 +- 18 files changed, 100 insertions(+), 65 deletions(-) diff --git a/cachedb/cachedb.c b/cachedb/cachedb.c index aca68d7ed..7a07b9976 100644 --- a/cachedb/cachedb.c +++ b/cachedb/cachedb.c @@ -983,7 +983,7 @@ cachedb_get_mem(struct module_env* env, int id) */ static struct module_func_block cachedb_block = { "cachedb", - &cachedb_init, &cachedb_deinit, NULL, NULL, &cachedb_operate, + NULL, NULL, &cachedb_init, &cachedb_deinit, &cachedb_operate, &cachedb_inform_super, &cachedb_clear, &cachedb_get_mem }; diff --git a/daemon/daemon.c b/daemon/daemon.c index ab3d182c3..d81bec844 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -450,7 +450,7 @@ daemon_privileged(struct daemon* daemon) daemon->env->cfg = daemon->cfg; daemon->env->alloc = &daemon->superalloc; daemon->env->worker = NULL; - if(!modstack_startup(&daemon->mods, daemon->cfg->module_conf, + if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf, daemon->env)) { fatal_exit("failed to startup modules"); } @@ -466,11 +466,15 @@ static void daemon_setup_modules(struct daemon* daemon) daemon->env->cfg = daemon->cfg; daemon->env->alloc = &daemon->superalloc; daemon->env->worker = NULL; - daemon->env->need_to_validate = 0; /* set by module init below */ - if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf, - daemon->env)) { - fatal_exit("failed to setup modules"); + if(daemon->mods_inited) { + modstack_call_deinit(&daemon->mods, daemon->env); } + daemon->env->need_to_validate = 0; /* set by module init below */ + if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf, + daemon->env)) { + fatal_exit("failed to init modules"); + } + daemon->mods_inited = 1; log_edns_known_options(VERB_ALGO, daemon->env); } @@ -904,8 +908,9 @@ daemon_delete(struct daemon* daemon) size_t i; if(!daemon) return; - modstack_desetup(&daemon->mods, daemon->env); - modstack_destartup(&daemon->mods, daemon->env); + modstack_call_deinit(&daemon->mods, daemon->env); + modstack_call_destartup(&daemon->mods, daemon->env); + modstack_free(&daemon->mods); daemon_remote_delete(daemon->rc); for(i = 0; i < daemon->num_ports; i++) listening_ports_free(daemon->ports[i]); diff --git a/daemon/daemon.h b/daemon/daemon.h index 200149745..a6b6391cc 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -115,6 +115,8 @@ struct daemon { struct module_env* env; /** stack of module callbacks */ struct module_stack mods; + /** The module stack has been inited */ + int mods_inited; /** access control, which client IPs are allowed to connect */ struct acl_list* acl; /** access control, which interfaces are allowed to connect */ diff --git a/dns64/dns64.c b/dns64/dns64.c index d34eafb9f..3a43698a8 100644 --- a/dns64/dns64.c +++ b/dns64/dns64.c @@ -1044,7 +1044,7 @@ dns64_get_mem(struct module_env* env, int id) */ static struct module_func_block dns64_block = { "dns64", - &dns64_init, &dns64_deinit, NULL, NULL, &dns64_operate, + NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super, &dns64_clear, &dns64_get_mem }; diff --git a/dynlibmod/dynlibmod.c b/dynlibmod/dynlibmod.c index 06c4f08c1..c94115492 100644 --- a/dynlibmod/dynlibmod.c +++ b/dynlibmod/dynlibmod.c @@ -297,7 +297,7 @@ inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type */ static struct module_func_block dynlibmod_block = { "dynlib", - &dynlibmod_init, &dynlibmod_deinit, NULL, NULL, &dynlibmod_operate, + NULL, NULL, &dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super, &dynlibmod_clear, &dynlibmod_get_mem }; diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c index 8e6db02e7..ead720f34 100644 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@ -996,7 +996,7 @@ subnetmod_get_mem(struct module_env *env, int id) */ static struct module_func_block subnetmod_block = { "subnetcache", - &subnetmod_init, &subnetmod_deinit, NULL, NULL, &subnetmod_operate, + NULL, NULL, &subnetmod_init, &subnetmod_deinit, &subnetmod_operate, &subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem }; diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c index 137e22c33..76f9b1965 100644 --- a/ipsecmod/ipsecmod.c +++ b/ipsecmod/ipsecmod.c @@ -615,7 +615,7 @@ ipsecmod_get_mem(struct module_env* env, int id) */ static struct module_func_block ipsecmod_block = { "ipsecmod", - &ipsecmod_init, &ipsecmod_deinit, NULL, NULL, &ipsecmod_operate, + NULL, NULL, &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate, &ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem }; diff --git a/ipset/ipset.c b/ipset/ipset.c index d416f34fd..1ad2c09f4 100644 --- a/ipset/ipset.c +++ b/ipset/ipset.c @@ -491,7 +491,7 @@ size_t ipset_get_mem(struct module_env *env, int id) { */ static struct module_func_block ipset_block = { "ipset", - &ipset_init, &ipset_deinit, &ipset_startup, &ipset_destartup, + &ipset_startup, &ipset_destartup, &ipset_init, &ipset_deinit, &ipset_operate, &ipset_inform_super, &ipset_clear, &ipset_get_mem }; diff --git a/iterator/iterator.c b/iterator/iterator.c index c99d9504a..cddb02717 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -4489,7 +4489,7 @@ iter_get_mem(struct module_env* env, int id) */ static struct module_func_block iter_block = { "iterator", - &iter_init, &iter_deinit, NULL, NULL, &iter_operate, + NULL, NULL, &iter_init, &iter_deinit, &iter_operate, &iter_inform_super, &iter_clear, &iter_get_mem }; diff --git a/libunbound/context.c b/libunbound/context.c index 5b2d36b2d..05f57987a 100644 --- a/libunbound/context.c +++ b/libunbound/context.c @@ -75,9 +75,9 @@ context_finalize(struct ub_ctx* ctx) ctx->pipe_pid = getpid(); cfg_apply_local_port_policy(cfg, 65536); config_apply(cfg); - if(!modstack_startup(&ctx->mods, cfg->module_conf, ctx->env)) + if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env)) return UB_INITFAIL; - if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env)) + if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env)) return UB_INITFAIL; listen_setup_locks(); log_edns_known_options(VERB_ALGO, ctx->env); diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index 561e41fba..9c6a3e309 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -188,8 +188,9 @@ ub_ctx_create(void) int e = errno; ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); - modstack_desetup(&ctx->mods, ctx->env); - modstack_destartup(&ctx->mods, ctx->env); + modstack_call_deinit(&ctx->mods, ctx->env); + modstack_call_destartup(&ctx->mods, ctx->env); + modstack_free(&ctx->mods); listen_desetup_locks(); edns_known_options_delete(ctx->env); edns_strings_delete(ctx->env->edns_strings); @@ -203,8 +204,9 @@ ub_ctx_create(void) tube_delete(ctx->qq_pipe); ub_randfree(ctx->seed_rnd); config_delete(ctx->env->cfg); - modstack_desetup(&ctx->mods, ctx->env); - modstack_destartup(&ctx->mods, ctx->env); + modstack_call_deinit(&ctx->mods, ctx->env); + modstack_call_destartup(&ctx->mods, ctx->env); + modstack_free(&ctx->mods); listen_desetup_locks(); edns_known_options_delete(ctx->env); edns_strings_delete(ctx->env->edns_strings); @@ -362,8 +364,9 @@ ub_ctx_delete(struct ub_ctx* ctx) } libworker_delete_event(ctx->event_worker); - modstack_desetup(&ctx->mods, ctx->env); - modstack_destartup(&ctx->mods, ctx->env); + modstack_call_deinit(&ctx->mods, ctx->env); + modstack_call_destartup(&ctx->mods, ctx->env); + modstack_free(&ctx->mods); a = ctx->alloc_list; while(a) { na = a->super; diff --git a/pythonmod/pythonmod.c b/pythonmod/pythonmod.c index f397012ac..e231ad079 100644 --- a/pythonmod/pythonmod.c +++ b/pythonmod/pythonmod.c @@ -777,7 +777,7 @@ size_t pythonmod_get_mem(struct module_env* env, int id) */ static struct module_func_block pythonmod_block = { "python", - &pythonmod_init, &pythonmod_deinit, NULL, NULL, &pythonmod_operate, + NULL, NULL, &pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super, &pythonmod_clear, &pythonmod_get_mem }; diff --git a/respip/respip.c b/respip/respip.c index cfc6a4908..db48f176e 100644 --- a/respip/respip.c +++ b/respip/respip.c @@ -1259,7 +1259,7 @@ respip_get_mem(struct module_env* env, int id) */ static struct module_func_block respip_block = { "respip", - &respip_init, &respip_deinit, NULL, NULL, &respip_operate, + NULL, NULL, &respip_init, &respip_deinit, &respip_operate, &respip_inform_super, &respip_clear, &respip_get_mem }; diff --git a/services/modstack.c b/services/modstack.c index f32f942c8..6c8af0505 100644 --- a/services/modstack.c +++ b/services/modstack.c @@ -95,6 +95,16 @@ modstack_init(struct module_stack* stack) stack->mod = NULL; } +void +modstack_free(struct module_stack* stack) +{ + if(!stack) + return; + stack->num = 0; + free(stack->mod); + stack->mod = NULL; +} + int modstack_config(struct module_stack* stack, const char* module_conf) { @@ -223,7 +233,7 @@ module_func_block* module_factory(const char** str) } int -modstack_startup(struct module_stack* stack, const char* module_conf, +modstack_call_startup(struct module_stack* stack, const char* module_conf, struct module_env* env) { int i; @@ -249,22 +259,33 @@ modstack_startup(struct module_stack* stack, const char* module_conf, } int -modstack_setup(struct module_stack* stack, const char* module_conf, +modstack_call_init(struct module_stack* stack, const char* module_conf, struct module_env* env) { - int i; - if(stack->num != 0) - modstack_desetup(stack, env); + int i, changed = 0; env->need_to_validate = 0; /* set by module init below */ for(i=0; inum; i++) { while(*module_conf && isspace(*module_conf)) module_conf++; if(strncmp(stack->mod[i]->name, module_conf, strlen(stack->mod[i]->name))) { - log_err("changed module ordering during reload not supported"); - return 0; + if(stack->mod[i]->startup || stack->mod[i]->destartup) { + log_err("changed module ordering during reload not supported, for module that needs startup"); + return 0; + } else { + changed = 1; + } } module_conf += strlen(stack->mod[i]->name); + } + if(changed) { + modstack_free(stack); + if(!modstack_config(stack, module_conf)) { + return 0; + } + } + + for(i=0; inum; i++) { verbose(VERB_OPS, "init module %d: %s", i, stack->mod[i]->name); fptr_ok(fptr_whitelist_mod_init(stack->mod[i]->init)); @@ -278,7 +299,7 @@ modstack_setup(struct module_stack* stack, const char* module_conf, } void -modstack_desetup(struct module_stack* stack, struct module_env* env) +modstack_call_deinit(struct module_stack* stack, struct module_env* env) { int i; for(i=0; inum; i++) { @@ -288,7 +309,7 @@ modstack_desetup(struct module_stack* stack, struct module_env* env) } void -modstack_destartup(struct module_stack* stack, struct module_env* env) +modstack_call_destartup(struct module_stack* stack, struct module_env* env) { int i; for(i=0; inum; i++) { @@ -297,9 +318,6 @@ modstack_destartup(struct module_stack* stack, struct module_env* env) fptr_ok(fptr_whitelist_mod_destartup(stack->mod[i]->destartup)); (*stack->mod[i]->destartup)(env, i); } - stack->num = 0; - free(stack->mod); - stack->mod = NULL; } int diff --git a/services/modstack.h b/services/modstack.h index deb8b634b..5674aefdd 100644 --- a/services/modstack.h +++ b/services/modstack.h @@ -61,14 +61,20 @@ struct module_stack { void modstack_init(struct module_stack* stack); /** - * Initialises modules and assignes ids. + * Free the stack of modules + * @param stack: stack that frees up memory. + */ +void modstack_free(struct module_stack* stack); + +/** + * Initialises modules and assignes ids. Calls module_startup(). * @param stack: Expected empty, filled according to module_conf * @param module_conf: string what modules to initialize * @param env: module environment which is inited by the modules. * environment should have a superalloc, cfg, * @return on false a module init failed. */ -int modstack_startup(struct module_stack* stack, const char* module_conf, +int modstack_call_startup(struct module_stack* stack, const char* module_conf, struct module_env* env); /** @@ -103,22 +109,22 @@ const char** module_list_avail(void); * env.need_to_validate is set by the modules. * @return on false a module init failed. */ -int modstack_setup(struct module_stack* stack, const char* module_conf, +int modstack_call_init(struct module_stack* stack, const char* module_conf, struct module_env* env); /** - * Desetup the modules, deinit. + * Deinit the modules. * @param stack: made empty. * @param env: module env for module deinit() calls. */ -void modstack_desetup(struct module_stack* stack, struct module_env* env); +void modstack_call_deinit(struct module_stack* stack, struct module_env* env); /** * Destartup the modules, close, delete. * @param stack: made empty. * @param env: module env for module destartup() calls. */ -void modstack_destartup(struct module_stack* stack, struct module_env* env); +void modstack_call_destartup(struct module_stack* stack, struct module_env* env); /** * Find index of module by name. diff --git a/testcode/unitzonemd.c b/testcode/unitzonemd.c index 6ae29cdc4..81d92c102 100644 --- a/testcode/unitzonemd.c +++ b/testcode/unitzonemd.c @@ -288,9 +288,9 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr, if(!env.auth_zones) fatal_exit("out of memory"); memset(&mods, 0, sizeof(mods)); - if(!modstack_startup(&mods, env.cfg->module_conf, &env)) + if(!modstack_call_startup(&mods, env.cfg->module_conf, &env)) fatal_exit("could not modstack_startup"); - if(!modstack_setup(&mods, env.cfg->module_conf, &env)) + if(!modstack_call_init(&mods, env.cfg->module_conf, &env)) fatal_exit("could not modstack_call_init"); env.mesh = mesh_create(&mods, &env); if(!env.mesh) @@ -329,8 +329,9 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr, /* desetup test harness */ mesh_delete(env.mesh); - modstack_desetup(&mods, &env); - modstack_destartup(&mods, &env); + modstack_call_deinit(&mods, &env); + modstack_call_destartup(&mods, &env); + modstack_free(&mods); auth_zones_delete(env.auth_zones); anchors_delete(env.anchors); config_delete(env.cfg); diff --git a/util/module.h b/util/module.h index 702372cb8..5bdb622a2 100644 --- a/util/module.h +++ b/util/module.h @@ -712,24 +712,6 @@ struct module_func_block { /** text string name of module */ const char* name; - /** - * Initialise the module. Called when restarting or reloading the - * daemon. - * This is the place to apply settings from the config file. - * @param env: module environment. - * @param id: module id number. - * return: 0 on error - */ - int (*init)(struct module_env* env, int id); - - /** - * Deinitialise the module, undo stuff done during init(). - * Called before reloading the daemon. - * @param env: module environment. - * @param id: module id number. - */ - void (*deinit)(struct module_env* env, int id); - /** * Set up the module for start. This is called only once at startup. * Privileged operations like opening device files may be done here. @@ -750,6 +732,24 @@ struct module_func_block { */ void (*destartup)(struct module_env* env, int id); + /** + * Initialise the module. Called when restarting or reloading the + * daemon. + * This is the place to apply settings from the config file. + * @param env: module environment. + * @param id: module id number. + * return: 0 on error + */ + int (*init)(struct module_env* env, int id); + + /** + * Deinitialise the module, undo stuff done during init(). + * Called before reloading the daemon. + * @param env: module environment. + * @param id: module id number. + */ + void (*deinit)(struct module_env* env, int id); + /** * accept a new query, or work further on existing query. * Changes the qstate->ext_state to be correct on exit. diff --git a/validator/validator.c b/validator/validator.c index 3f62733c7..d02f66d1f 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -3344,7 +3344,7 @@ val_get_mem(struct module_env* env, int id) */ static struct module_func_block val_block = { "validator", - &val_init, &val_deinit, NULL, NULL, &val_operate, &val_inform_super, + NULL, NULL, &val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear, &val_get_mem };