From: Wouter Wijngaards Date: Tue, 4 Dec 2007 13:23:41 +0000 (+0000) Subject: makefile nit and modstack. X-Git-Tag: release-0.9~135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8892d4b63c73206e7f210e0f525c44c5a902e202;p=thirdparty%2Funbound.git makefile nit and modstack. git-svn-id: file:///svn/unbound/trunk@801 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/Makefile.in b/Makefile.in index 3d6ad04fa..311446b75 100644 --- a/Makefile.in +++ b/Makefile.in @@ -138,7 +138,7 @@ unbound-checkconf: $(CHECKCONF_OBJ) $(ldnslib) $(INFO) Link $@ $Q$(LINK) -o $@ $(sort $(CHECKCONF_OBJ)) $(LIBS) -unbound-host: $(HOST_OBJ) lib +unbound-host: $(HOST_OBJ) libunbound.la $(INFO) Link $@ $Q$(LINK) -o $@ $(sort $(HOST_OBJ)) -L. -L.libs -lunbound $(LIBS) diff --git a/daemon/daemon.c b/daemon/daemon.c index 43334d696..12785135a 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -51,10 +51,8 @@ #include "services/cache/rrset.h" #include "services/cache/infra.h" #include "services/localzone.h" +#include "services/modstack.h" #include "util/module.h" -#include "iterator/iterator.h" -#include "validator/validator.h" -#include "util/fptr_wlist.h" #include /** How many quit requests happened. */ @@ -129,7 +127,7 @@ daemon_init() checklock_start(); ERR_load_crypto_strings(); daemon->need_to_exit = 0; - daemon->num_modules = 0; + modstack_init(&daemon->mods); if(!(daemon->env = (struct module_env*)calloc(1, sizeof(*daemon->env)))) { free(daemon); @@ -158,136 +156,19 @@ daemon_open_shared_ports(struct daemon* daemon) return 1; } -/** count number of modules (words) in the string */ -static int -count_modules(const char* s) -{ - int num = 0; - if(!s) - return 0; - while(*s) { - /* skip whitespace */ - while(*s && isspace((int)*s)) - s++; - if(*s && !isspace((int)*s)) { - /* skip identifier */ - num++; - while(*s && !isspace((int)*s)) - s++; - } - } - return num; -} - -/** - * Get funcblock for module name - * @param str: string with module name. Advanced to next value on success. - * @return funcblock or NULL on error. - */ -static struct module_func_block* -daemon_module_factory(const char** str) -{ - /* these are the modules available */ - int num = 2; - const char* names[] = {"iterator", "validator", NULL}; - struct module_func_block* (*fb[])(void) = - {&iter_get_funcblock, &val_get_funcblock, NULL}; - - int i; - const char* s = *str; - while(*s && isspace((int)*s)) - s++; - for(i=0; icfg->module_conf; - int i; - verbose(VERB_DETAIL, "module config: \"%s\"", str); - daemon->num_modules = count_modules(str); - if(daemon->num_modules == 0) { - log_err("error: no modules specified"); - return 0; - } - if(daemon->num_modules > MAX_MODULE) { - log_err("error: too many modules (%d max %d)", - daemon->num_modules, MAX_MODULE); - return 0; - } - daemon->modfunc = (struct module_func_block**)calloc((size_t) - daemon->num_modules, sizeof(struct module_func_block*)); - if(!daemon->modfunc) { - log_err("out of memory"); - return 0; - } - for(i=0; inum_modules; i++) { - daemon->modfunc[i] = daemon_module_factory(&str); - if(!daemon->modfunc[i]) { - log_err("Unknown value for first module in: '%s'", - str); - return 0; - } - } - return 1; -} - -/** - * Desetup the modules, deinit, delete. - * @param daemon: the daemon. - */ -static void -daemon_desetup_modules(struct daemon* daemon) -{ - int i; - for(i=0; inum_modules; i++) { - log_assert(fptr_whitelist_mod_deinit( - daemon->modfunc[i]->deinit)); - (*daemon->modfunc[i]->deinit)(daemon->env, i); - } - daemon->num_modules = 0; - free(daemon->modfunc); - daemon->modfunc = 0; -} - /** - * Setup modules. Assigns ids and calls module_init. + * Setup modules. setup module stack. * @param daemon: the daemon */ static void daemon_setup_modules(struct daemon* daemon) { - int i; - if(daemon->num_modules != 0) - daemon_desetup_modules(daemon); - /* fixed setup of the modules */ - if(!daemon_config_modules(daemon)) { - fatal_exit("failed to setup modules"); - } 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 */ - for(i=0; inum_modules; i++) { - verbose(VERB_OPS, "init module %d: %s", - i, daemon->modfunc[i]->name); - log_assert(fptr_whitelist_mod_init(daemon->modfunc[i]->init)); - if(!(*daemon->modfunc[i]->init)(daemon->env, i)) { - fatal_exit("module init for module %s failed", - daemon->modfunc[i]->name); - } + if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf, + daemon->env)) { + fatal_exit("failed to setup modules"); } } @@ -475,7 +356,7 @@ daemon_delete(struct daemon* daemon) { if(!daemon) return; - daemon_desetup_modules(daemon); + modstack_desetup(&daemon->mods, daemon->env); listening_ports_free(daemon->ports); if(daemon->env) { slabhash_delete(daemon->env->msg_cache); diff --git a/daemon/daemon.h b/daemon/daemon.h index 37bc219b5..d8db511cf 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -44,6 +44,7 @@ #include "util/locks.h" #include "util/alloc.h" +#include "services/modstack.h" struct config_file; struct worker; struct listen_port; @@ -76,10 +77,8 @@ struct daemon { struct alloc_cache superalloc; /** the module environment master value, copied and changed by threads*/ struct module_env* env; - /** number of modules active, ids from 0 to num-1. */ - int num_modules; - /** the module callbacks, array of num_modules length */ - struct module_func_block** modfunc; + /** stack of module callbacks */ + struct module_stack mods; /** access control, which client IPs are allowed to connect */ struct acl_list* acl; /** local authority zones */ diff --git a/daemon/worker.c b/daemon/worker.c index 977c111f0..6f6ee2ac6 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -967,8 +967,7 @@ worker_init(struct worker* worker, struct config_file *cfg, worker->env.alloc = &worker->alloc; worker->env.rnd = worker->rndstate; worker->env.scratch = worker->scratchpad; - worker->env.mesh = mesh_create(worker->daemon->num_modules, - worker->daemon->modfunc, &worker->env); + worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env); worker->env.detach_subs = &mesh_detach_subs; worker->env.attach_sub = &mesh_attach_sub; worker->env.kill_sub = &mesh_state_delete; diff --git a/doc/Changelog b/doc/Changelog index bc983b7e8..dc4f349d7 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,8 @@ +4 December 2007: Wouter + - minor Makefile fixup. + - moved module-stack code out of daemon/daemon into services/modstack, + preparing for code-reuse. + 3 December 2007: Wouter - changed checkconf/ to smallapp/ to make room for more support tools. (such as unbound-host). diff --git a/services/mesh.c b/services/mesh.c index 22f951e88..f8ae1161d 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -88,8 +88,7 @@ mesh_state_ref_compare(const void* ap, const void* bp) } struct mesh_area* -mesh_create(int num_modules, struct module_func_block** modfunc, - struct module_env* env) +mesh_create(struct module_stack* stack, struct module_env* env) { struct mesh_area* mesh = calloc(1, sizeof(struct mesh_area)); if(!mesh) { @@ -102,8 +101,7 @@ mesh_create(int num_modules, struct module_func_block** modfunc, log_err("mesh area alloc: out of memory"); return NULL; } - mesh->num_modules = num_modules; - mesh->modfunc = modfunc; + mesh->mods = *stack; mesh->env = env; rbtree_init(&mesh->run, &mesh_state_compare); rbtree_init(&mesh->all, &mesh_state_compare); @@ -237,7 +235,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo, mstate->s.env = env; mstate->s.mesh_info = mstate; /* init modules */ - for(i=0; imesh->num_modules; i++) { + for(i=0; imesh->mods.num; i++) { mstate->s.minfo[i] = NULL; mstate->s.ext_state[i] = module_state_initial; } @@ -253,9 +251,9 @@ mesh_state_cleanup(struct mesh_state* mstate) return; /* de-init modules */ mesh = mstate->s.env->mesh; - for(i=0; inum_modules; i++) { - log_assert(fptr_whitelist_mod_clear(mesh->modfunc[i]->clear)); - (*mesh->modfunc[i]->clear)(&mstate->s, i); + for(i=0; imods.num; i++) { + log_assert(fptr_whitelist_mod_clear(mesh->mods.mod[i]->clear)); + (*mesh->mods.mod[i]->clear)(&mstate->s, i); mstate->s.minfo[i] = NULL; mstate->s.ext_state[i] = module_finished; } @@ -493,8 +491,8 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate) (void)rbtree_insert(&mesh->run, &ref->s->run_node); /* callback the function to inform super of result */ log_assert(fptr_whitelist_mod_inform_super( - mesh->modfunc[ref->s->s.curmod]->inform_super)); - (*mesh->modfunc[ref->s->s.curmod]->inform_super)(&mstate->s, + mesh->mods.mod[ref->s->s.curmod]->inform_super)); + (*mesh->mods.mod[ref->s->s.curmod]->inform_super)(&mstate->s, ref->s->s.curmod, &ref->s->s); } } @@ -565,7 +563,7 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate, if(s == module_wait_module) { /* start next module */ mstate->s.curmod++; - if(mesh->num_modules == mstate->s.curmod) { + if(mesh->mods.num == mstate->s.curmod) { log_err("Cannot pass to next module; at last module"); log_query_info(VERB_DETAIL, "pass error for qstate", &mstate->s.qinfo); @@ -602,8 +600,8 @@ void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate, while(mstate) { /* run the module */ log_assert(fptr_whitelist_mod_operate( - mesh->modfunc[mstate->s.curmod]->operate)); - (*mesh->modfunc[mstate->s.curmod]->operate) + mesh->mods.mod[mstate->s.curmod]->operate)); + (*mesh->mods.mod[mstate->s.curmod]->operate) (&mstate->s, ev, mstate->s.curmod, e); /* examine results */ @@ -611,7 +609,7 @@ void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate, regional_free_all(mstate->s.env->scratch); s = mstate->s.ext_state[mstate->s.curmod]; verbose(VERB_ALGO, "mesh_run: %s module exit state is %s", - mesh->modfunc[mstate->s.curmod]->name, strextstate(s)); + mesh->mods.mod[mstate->s.curmod]->name, strextstate(s)); e = NULL; if(mesh_continue(mesh, mstate, s, &ev)) continue; diff --git a/services/mesh.h b/services/mesh.h index 57001ed47..7ba98732f 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -50,6 +50,7 @@ #include "util/netevent.h" #include "util/data/msgparse.h" #include "util/module.h" +#include "services/modstack.h" struct mesh_state; struct mesh_reply; struct query_info; @@ -67,10 +68,8 @@ struct timehist; * Mesh of query states */ struct mesh_area { - /** the number of modules */ - int num_modules; - /** the module callbacks, array of num_modules length (ref only) */ - struct module_func_block** modfunc; + /** active module stack */ + struct module_stack mods; /** environment for new states */ struct module_env* env; @@ -160,14 +159,12 @@ struct mesh_reply { /** * Allocate mesh, to empty. - * @param num_modules: number of modules that are present. - * @param modfunc: array passed (alloced and deleted by caller), that has - * num_modules function callbacks for the modules. + * @param stack: module stack to activate, copied (as readonly reference). * @param env: environment for new queries. * @return mesh: the new mesh or NULL on error. */ -struct mesh_area* mesh_create(int num_modules, - struct module_func_block** modfunc, struct module_env* env); +struct mesh_area* mesh_create(struct module_stack* stack, + struct module_env* env); /** * Delete mesh, and all query states and replies in it. diff --git a/services/modstack.c b/services/modstack.c new file mode 100644 index 000000000..0040c3d9e --- /dev/null +++ b/services/modstack.c @@ -0,0 +1,167 @@ +/* + * services/modstack.c - stack of modules + * + * Copyright (c) 2007, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains functions to help maintain a stack of modules. + */ +#include "config.h" +#include "services/modstack.h" +#include "util/module.h" +#include "util/fptr_wlist.h" +#include "iterator/iterator.h" +#include "validator/validator.h" + +/** count number of modules (words) in the string */ +static int +count_modules(const char* s) +{ + int num = 0; + if(!s) + return 0; + while(*s) { + /* skip whitespace */ + while(*s && isspace((int)*s)) + s++; + if(*s && !isspace((int)*s)) { + /* skip identifier */ + num++; + while(*s && !isspace((int)*s)) + s++; + } + } + return num; +} + +void +modstack_init(struct module_stack* stack) +{ + stack->num = 0; + stack->mod = NULL; +} + +int +modstack_config(struct module_stack* stack, const char* module_conf) +{ + int i; + verbose(VERB_DETAIL, "module config: \"%s\"", module_conf); + stack->num = count_modules(module_conf); + if(stack->num == 0) { + log_err("error: no modules specified"); + return 0; + } + if(stack->num > MAX_MODULE) { + log_err("error: too many modules (%d max %d)", + stack->num, MAX_MODULE); + return 0; + } + stack->mod = (struct module_func_block**)calloc((size_t) + stack->num, sizeof(struct module_func_block*)); + if(!stack->mod) { + log_err("out of memory"); + return 0; + } + for(i=0; inum; i++) { + stack->mod[i] = module_factory(&module_conf); + if(!stack->mod[i]) { + log_err("Unknown value for next module: '%s'", + module_conf); + return 0; + } + } + return 1; +} + +struct +module_func_block* module_factory(const char** str) +{ + /* these are the modules available */ + int num = 2; + const char* names[] = {"iterator", "validator", NULL}; + struct module_func_block* (*fb[])(void) = + {&iter_get_funcblock, &val_get_funcblock, NULL}; + + int i; + const char* s = *str; + while(*s && isspace((int)*s)) + s++; + for(i=0; inum != 0) + modstack_desetup(stack, env); + /* 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; inum; i++) { + verbose(VERB_OPS, "init module %d: %s", + i, stack->mod[i]->name); + log_assert(fptr_whitelist_mod_init(stack->mod[i]->init)); + if(!(*stack->mod[i]->init)(env, i)) { + log_err("module init 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; inum; i++) { + log_assert(fptr_whitelist_mod_deinit(stack->mod[i]->deinit)); + (*stack->mod[i]->deinit)(env, i); + } + stack->num = 0; + free(stack->mod); + stack->mod = NULL; +} diff --git a/services/modstack.h b/services/modstack.h new file mode 100644 index 000000000..e76b4659e --- /dev/null +++ b/services/modstack.h @@ -0,0 +1,99 @@ +/* + * services/modstack.h - stack of modules + * + * Copyright (c) 2007, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This file contains functions to help maintain a stack of modules. + */ + +#ifndef SERVICES_MODSTACK_H +#define SERVICES_MODSTACK_H +struct module_func_block; +struct module_env; + +/** + * Stack of modules. + */ +struct module_stack { + /** the number of modules */ + int num; + /** the module callbacks, array of num_modules length (ref only) */ + struct module_func_block** mod; +}; + +/** + * Init a stack of modules + * @param stack: initialised as empty. + */ +void modstack_init(struct module_stack* stack); + +/** + * Read config file module settings and set up the modfunc block + * @param stack: the stack of modules (empty before call). + * @param module_conf: string what modules to insert. + * @return false on error + */ +int modstack_config(struct module_stack* stack, const char* module_conf); + +/** + * Get funcblock for module name + * @param str: string with module name. Advanced to next value on success. + * The string is assumed whitespace separated list of module names. + * @return funcblock or NULL on error. + */ +struct module_func_block* module_factory(const char** str); + +/** + * 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. + * @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. + */ +int modstack_setup(struct module_stack* stack, const char* module_conf, + struct module_env* env); + +/** + * Desetup the modules, deinit, delete. + * @param stack: made empty. + * @param env: module env for module deinit() calls. + */ +void modstack_desetup(struct module_stack* stack, struct module_env* env); + +#endif /* SERVICES_MODSTACK_H */