]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
allow privileged initialisation of modules
authorChristopher Zimmermann <madroach@gmerlin.de>
Sat, 11 Jan 2020 14:49:04 +0000 (15:49 +0100)
committerChristopher Zimmermann <madroach@gmerlin.de>
Sun, 10 May 2020 20:30:25 +0000 (22:30 +0200)
28 files changed:
cachedb/cachedb.c
cachedb/cachedb.h
daemon/daemon.c
daemon/daemon.h
daemon/unbound.c
dns64/dns64.c
dns64/dns64.h
edns-subnet/subnetmod.c
edns-subnet/subnetmod.h
ipsecmod/ipsecmod.c
ipsecmod/ipsecmod.h
ipset/ipset.c
ipset/ipset.h
iterator/iterator.c
iterator/iterator.h
libunbound/context.c
libunbound/libunbound.c
respip/respip.c
respip/respip.h
services/modstack.c
services/modstack.h
smallapp/unbound-checkconf.c
util/fptr_wlist.c
util/fptr_wlist.h
util/module.c
util/module.h
validator/validator.c
validator/validator.h

index eed4d5fd9bed8cbc6e2107e241b58bcea6d46e0d..06738972ffe5c2f01f6f03f04cde11b63cc4347a 100644 (file)
@@ -229,7 +229,7 @@ cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
 }
 
 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,
                sizeof(struct cachedb_env));
@@ -268,7 +268,7 @@ cachedb_init(struct module_env* env, int id)
 }
 
 void 
-cachedb_deinit(struct module_env* env, int id)
+cachedb_desetup(struct module_env* env, int id)
 {
        struct cachedb_env* cachedb_env;
        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 = {
        "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
 };
 
index 05c4368e60b433337eb2eb6223ec351f9c0fe648..117916e4b019748fecfc08dde6295b55f8c316d2 100644 (file)
@@ -90,9 +90,9 @@ struct cachedb_backend {
 #define CACHEDB_HASHSIZE 256 /* bit hash */
 
 /** 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 */
-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). */
 void cachedb_operate(struct module_qstate* qstate, enum module_ev event,
        int id, struct outbound_entry* outbound);
index 5d4279259ed6b926fdbff459fea746899dd1e22a..05f16cc60d2231921c9af0507b91ffc508ec0c64 100644 (file)
@@ -251,7 +251,7 @@ daemon_init(void)
        tzset();
 #endif
        daemon->need_to_exit = 0;
-       modstack_init(&daemon->mods);
+       memset(&daemon->mods, 0, sizeof(daemon->mods));
        if(!(daemon->env = (struct module_env*)calloc(1, 
                sizeof(*daemon->env)))) {
                free(daemon);
@@ -293,7 +293,7 @@ daemon_init(void)
        return daemon;  
 }
 
-int 
+int
 daemon_open_shared_ports(struct daemon* daemon)
 {
        log_assert(daemon);
@@ -365,6 +365,22 @@ daemon_open_shared_ports(struct daemon* daemon)
        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.
  * @param daemon: the daemon
index 3effbafb79183a2da8312a082d50dec0b5e2d008..7d8b99fc4333f3382e9621578559db3e553c919e 100644 (file)
@@ -147,12 +147,13 @@ struct daemon {
 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.
  * @param daemon: the daemon.
  * @return: false on error.
  */
-int daemon_open_shared_ports(struct daemon* daemon);
+int daemon_privileged(struct daemon* daemon);
 
 /**
  * Fork workers and start service.
index ceb3da6f53aa821317a7f47fb24f4102a8fe7c8b..32604728d32050c4a67b5fb85302eae1d41f2561 100644 (file)
@@ -668,8 +668,8 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi
                        config_lookup_uid(cfg);
        
                /* prepare */
-               if(!daemon_open_shared_ports(daemon))
-                       fatal_exit("could not open ports");
+               if(!daemon_privileged(daemon))
+                       fatal_exit("could not do privileged setup");
                if(!done_setup) { 
                        perform_setup(daemon, cfg, debug_mode, &cfgfile, need_pidfile);
                        done_setup = 1; 
index 5c70119a54de1711f751f189596b626b19f2d2e0..97ecce4b00dcc254c5c4179b93bb598fa21c7329 100644 (file)
@@ -394,7 +394,7 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
  * \param id  This instance's ID number.
  */
 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*)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.
  */
 void
-dns64_deinit(struct module_env* env, int id)
+dns64_desetup(struct module_env* env, int id)
 {
     struct dns64_env* dns64_env;
     if (!env)
@@ -1019,8 +1019,8 @@ dns64_get_mem(struct module_env* env, int id)
  */
 static struct module_func_block dns64_block = {
        "dns64",
-       &dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
-       &dns64_clear, &dns64_get_mem
+       &module_dummy_init, &module_dummy_init, &dns64_setup, &dns64_desetup,
+       &dns64_operate, &dns64_inform_super, &dns64_clear, &dns64_get_mem
 };
 
 /**
index 2f0c01a228cd06b8390c91ec65aac58cb96d24a1..532a5bed3a984a48bbe7c0e009ff4c6025ded19d 100644 (file)
 struct module_func_block *dns64_get_funcblock(void);
 
 /** dns64 init */
-int dns64_init(struct module_env* env, int id);
+int dns64_setup(struct module_env* env, int id);
 
 /** 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 */
 void dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
index 37dc550cd69c36d768c4b95baf206ebd0cebf0a5..cb29693526cac7def9fa9de319f9b75c56abef8f 100644 (file)
@@ -188,7 +188,7 @@ subnet_markdel(void* key)
 }
 
 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,
                sizeof(struct subnet_env));
@@ -246,7 +246,7 @@ subnetmod_init(struct module_env *env, int id)
 }
 
 void
-subnetmod_deinit(struct module_env *env, int id)
+subnetmod_desetup(struct module_env *env, int id)
 {
        struct subnet_env *sn_env;
        if(!env || !env->modinfo[id])
@@ -846,8 +846,10 @@ subnetmod_get_mem(struct module_env *env, int id)
  * The module function block 
  */
 static struct module_func_block subnetmod_block = {
-       "subnet", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
-       &subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
+       "subnet",
+       &module_dummy_init, &module_dummy_init, &subnetmod_setup,
+       &subnetmod_desetup, &subnetmod_operate, &subnetmod_inform_super,
+       &subnetmod_clear, &subnetmod_get_mem
 };
 
 struct module_func_block*
index e408627b0abdf25f0799519c68306b104dcf288f..7936d889eb136574a88f2ff1be5af7881471733a 100644 (file)
@@ -97,10 +97,10 @@ size_t msg_cache_sizefunc(void* k, void* d);
 struct module_func_block* subnetmod_get_funcblock(void);
 
 /** subnet module init */
-int subnetmod_init(struct module_env* env, int id);
+int subnetmod_setup(struct module_env* env, int id);
 
 /** 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 */
 void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,
index a1f40a512b8a0c883567367c369d6689db814eed..ce461f00aecd1ce87022c2d873b19f4e926acf4c 100644 (file)
@@ -67,7 +67,7 @@ ipsecmod_apply_cfg(struct ipsecmod_env* ipsecmod_env, struct config_file* cfg)
 }
 
 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,
                sizeof(struct ipsecmod_env));
@@ -85,7 +85,7 @@ ipsecmod_init(struct module_env* env, int id)
 }
 
 void
-ipsecmod_deinit(struct module_env* env, int id)
+ipsecmod_desetup(struct module_env* env, int id)
 {
        struct ipsecmod_env* ipsecmod_env;
        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 = {
        "ipsecmod",
-       &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
-       &ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
+       &module_dummy_init, &module_dummy_init, &ipsecmod_setup,
+       &ipsecmod_desetup, &ipsecmod_operate, &ipsecmod_inform_super,
+       &ipsecmod_clear, &ipsecmod_get_mem
 };
 
 struct module_func_block*
index e00816d4bf998db25f21b07e350b286861d0ebf8..96d28717b1b205076100d451c0e284ff2d9235d1 100644 (file)
@@ -74,9 +74,9 @@ struct ipsecmod_qstate {
 };
 
 /** 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 */
-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). */
 void ipsecmod_operate(struct module_qstate* qstate, enum module_ev event,
        int id, struct outbound_entry* outbound);
index f6e2c4a9d8a6d947f056acd88f023624a22296bf..bf4cbea477b33ea55f63f49580c5a3496eccf8c6 100755 (executable)
@@ -223,7 +223,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg, stru
        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;
 
        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;
 }
 
-void ipset_deinit(struct module_env *env, int id) {
+void ipset_desetup(struct module_env *env, int id) {
        struct mnl_socket *mnl;
        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 = {
        "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
 };
 
index f60a8be8c8377da240452b2464298a83772dff44..6273ec789931a7c5d204987187c21047ef79d53a 100755 (executable)
@@ -51,9 +51,9 @@ struct ipset_qstate {
 };
 
 /** 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 */
-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). */
 void ipset_operate(struct module_qstate* qstate, enum module_ev event,
        int id, struct outbound_entry* outbound);
index eea2f2fb23ad3773aca42da235166e1830aeee28..af209f84d9f928a9a2a9ea0ca505664dee7325b5 100644 (file)
@@ -73,7 +73,7 @@
 int UNKNOWN_SERVER_NICENESS = 376;
 
 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,
                sizeof(struct iter_env));
@@ -107,7 +107,7 @@ caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
 }
 
 void 
-iter_deinit(struct module_env* env, int id)
+iter_desetup(struct module_env* env, int id)
 {
        struct iter_env* iter_env;
        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 = {
        "iterator",
-       &iter_init, &iter_deinit, &iter_operate, &iter_inform_super, 
-       &iter_clear, &iter_get_mem
+       &module_dummy_init, &module_dummy_init, &iter_setup, &iter_desetup,
+       &iter_operate, &iter_inform_super, &iter_clear, &iter_get_mem
 };
 
 struct module_func_block* 
index 26ff39559f108e053e923619beaae4a89625eef4..30bc47289651a793ce34685cc487e374c278b3c5 100644 (file)
@@ -429,10 +429,10 @@ const char* iter_state_to_string(enum iter_state state);
 int iter_state_is_responsestate(enum iter_state s);
 
 /** iterator init */
-int iter_init(struct module_env* env, int id);
+int iter_setup(struct module_env* env, int id);
 
 /** 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 */
 void iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
index 6d62e32b50fdd5d9e977bdb569bbfdf77fbc684a..e04cd653dc2aec10bf568a3d73d208d16829611d 100644 (file)
@@ -69,6 +69,8 @@ context_finalize(struct ub_ctx* ctx)
                log_init(cfg->logfile, cfg->use_syslog, NULL);
        }
        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))
                return UB_INITFAIL;
        log_edns_known_options(VERB_ALGO, ctx->env);
index 3b30419b315e35b444086b32520d17d84952435a..e1abfe64ab02888872813e7365d3baedcea1ab8a 100644 (file)
@@ -156,7 +156,7 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
        ctx->env->alloc = &ctx->superalloc;
        ctx->env->worker = NULL;
        ctx->env->need_to_validate = 0;
-       modstack_init(&ctx->mods);
+       memset(&ctx->mods, 0, sizeof(ctx->mods));
        rbtree_init(&ctx->queries, &context_query_cmp);
        return ctx;
 }
@@ -172,6 +172,7 @@ ub_ctx_create(void)
                ub_randfree(ctx->seed_rnd);
                config_delete(ctx->env->cfg);
                modstack_desetup(&ctx->mods, ctx->env);
+               modstack_deinit(&ctx->mods, ctx->env);
                edns_known_options_delete(ctx->env);
                free(ctx->env);
                free(ctx);
@@ -184,6 +185,7 @@ ub_ctx_create(void)
                ub_randfree(ctx->seed_rnd);
                config_delete(ctx->env->cfg);
                modstack_desetup(&ctx->mods, ctx->env);
+               modstack_deinit(&ctx->mods, ctx->env);
                edns_known_options_delete(ctx->env);
                free(ctx->env);
                free(ctx);
@@ -303,6 +305,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
        libworker_delete_event(ctx->event_worker);
 
        modstack_desetup(&ctx->mods, ctx->env);
+       modstack_deinit(&ctx->mods, ctx->env);
        a = ctx->alloc_list;
        while(a) {
                na = a->super;
index 6fa4f18851fdefbf6cc5325f60cabd5f837c4189..44aea841cc6bcb4351569d86c4f6fae56861aa75 100644 (file)
@@ -547,7 +547,7 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
 }
 
 int
-respip_init(struct module_env* env, int id)
+respip_setup(struct module_env* env, int id)
 {
        (void)env;
        (void)id;
@@ -555,7 +555,7 @@ respip_init(struct module_env* env, int id)
 }
 
 void
-respip_deinit(struct module_env* env, int id)
+respip_desetup(struct module_env* env, int id)
 {
        (void)env;
        (void)id;
@@ -1273,8 +1273,8 @@ respip_get_mem(struct module_env* env, int id)
  */
 static struct module_func_block respip_block = {
        "respip",
-       &respip_init, &respip_deinit, &respip_operate, &respip_inform_super,
-       &respip_clear, &respip_get_mem
+       &module_dummy_init, &module_dummy_init, &respip_setup, &respip_desetup, &respip_operate,
+       &respip_inform_super, &respip_clear, &respip_get_mem
 };
 
 struct module_func_block*
index bbd471421c1ee0faad8a1cc3451a7306b0196245..d260147666324a273cb7394587ce1dfb6d1b64d4 100644 (file)
@@ -192,10 +192,10 @@ int respip_rewrite_reply(const struct query_info* qinfo,
 struct module_func_block* respip_get_funcblock(void);
 
 /** response-ip init */
-int respip_init(struct module_env* env, int id);
+int respip_setup(struct module_env* env, int id);
 
 /** 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 */
 void respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
index 68e5928146dd5a6d71255e55982b667f8a775bb6..5a57ecd2d4695942fd5c9e5ef5db17a2b6d34169 100644 (file)
@@ -85,14 +85,7 @@ count_modules(const char* s)
         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)
 {
         int i;
@@ -210,18 +203,17 @@ module_func_block* module_factory(const char** str)
         return NULL;
 }
 
-int 
-modstack_setup(struct module_stack* stack, const char* module_conf,
+int
+modstack_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;
+       if (stack->num != 0)
+               fatal_exit("unexpected already initialised modules");
         /* fixed setup of the modules */
         if(!modstack_config(stack, module_conf)) {
                return 0;
         }
-        env->need_to_validate = 0; /* set by module init below */
         for(i=0; i<stack->num; i++) {
                 verbose(VERB_OPS, "init module %d: %s",
                         i, stack->mod[i]->name);
@@ -235,8 +227,45 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
        return 1;
 }
 
-void 
+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
 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;
         for(i=0; i<stack->num; i++) {
@@ -248,7 +277,7 @@ modstack_desetup(struct module_stack* stack, struct module_env* env)
         stack->mod = NULL;
 }
 
-int 
+int
 modstack_find(struct module_stack* stack, const char* name)
 {
        int i;
index 3ff01b54d938d192a98ade210a7416542eaeb2cc..3e79595ed6ebd5b9763727b024d5afc8df4762b3 100644 (file)
@@ -55,10 +55,16 @@ struct module_stack {
 };
 
 /**
- * Init a stack of modules
- * @param stack: initialised as empty.
+ * Initialises modules and assignes ids.
+ * @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
@@ -83,10 +89,10 @@ struct module_func_block* module_factory(const char** str);
 const char** module_list_avail(void);
 
 /**
- * Setup modules. Assigns ids and calls module_init.
- * @param stack: if not empty beforehand, it will be desetup()ed.
- *     It is then modstack_configged().
- * @param module_conf: string what modules to insert.
+ * Setup modules. Calls module_setup().
+ * @param stack: It is modstack_setupped().
+ * @param module_conf: module ordering to check against the ordering in stack.
+ * fails on changed ordering.
  * @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.
@@ -96,12 +102,19 @@ int modstack_setup(struct module_stack* stack, const char* module_conf,
        struct module_env* env);
 
 /**
- * Desetup the modules, deinit, delete.
+ * Desetup 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);
 
+/**
+ * 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.
  * @param stack: to look in
index 3fc638cae980794b78e6e1cfcb0b49812ac1c100..a1f70a8e67dfe6dba9110edeb37e1273c6ce4d80 100644 (file)
@@ -137,9 +137,11 @@ check_mod(struct config_file* cfg, struct module_func_block* fb)
                fatal_exit("out of memory");
        if(!edns_known_options_init(&env))
                fatal_exit("out of memory");
-       if(!(*fb->init)(&env, 0)) {
+       if(!(*fb->setup)(&env, 0))
                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);
        sldns_buffer_free(env.scratch_buffer);
        regional_destroy(env.scratch);
index b124e7169ea9a4586ae6f65df5bcfe4a853967c7..35d8bfaedf65f2f75b6bd832025d8419c158af54 100644 (file)
@@ -382,52 +382,72 @@ fptr_whitelist_modenv_detect_cycle(int (*fptr)(
        return 0;
 }
 
-int 
+int
 fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
 {
-       if(fptr == &iter_init) return 1;
-       else if(fptr == &val_init) return 1;
-       else if(fptr == &dns64_init) return 1;
-       else if(fptr == &respip_init) return 1;
+       if(fptr == &module_dummy_init) return 1;
+#ifdef USE_IPSET
+       else if(fptr == &ipset_init) return 1;
+#endif
+       return 0;
+}
+
+int
+fptr_whitelist_mod_deinit(int (*fptr)(struct module_env* env, int id))
+{
+       if(fptr == &module_dummy_init) return 1;
+#ifdef USE_IPSET
+       else if(fptr == &ipset_deinit) return 1;
+#endif
+       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_init) return 1;
+       else if(fptr == &pythonmod_setup) return 1;
 #endif
 #ifdef USE_CACHEDB
-       else if(fptr == &cachedb_init) return 1;
+       else if(fptr == &cachedb_setup) return 1;
 #endif
 #ifdef USE_IPSECMOD
-       else if(fptr == &ipsecmod_init) return 1;
+       else if(fptr == &ipsecmod_setup) return 1;
 #endif
 #ifdef CLIENT_SUBNET
-       else if(fptr == &subnetmod_init) return 1;
+       else if(fptr == &subnetmod_setup) return 1;
 #endif
 #ifdef USE_IPSET
-       else if(fptr == &ipset_init) return 1;
+       else if(fptr == &ipset_setup) return 1;
 #endif
        return 0;
 }
 
 int 
-fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
+fptr_whitelist_mod_desetup(void (*fptr)(struct module_env* env, int id))
 {
-       if(fptr == &iter_deinit) return 1;
-       else if(fptr == &val_deinit) return 1;
-       else if(fptr == &dns64_deinit) return 1;
-       else if(fptr == &respip_deinit) return 1;
+       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_deinit) return 1;
+       else if(fptr == &pythonmod_desetup) return 1;
 #endif
 #ifdef USE_CACHEDB
-       else if(fptr == &cachedb_deinit) return 1;
+       else if(fptr == &cachedb_desetup) return 1;
 #endif
 #ifdef USE_IPSECMOD
-       else if(fptr == &ipsecmod_deinit) return 1;
+       else if(fptr == &ipsecmod_desetup) return 1;
 #endif
 #ifdef CLIENT_SUBNET
-       else if(fptr == &subnetmod_deinit) return 1;
+       else if(fptr == &subnetmod_desetup) return 1;
 #endif
 #ifdef USE_IPSET
-       else if(fptr == &ipset_deinit) return 1;
+       else if(fptr == &ipset_desetup) return 1;
 #endif
        return 0;
 }
index cd331febb0701a7bdbe515620228ff5ce5222880..3f74fc8b041dc4f82990a9e85f5e77b8460853b6 100644 (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));
 
 /**
- * Check function pointer whitelist for module deinit call values.
+ * Check function pointer whitelist for module setup call values.
  *
  * @param fptr: function pointer to check.
  * @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.
index f16583183bfef8ffaae8972c35e5b134ebd4fe2f..a94b0fffa671a100d1f8c25f035bb18f38f717ba 100644 (file)
@@ -246,3 +246,8 @@ copy_state_to_super(struct module_qstate* qstate, int ATTR_UNUSED(id),
                super->was_ratelimited = qstate->was_ratelimited;
        }
 }
+
+int module_dummy_init(struct module_env* env, int id)
+{
+       return 1;
+}
index fa89c647e3700085c32053d28080294f13f64dfe..e7b1f33e59c6baadb28259fca576c5e1b1b65f9b 100644 (file)
@@ -672,21 +672,40 @@ struct module_func_block {
        /** text string name of module */
        const char* name;
 
-       /** 
-        * init the module. Called once for the global state.
+       /**
+        * initialise the module. This is called only once at startup.
+        * Privileged operations like opening device files may be done here.
+        * @param id: module id number.
+        * return: 0 on error
+        */
+       int (*init)(struct module_env* env, int id);
+
+       /**
+        * 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 (*init)(struct module_env* env, int id);
+       int (*setup)(struct module_env* env, int id);
 
        /**
-        * de-init, delete, the module. Called once for the global state.
+        * de-setup, undo stuff done during setup().
+        * Called before reloading the daemon.
         * @param env: module environment.
         * @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.
@@ -858,4 +877,6 @@ void log_edns_known_options(enum verbosity_value level,
 void copy_state_to_super(struct module_qstate* qstate, int id,
        struct module_qstate* super);
 
+int module_dummy_init(struct module_env* env, int id);
+
 #endif /* UTIL_MODULE_H */
index c3ca0a27da83ddcbda414f1b22246f06eaec26d5..fa5fe4c0eaa8ceb8e59dd4f5904568c9a865f33b 100644 (file)
@@ -165,7 +165,7 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env,
 void ecdsa_evp_workaround_init(void);
 #endif
 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,
                sizeof(struct val_env));
@@ -190,7 +190,7 @@ val_init(struct module_env* env, int id)
 }
 
 void
-val_deinit(struct module_env* env, int id)
+val_desetup(struct module_env* env, int id)
 {
        struct val_env* val_env;
        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 = {
        "validator",
-       &val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear,
-       &val_get_mem
+       &module_dummy_init, &module_dummy_init, &val_setup, &val_desetup,
+       &val_operate, &val_inform_super, &val_clear, &val_get_mem
 };
 
 struct module_func_block* 
index 9e4c8a9414a15a6ae128cc7a1678dc3fabc9215d..caa18d7fdeec1608062e284b0ceabc3aa77c8c49 100644 (file)
@@ -254,10 +254,10 @@ struct module_func_block* val_get_funcblock(void);
 const char* val_state_to_string(enum val_state state);
 
 /** validator init */
-int val_init(struct module_env* env, int id);
+int val_setup(struct module_env* env, int id);
 
 /** 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 */
 void val_operate(struct module_qstate* qstate, enum module_ev event, int id,