allow privileged initialisation of modules

This commit is contained in:
Christopher Zimmermann 2020-01-11 15:49:04 +01:00
parent a269db3828
commit c96e4ca121
28 changed files with 245 additions and 122 deletions

View file

@ -229,7 +229,7 @@ cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
} }
int int
cachedb_init(struct module_env* env, int id) cachedb_setup(struct module_env* env, int id)
{ {
struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1, struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1,
sizeof(struct cachedb_env)); sizeof(struct cachedb_env));
@ -268,7 +268,7 @@ cachedb_init(struct module_env* env, int id)
} }
void void
cachedb_deinit(struct module_env* env, int id) cachedb_desetup(struct module_env* env, int id)
{ {
struct cachedb_env* cachedb_env; struct cachedb_env* cachedb_env;
if(!env || !env->modinfo[id]) if(!env || !env->modinfo[id])
@ -846,7 +846,7 @@ cachedb_get_mem(struct module_env* env, int id)
*/ */
static struct module_func_block cachedb_block = { static struct module_func_block cachedb_block = {
"cachedb", "cachedb",
&cachedb_init, &cachedb_deinit, &cachedb_operate, &module_dummy_init, &module_dummy_init, &cachedb_setup, &cachedb_desetup, &cachedb_operate,
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem &cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
}; };

View file

@ -90,9 +90,9 @@ struct cachedb_backend {
#define CACHEDB_HASHSIZE 256 /* bit hash */ #define CACHEDB_HASHSIZE 256 /* bit hash */
/** Init the cachedb module */ /** Init the cachedb module */
int cachedb_init(struct module_env* env, int id); int cachedb_setup(struct module_env* env, int id);
/** Deinit the cachedb module */ /** Deinit the cachedb module */
void cachedb_deinit(struct module_env* env, int id); void cachedb_desetup(struct module_env* env, int id);
/** Operate on an event on a query (in qstate). */ /** Operate on an event on a query (in qstate). */
void cachedb_operate(struct module_qstate* qstate, enum module_ev event, void cachedb_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound); int id, struct outbound_entry* outbound);

View file

@ -251,7 +251,7 @@ daemon_init(void)
tzset(); tzset();
#endif #endif
daemon->need_to_exit = 0; daemon->need_to_exit = 0;
modstack_init(&daemon->mods); memset(&daemon->mods, 0, sizeof(daemon->mods));
if(!(daemon->env = (struct module_env*)calloc(1, if(!(daemon->env = (struct module_env*)calloc(1,
sizeof(*daemon->env)))) { sizeof(*daemon->env)))) {
free(daemon); free(daemon);
@ -365,6 +365,22 @@ daemon_open_shared_ports(struct daemon* daemon)
return 1; return 1;
} }
int
daemon_privileged(struct daemon* daemon)
{
if(!daemon_open_shared_ports(daemon))
fatal_exit("could not open ports");
daemon->env->cfg = daemon->cfg;
daemon->env->alloc = &daemon->superalloc;
daemon->env->worker = NULL;
if(!modstack_init(&daemon->mods, daemon->cfg->module_conf,
daemon->env)) {
fatal_exit("failed to init modules");
}
return 1;
}
/** /**
* Setup modules. setup module stack. * Setup modules. setup module stack.
* @param daemon: the daemon * @param daemon: the daemon

View file

@ -147,12 +147,13 @@ struct daemon {
struct daemon* daemon_init(void); struct daemon* daemon_init(void);
/** /**
* Open shared listening ports (if needed). * Do daemon setup that needs privileges
* like opening privileged ports or opening device files.
* The cfg member pointer must have been set for the daemon. * The cfg member pointer must have been set for the daemon.
* @param daemon: the daemon. * @param daemon: the daemon.
* @return: false on error. * @return: false on error.
*/ */
int daemon_open_shared_ports(struct daemon* daemon); int daemon_privileged(struct daemon* daemon);
/** /**
* Fork workers and start service. * Fork workers and start service.

View file

@ -668,8 +668,8 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi
config_lookup_uid(cfg); config_lookup_uid(cfg);
/* prepare */ /* prepare */
if(!daemon_open_shared_ports(daemon)) if(!daemon_privileged(daemon))
fatal_exit("could not open ports"); fatal_exit("could not do privileged setup");
if(!done_setup) { if(!done_setup) {
perform_setup(daemon, cfg, debug_mode, &cfgfile, need_pidfile); perform_setup(daemon, cfg, debug_mode, &cfgfile, need_pidfile);
done_setup = 1; done_setup = 1;

View file

@ -394,7 +394,7 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
* \param id This instance's ID number. * \param id This instance's ID number.
*/ */
int int
dns64_init(struct module_env* env, int id) dns64_setup(struct module_env* env, int id)
{ {
struct dns64_env* dns64_env = struct dns64_env* dns64_env =
(struct dns64_env*)calloc(1, sizeof(struct dns64_env)); (struct dns64_env*)calloc(1, sizeof(struct dns64_env));
@ -428,7 +428,7 @@ free_ignore_aaaa_node(rbnode_type* node, void* ATTR_UNUSED(arg))
* \param id This instance's ID number. * \param id This instance's ID number.
*/ */
void void
dns64_deinit(struct module_env* env, int id) dns64_desetup(struct module_env* env, int id)
{ {
struct dns64_env* dns64_env; struct dns64_env* dns64_env;
if (!env) if (!env)
@ -1019,8 +1019,8 @@ dns64_get_mem(struct module_env* env, int id)
*/ */
static struct module_func_block dns64_block = { static struct module_func_block dns64_block = {
"dns64", "dns64",
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super, &module_dummy_init, &module_dummy_init, &dns64_setup, &dns64_desetup,
&dns64_clear, &dns64_get_mem &dns64_operate, &dns64_inform_super, &dns64_clear, &dns64_get_mem
}; };
/** /**

View file

@ -50,10 +50,10 @@
struct module_func_block *dns64_get_funcblock(void); struct module_func_block *dns64_get_funcblock(void);
/** dns64 init */ /** dns64 init */
int dns64_init(struct module_env* env, int id); int dns64_setup(struct module_env* env, int id);
/** dns64 deinit */ /** dns64 deinit */
void dns64_deinit(struct module_env* env, int id); void dns64_desetup(struct module_env* env, int id);
/** dns64 operate on a query */ /** dns64 operate on a query */
void dns64_operate(struct module_qstate* qstate, enum module_ev event, int id, void dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,

View file

@ -188,7 +188,7 @@ subnet_markdel(void* key)
} }
int int
subnetmod_init(struct module_env *env, int id) subnetmod_setup(struct module_env *env, int id)
{ {
struct subnet_env *sn_env = (struct subnet_env*)calloc(1, struct subnet_env *sn_env = (struct subnet_env*)calloc(1,
sizeof(struct subnet_env)); sizeof(struct subnet_env));
@ -246,7 +246,7 @@ subnetmod_init(struct module_env *env, int id)
} }
void void
subnetmod_deinit(struct module_env *env, int id) subnetmod_desetup(struct module_env *env, int id)
{ {
struct subnet_env *sn_env; struct subnet_env *sn_env;
if(!env || !env->modinfo[id]) if(!env || !env->modinfo[id])
@ -846,8 +846,10 @@ subnetmod_get_mem(struct module_env *env, int id)
* The module function block * The module function block
*/ */
static struct module_func_block subnetmod_block = { static struct module_func_block subnetmod_block = {
"subnet", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate, "subnet",
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem &module_dummy_init, &module_dummy_init, &subnetmod_setup,
&subnetmod_desetup, &subnetmod_operate, &subnetmod_inform_super,
&subnetmod_clear, &subnetmod_get_mem
}; };
struct module_func_block* struct module_func_block*

View file

@ -97,10 +97,10 @@ size_t msg_cache_sizefunc(void* k, void* d);
struct module_func_block* subnetmod_get_funcblock(void); struct module_func_block* subnetmod_get_funcblock(void);
/** subnet module init */ /** subnet module init */
int subnetmod_init(struct module_env* env, int id); int subnetmod_setup(struct module_env* env, int id);
/** subnet module deinit */ /** subnet module deinit */
void subnetmod_deinit(struct module_env* env, int id); void subnetmod_desetup(struct module_env* env, int id);
/** subnet module operate on a query */ /** subnet module operate on a query */
void subnetmod_operate(struct module_qstate* qstate, enum module_ev event, void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,

View file

@ -67,7 +67,7 @@ ipsecmod_apply_cfg(struct ipsecmod_env* ipsecmod_env, struct config_file* cfg)
} }
int int
ipsecmod_init(struct module_env* env, int id) ipsecmod_setup(struct module_env* env, int id)
{ {
struct ipsecmod_env* ipsecmod_env = (struct ipsecmod_env*)calloc(1, struct ipsecmod_env* ipsecmod_env = (struct ipsecmod_env*)calloc(1,
sizeof(struct ipsecmod_env)); sizeof(struct ipsecmod_env));
@ -85,7 +85,7 @@ ipsecmod_init(struct module_env* env, int id)
} }
void void
ipsecmod_deinit(struct module_env* env, int id) ipsecmod_desetup(struct module_env* env, int id)
{ {
struct ipsecmod_env* ipsecmod_env; struct ipsecmod_env* ipsecmod_env;
if(!env || !env->modinfo[id]) if(!env || !env->modinfo[id])
@ -598,8 +598,9 @@ ipsecmod_get_mem(struct module_env* env, int id)
*/ */
static struct module_func_block ipsecmod_block = { static struct module_func_block ipsecmod_block = {
"ipsecmod", "ipsecmod",
&ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate, &module_dummy_init, &module_dummy_init, &ipsecmod_setup,
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem &ipsecmod_desetup, &ipsecmod_operate, &ipsecmod_inform_super,
&ipsecmod_clear, &ipsecmod_get_mem
}; };
struct module_func_block* struct module_func_block*

View file

@ -74,9 +74,9 @@ struct ipsecmod_qstate {
}; };
/** Init the ipsecmod module */ /** Init the ipsecmod module */
int ipsecmod_init(struct module_env* env, int id); int ipsecmod_setup(struct module_env* env, int id);
/** Deinit the ipsecmod module */ /** Deinit the ipsecmod module */
void ipsecmod_deinit(struct module_env* env, int id); void ipsecmod_desetup(struct module_env* env, int id);
/** Operate on an event on a query (in qstate). */ /** Operate on an event on a query (in qstate). */
void ipsecmod_operate(struct module_qstate* qstate, enum module_ev event, void ipsecmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound); int id, struct outbound_entry* outbound);

View file

@ -223,7 +223,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, stru
return 0; return 0;
} }
int ipset_init(struct module_env* env, int id) { int ipset_setup(struct module_env* env, int id) {
struct ipset_env *ipset_env; struct ipset_env *ipset_env;
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env)); ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
@ -250,7 +250,7 @@ int ipset_init(struct module_env* env, int id) {
return 1; return 1;
} }
void ipset_deinit(struct module_env *env, int id) { void ipset_desetup(struct module_env *env, int id) {
struct mnl_socket *mnl; struct mnl_socket *mnl;
struct ipset_env *ipset_env; struct ipset_env *ipset_env;
@ -373,7 +373,7 @@ size_t ipset_get_mem(struct module_env *env, int id) {
*/ */
static struct module_func_block ipset_block = { static struct module_func_block ipset_block = {
"ipset", "ipset",
&ipset_init, &ipset_deinit, &ipset_operate, &module_dummy_init, &module_dummy_init, &ipset_setup, &ipset_desetup, &ipset_operate,
&ipset_inform_super, &ipset_clear, &ipset_get_mem &ipset_inform_super, &ipset_clear, &ipset_get_mem
}; };

View file

@ -51,9 +51,9 @@ struct ipset_qstate {
}; };
/** Init the ipset module */ /** Init the ipset module */
int ipset_init(struct module_env* env, int id); int ipset_setup(struct module_env* env, int id);
/** Deinit the ipset module */ /** Deinit the ipset module */
void ipset_deinit(struct module_env* env, int id); void ipset_desetup(struct module_env* env, int id);
/** Operate on an event on a query (in qstate). */ /** Operate on an event on a query (in qstate). */
void ipset_operate(struct module_qstate* qstate, enum module_ev event, void ipset_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound); int id, struct outbound_entry* outbound);

View file

@ -73,7 +73,7 @@
int UNKNOWN_SERVER_NICENESS = 376; int UNKNOWN_SERVER_NICENESS = 376;
int int
iter_init(struct module_env* env, int id) iter_setup(struct module_env* env, int id)
{ {
struct iter_env* iter_env = (struct iter_env*)calloc(1, struct iter_env* iter_env = (struct iter_env*)calloc(1,
sizeof(struct iter_env)); sizeof(struct iter_env));
@ -107,7 +107,7 @@ caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
} }
void void
iter_deinit(struct module_env* env, int id) iter_desetup(struct module_env* env, int id)
{ {
struct iter_env* iter_env; struct iter_env* iter_env;
if(!env || !env->modinfo[id]) if(!env || !env->modinfo[id])
@ -3849,8 +3849,8 @@ iter_get_mem(struct module_env* env, int id)
*/ */
static struct module_func_block iter_block = { static struct module_func_block iter_block = {
"iterator", "iterator",
&iter_init, &iter_deinit, &iter_operate, &iter_inform_super, &module_dummy_init, &module_dummy_init, &iter_setup, &iter_desetup,
&iter_clear, &iter_get_mem &iter_operate, &iter_inform_super, &iter_clear, &iter_get_mem
}; };
struct module_func_block* struct module_func_block*

View file

@ -429,10 +429,10 @@ const char* iter_state_to_string(enum iter_state state);
int iter_state_is_responsestate(enum iter_state s); int iter_state_is_responsestate(enum iter_state s);
/** iterator init */ /** iterator init */
int iter_init(struct module_env* env, int id); int iter_setup(struct module_env* env, int id);
/** iterator deinit */ /** iterator deinit */
void iter_deinit(struct module_env* env, int id); void iter_desetup(struct module_env* env, int id);
/** iterator operate on a query */ /** iterator operate on a query */
void iter_operate(struct module_qstate* qstate, enum module_ev event, int id, void iter_operate(struct module_qstate* qstate, enum module_ev event, int id,

View file

@ -69,6 +69,8 @@ context_finalize(struct ub_ctx* ctx)
log_init(cfg->logfile, cfg->use_syslog, NULL); log_init(cfg->logfile, cfg->use_syslog, NULL);
} }
config_apply(cfg); config_apply(cfg);
if(!modstack_init(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL;
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env)) if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
return UB_INITFAIL; return UB_INITFAIL;
log_edns_known_options(VERB_ALGO, ctx->env); log_edns_known_options(VERB_ALGO, ctx->env);

View file

@ -156,7 +156,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
ctx->env->alloc = &ctx->superalloc; ctx->env->alloc = &ctx->superalloc;
ctx->env->worker = NULL; ctx->env->worker = NULL;
ctx->env->need_to_validate = 0; ctx->env->need_to_validate = 0;
modstack_init(&ctx->mods); memset(&ctx->mods, 0, sizeof(ctx->mods));
rbtree_init(&ctx->queries, &context_query_cmp); rbtree_init(&ctx->queries, &context_query_cmp);
return ctx; return ctx;
} }
@ -172,6 +172,7 @@ ub_ctx_create(void)
ub_randfree(ctx->seed_rnd); ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg); config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env); modstack_desetup(&ctx->mods, ctx->env);
modstack_deinit(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
free(ctx->env); free(ctx->env);
free(ctx); free(ctx);
@ -184,6 +185,7 @@ ub_ctx_create(void)
ub_randfree(ctx->seed_rnd); ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg); config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env); modstack_desetup(&ctx->mods, ctx->env);
modstack_deinit(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
free(ctx->env); free(ctx->env);
free(ctx); free(ctx);
@ -303,6 +305,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
libworker_delete_event(ctx->event_worker); libworker_delete_event(ctx->event_worker);
modstack_desetup(&ctx->mods, ctx->env); modstack_desetup(&ctx->mods, ctx->env);
modstack_deinit(&ctx->mods, ctx->env);
a = ctx->alloc_list; a = ctx->alloc_list;
while(a) { while(a) {
na = a->super; na = a->super;

View file

@ -547,7 +547,7 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
} }
int int
respip_init(struct module_env* env, int id) respip_setup(struct module_env* env, int id)
{ {
(void)env; (void)env;
(void)id; (void)id;
@ -555,7 +555,7 @@ respip_init(struct module_env* env, int id)
} }
void void
respip_deinit(struct module_env* env, int id) respip_desetup(struct module_env* env, int id)
{ {
(void)env; (void)env;
(void)id; (void)id;
@ -1273,8 +1273,8 @@ respip_get_mem(struct module_env* env, int id)
*/ */
static struct module_func_block respip_block = { static struct module_func_block respip_block = {
"respip", "respip",
&respip_init, &respip_deinit, &respip_operate, &respip_inform_super, &module_dummy_init, &module_dummy_init, &respip_setup, &respip_desetup, &respip_operate,
&respip_clear, &respip_get_mem &respip_inform_super, &respip_clear, &respip_get_mem
}; };
struct module_func_block* struct module_func_block*

View file

@ -192,10 +192,10 @@ int respip_rewrite_reply(const struct query_info* qinfo,
struct module_func_block* respip_get_funcblock(void); struct module_func_block* respip_get_funcblock(void);
/** response-ip init */ /** response-ip init */
int respip_init(struct module_env* env, int id); int respip_setup(struct module_env* env, int id);
/** response-ip deinit */ /** response-ip deinit */
void respip_deinit(struct module_env* env, int id); void respip_desetup(struct module_env* env, int id);
/** response-ip operate on a query */ /** response-ip operate on a query */
void respip_operate(struct module_qstate* qstate, enum module_ev event, int id, void respip_operate(struct module_qstate* qstate, enum module_ev event, int id,

View file

@ -85,13 +85,6 @@ count_modules(const char* s)
return num; return num;
} }
void
modstack_init(struct module_stack* stack)
{
stack->num = 0;
stack->mod = NULL;
}
int int
modstack_config(struct module_stack* stack, const char* module_conf) modstack_config(struct module_stack* stack, const char* module_conf)
{ {
@ -211,17 +204,16 @@ module_func_block* module_factory(const char** str)
} }
int int
modstack_setup(struct module_stack* stack, const char* module_conf, modstack_init(struct module_stack* stack, const char* module_conf,
struct module_env* env) struct module_env* env)
{ {
int i; int i;
if(stack->num != 0) if (stack->num != 0)
modstack_desetup(stack, env); fatal_exit("unexpected already initialised modules");
/* fixed setup of the modules */ /* fixed setup of the modules */
if(!modstack_config(stack, module_conf)) { if(!modstack_config(stack, module_conf)) {
return 0; return 0;
} }
env->need_to_validate = 0; /* set by module init below */
for(i=0; i<stack->num; i++) { for(i=0; i<stack->num; i++) {
verbose(VERB_OPS, "init module %d: %s", verbose(VERB_OPS, "init module %d: %s",
i, stack->mod[i]->name); i, stack->mod[i]->name);
@ -235,8 +227,45 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
return 1; return 1;
} }
int
modstack_setup(struct module_stack* stack, const char* module_conf,
struct module_env* env)
{
int i;
env->need_to_validate = 0; /* set by module setup below */
for(i=0; i<stack->num; 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;
}
module_conf += strlen(stack->mod[i]->name);
verbose(VERB_OPS, "setup module %d: %s",
i, stack->mod[i]->name);
fptr_ok(fptr_whitelist_mod_setup(stack->mod[i]->setup));
if(!(*stack->mod[i]->setup)(env, i)) {
log_err("module setup for module %s failed",
stack->mod[i]->name);
return 0;
}
}
return 1;
}
void void
modstack_desetup(struct module_stack* stack, struct module_env* env) modstack_desetup(struct module_stack* stack, struct module_env* env)
{
int i;
for(i=0; i<stack->num; i++) {
fptr_ok(fptr_whitelist_mod_desetup(stack->mod[i]->desetup));
(*stack->mod[i]->desetup)(env, i);
}
}
void
modstack_deinit(struct module_stack* stack, struct module_env* env)
{ {
int i; int i;
for(i=0; i<stack->num; i++) { for(i=0; i<stack->num; i++) {

View file

@ -55,10 +55,16 @@ struct module_stack {
}; };
/** /**
* Init a stack of modules * Initialises modules and assignes ids.
* @param stack: initialised as empty. * @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,
* env.need_to_validate is set by the modules.
* @return on false a module init failed.
*/ */
void modstack_init(struct module_stack* stack); int modstack_init(struct module_stack* stack, const char* module_conf,
struct module_env* env);
/** /**
* Read config file module settings and set up the modfunc block * Read config file module settings and set up the modfunc block
@ -83,10 +89,10 @@ struct module_func_block* module_factory(const char** str);
const char** module_list_avail(void); const char** module_list_avail(void);
/** /**
* Setup modules. Assigns ids and calls module_init. * Setup modules. Calls module_setup().
* @param stack: if not empty beforehand, it will be desetup()ed. * @param stack: It is modstack_setupped().
* It is then modstack_configged(). * @param module_conf: module ordering to check against the ordering in stack.
* @param module_conf: string what modules to insert. * fails on changed ordering.
* @param env: module environment which is inited by the modules. * @param env: module environment which is inited by the modules.
* environment should have a superalloc, cfg, * environment should have a superalloc, cfg,
* env.need_to_validate is set by the modules. * env.need_to_validate is set by the modules.
@ -96,12 +102,19 @@ int modstack_setup(struct module_stack* stack, const char* module_conf,
struct module_env* env); struct module_env* env);
/** /**
* Desetup the modules, deinit, delete. * Desetup the modules
* @param stack: made empty. * @param stack: made empty.
* @param env: module env for module deinit() calls. * @param env: module env for module deinit() calls.
*/ */
void modstack_desetup(struct module_stack* stack, struct module_env* env); void modstack_desetup(struct module_stack* stack, struct module_env* env);
/**
* Deinit the modules, deinit, delete.
* @param stack: made empty.
* @param env: module env for module deinit() calls.
*/
void modstack_deinit(struct module_stack* stack, struct module_env* env);
/** /**
* Find index of module by name. * Find index of module by name.
* @param stack: to look in * @param stack: to look in

View file

@ -137,9 +137,11 @@ check_mod(struct config_file* cfg, struct module_func_block* fb)
fatal_exit("out of memory"); fatal_exit("out of memory");
if(!edns_known_options_init(&env)) if(!edns_known_options_init(&env))
fatal_exit("out of memory"); fatal_exit("out of memory");
if(!(*fb->init)(&env, 0)) { if(!(*fb->setup)(&env, 0))
fatal_exit("bad config for %s module", fb->name); fatal_exit("bad config for %s module", fb->name);
} if(!(*fb->setup)(&env, 0))
fatal_exit("bad config for %s module", fb->name);
(*fb->desetup)(&env, 0);
(*fb->deinit)(&env, 0); (*fb->deinit)(&env, 0);
sldns_buffer_free(env.scratch_buffer); sldns_buffer_free(env.scratch_buffer);
regional_destroy(env.scratch); regional_destroy(env.scratch);

View file

@ -385,22 +385,7 @@ fptr_whitelist_modenv_detect_cycle(int (*fptr)(
int int
fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)) fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
{ {
if(fptr == &iter_init) return 1; if(fptr == &module_dummy_init) return 1;
else if(fptr == &val_init) return 1;
else if(fptr == &dns64_init) return 1;
else if(fptr == &respip_init) return 1;
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_init) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_init) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_init) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_init) return 1;
#endif
#ifdef USE_IPSET #ifdef USE_IPSET
else if(fptr == &ipset_init) return 1; else if(fptr == &ipset_init) return 1;
#endif #endif
@ -408,30 +393,65 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
} }
int int
fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)) fptr_whitelist_mod_deinit(int (*fptr)(struct module_env* env, int id))
{ {
if(fptr == &iter_deinit) return 1; if(fptr == &module_dummy_init) return 1;
else if(fptr == &val_deinit) return 1;
else if(fptr == &dns64_deinit) return 1;
else if(fptr == &respip_deinit) return 1;
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_deinit) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_deinit) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_deinit) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_deinit) return 1;
#endif
#ifdef USE_IPSET #ifdef USE_IPSET
else if(fptr == &ipset_deinit) return 1; else if(fptr == &ipset_deinit) return 1;
#endif #endif
return 0; return 0;
} }
int
fptr_whitelist_mod_setup(int (*fptr)(struct module_env* env, int id))
{
if(fptr == &iter_setup) return 1;
else if(fptr == &val_setup) return 1;
else if(fptr == &dns64_setup) return 1;
else if(fptr == &respip_setup) return 1;
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_setup) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_setup) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_setup) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_setup) return 1;
#endif
#ifdef USE_IPSET
else if(fptr == &ipset_setup) return 1;
#endif
return 0;
}
int
fptr_whitelist_mod_desetup(void (*fptr)(struct module_env* env, int id))
{
if(fptr == &iter_desetup) return 1;
else if(fptr == &val_desetup) return 1;
else if(fptr == &dns64_desetup) return 1;
else if(fptr == &respip_desetup) return 1;
#ifdef WITH_PYTHONMODULE
else if(fptr == &pythonmod_desetup) return 1;
#endif
#ifdef USE_CACHEDB
else if(fptr == &cachedb_desetup) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_desetup) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_desetup) return 1;
#endif
#ifdef USE_IPSET
else if(fptr == &ipset_desetup) return 1;
#endif
return 0;
}
int int
fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate, fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
enum module_ev event, int id, struct outbound_entry* outbound)) enum module_ev event, int id, struct outbound_entry* outbound))

View file

@ -270,12 +270,20 @@ int fptr_whitelist_modenv_detect_cycle(int (*fptr)(
int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)); int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id));
/** /**
* Check function pointer whitelist for module deinit call values. * Check function pointer whitelist for module setup call values.
* *
* @param fptr: function pointer to check. * @param fptr: function pointer to check.
* @return false if not in whitelist. * @return false if not in whitelist.
*/ */
int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)); int fptr_whitelist_mod_setup(int (*fptr)(struct module_env* env, int id));
/**
* Check function pointer whitelist for module desetup call values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_mod_desetup(void (*fptr)(struct module_env* env, int id));
/** /**
* Check function pointer whitelist for module operate call values. * Check function pointer whitelist for module operate call values.

View file

@ -246,3 +246,8 @@ copy_state_to_super(struct module_qstate* qstate, int ATTR_UNUSED(id),
super->was_ratelimited = qstate->was_ratelimited; super->was_ratelimited = qstate->was_ratelimited;
} }
} }
int module_dummy_init(struct module_env* env, int id)
{
return 1;
}

View file

@ -673,20 +673,39 @@ struct module_func_block {
const char* name; const char* name;
/** /**
* init the module. Called once for the global state. * initialise the module. This is called only once at startup.
* This is the place to apply settings from the config file. * Privileged operations like opening device files may be done here.
* @param env: module environment.
* @param id: module id number. * @param id: module id number.
* return: 0 on error * return: 0 on error
*/ */
int (*init)(struct module_env* env, int id); int (*init)(struct module_env* env, int id);
/** /**
* de-init, delete, the module. Called once for the global state. * deinitialise the module. This is called only once before shutdown to
* free resources allocated during init().
* Closing privileged ports or files must be done here.
* @param id: module id number.
* return: 0 on error
*/
int (*deinit)(struct module_env* env, int id);
/**
* setup 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 (*setup)(struct module_env* env, int id);
/**
* de-setup, undo stuff done during setup().
* Called before reloading the daemon.
* @param env: module environment. * @param env: module environment.
* @param id: module id number. * @param id: module id number.
*/ */
void (*deinit)(struct module_env* env, int id); void (*desetup)(struct module_env* env, int id);
/** /**
* accept a new query, or work further on existing query. * accept a new query, or work further on existing query.
@ -858,4 +877,6 @@ void log_edns_known_options(enum verbosity_value level,
void copy_state_to_super(struct module_qstate* qstate, int id, void copy_state_to_super(struct module_qstate* qstate, int id,
struct module_qstate* super); struct module_qstate* super);
int module_dummy_init(struct module_env* env, int id);
#endif /* UTIL_MODULE_H */ #endif /* UTIL_MODULE_H */

View file

@ -165,7 +165,7 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env,
void ecdsa_evp_workaround_init(void); void ecdsa_evp_workaround_init(void);
#endif #endif
int int
val_init(struct module_env* env, int id) val_setup(struct module_env* env, int id)
{ {
struct val_env* val_env = (struct val_env*)calloc(1, struct val_env* val_env = (struct val_env*)calloc(1,
sizeof(struct val_env)); sizeof(struct val_env));
@ -190,7 +190,7 @@ val_init(struct module_env* env, int id)
} }
void void
val_deinit(struct module_env* env, int id) val_desetup(struct module_env* env, int id)
{ {
struct val_env* val_env; struct val_env* val_env;
if(!env || !env->modinfo[id]) if(!env || !env->modinfo[id])
@ -3266,8 +3266,8 @@ val_get_mem(struct module_env* env, int id)
*/ */
static struct module_func_block val_block = { static struct module_func_block val_block = {
"validator", "validator",
&val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear, &module_dummy_init, &module_dummy_init, &val_setup, &val_desetup,
&val_get_mem &val_operate, &val_inform_super, &val_clear, &val_get_mem
}; };
struct module_func_block* struct module_func_block*

View file

@ -254,10 +254,10 @@ struct module_func_block* val_get_funcblock(void);
const char* val_state_to_string(enum val_state state); const char* val_state_to_string(enum val_state state);
/** validator init */ /** validator init */
int val_init(struct module_env* env, int id); int val_setup(struct module_env* env, int id);
/** validator deinit */ /** validator deinit */
void val_deinit(struct module_env* env, int id); void val_desetup(struct module_env* env, int id);
/** validator operate on a query */ /** validator operate on a query */
void val_operate(struct module_qstate* qstate, enum module_ev event, int id, void val_operate(struct module_qstate* qstate, enum module_ev event, int id,