function pointer whitelist for module operations. completing fptr work.

git-svn-id: file:///svn/unbound/trunk@661 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-10-05 12:42:25 +00:00
parent 2a547a35a7
commit 8e55996b7c
11 changed files with 350 additions and 30 deletions

View file

@ -44,6 +44,7 @@
#include "util/log.h"
struct comm_reply;
struct comm_point;
struct module_qstate;
int worker_handle_control_cmd(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
@ -81,3 +82,22 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int worker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
struct module_qstate* ATTR_UNUSED(q), int ATTR_UNUSED(use_tcp))
{
log_assert(0);
return 0;
}
struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
return 0;
}

View file

@ -52,6 +52,7 @@
#include "util/module.h"
#include "iterator/iterator.h"
#include "validator/validator.h"
#include "util/fptr_wlist.h"
#include <signal.h>
/** How many quit requests happened. */
@ -243,6 +244,8 @@ daemon_desetup_modules(struct daemon* daemon)
{
int i;
for(i=0; i<daemon->num_modules; i++) {
log_assert(fptr_whitelist_mod_deinit(
daemon->modfunc[i]->deinit));
(*daemon->modfunc[i]->deinit)(daemon->env, i);
}
daemon->num_modules = 0;
@ -271,6 +274,7 @@ static void daemon_setup_modules(struct daemon* daemon)
daemon->env->need_to_validate = 0; /* set by module init below */
for(i=0; i<daemon->num_modules; i++) {
log_info("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);

View file

@ -134,6 +134,8 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
iter = 0;
val = 0;
for(i=0; i<worker->env.mesh->num_modules; i++) {
log_assert(fptr_whitelist_mod_get_mem(worker->env.mesh->
modfunc[i]->get_mem));
if(strcmp(worker->env.mesh->modfunc[i]->name, "validator")==0)
val += (*worker->env.mesh->modfunc[i]->get_mem)
(&worker->env, i);

View file

@ -57,6 +57,7 @@
#include "util/data/msgparse.h"
#include "util/data/dname.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
/** fillup fetch policy array */
static void
@ -297,6 +298,8 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
qinf.qname_len = namelen;
qinf.qtype = t;
qinf.qclass = c;
log_assert(fptr_whitelist_modenv_detect_cycle(
qstate->env->detect_cycle));
return (*qstate->env->detect_cycle)(qstate, &qinf,
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming);
}

View file

@ -57,9 +57,9 @@
#include "util/region-allocator.h"
#include "util/data/dname.h"
#include "util/data/msgencode.h"
#include "util/fptr_wlist.h"
/** iterator init */
static int
int
iter_init(struct module_env* env, int id)
{
struct iter_env* iter_env = (struct iter_env*)calloc(1,
@ -76,8 +76,7 @@ iter_init(struct module_env* env, int id)
return 1;
}
/** iterator deinit */
static void
void
iter_deinit(struct module_env* env, int id)
{
struct iter_env* iter_env;
@ -432,6 +431,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
qflags |= BIT_CD;
/* attach subquery, lookup existing or make a new one */
log_assert(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) {
return 0;
}
@ -444,6 +444,8 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
sizeof(struct iter_qstate));
if(!subq->minfo[id]) {
log_err("init subq: out of memory");
log_assert(fptr_whitelist_modenv_kill_sub(
qstate->env->kill_sub));
(*qstate->env->kill_sub)(subq);
return 0;
}
@ -560,6 +562,8 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
subiq->dp = delegpt_copy(stub_dp, subq->region);
if(!subiq->dp) {
log_err("out of memory priming stub, copydp");
log_assert(fptr_whitelist_modenv_kill_sub(
qstate->env->kill_sub));
(*qstate->env->kill_sub)(subq);
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return 1; /* return 1 to make module stop, with error */
@ -1131,6 +1135,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
log_query_info(VERB_DETAIL, "sending query:", &iq->qchase);
log_name_addr(VERB_DETAIL, "sending to target:", iq->dp->name,
&target->addr, target->addrlen);
log_assert(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(
iq->qchase.qname, iq->qchase.qname_len,
iq->qchase.qtype, iq->qchase.qclass,
@ -1189,6 +1194,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
log_assert(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
return final_state(iq);
@ -1221,6 +1228,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
*/
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
log_assert(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
verbose(VERB_ALGO, "cleared outbound list for next round");
@ -1258,6 +1267,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
*/
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
log_assert(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
verbose(VERB_ALGO, "cleared outbound list for query restart");
@ -1509,7 +1520,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
/**
/*
* Return priming query results to interestes super querystates.
*
* Sets the delegation point and delegation message (not nonRD queries).
@ -1519,7 +1530,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
* @param id: module id.
* @param super: the qstate to inform.
*/
static void
void
iter_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super)
{
@ -1666,8 +1677,7 @@ handle_it:
iter_handle(qstate, iq, ie, id);
}
/** iterator operate on a query */
static void
void
iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
@ -1710,8 +1720,7 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
/** iterator cleanup query state */
static void
void
iter_clear(struct module_qstate* qstate, int id)
{
struct iter_qstate* iq;
@ -1725,8 +1734,8 @@ iter_clear(struct module_qstate* qstate, int id)
qstate->minfo[id] = NULL;
}
/** iterator alloc size routine */
static size_t iter_get_mem(struct module_env* env, int id)
size_t
iter_get_mem(struct module_env* env, int id)
{
struct iter_env* ie = (struct iter_env*)env->modinfo[id];
if(!ie)

View file

@ -45,6 +45,8 @@
#include "services/outbound_list.h"
#include "util/data/msgreply.h"
struct module_func_block;
enum module_ev;
struct module_env;
struct delegpt;
struct iter_hints;
struct iter_forwards;
@ -273,4 +275,33 @@ 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);
/** iterator deinit */
void iter_deinit(struct module_env* env, int id);
/** iterator operate on a query */
void iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound);
/**
* Return priming query results to interestes super querystates.
*
* Sets the delegation point and delegation message (not nonRD queries).
* This is a callback from walk_supers.
*
* @param qstate: query state that finished.
* @param id: module id.
* @param super: the qstate to inform.
*/
void iter_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** iterator cleanup query state */
void iter_clear(struct module_qstate* qstate, int id);
/** iterator alloc size routine */
size_t iter_get_mem(struct module_env* env, int id);
#endif /* ITERATOR_ITERATOR_H */

View file

@ -52,6 +52,7 @@
#include "util/region-allocator.h"
#include "util/data/msgencode.h"
#include "util/timehist.h"
#include "util/fptr_wlist.h"
int
mesh_state_compare(const void* ap, const void* bp)
@ -252,6 +253,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
/* de-init modules */
mesh = mstate->s.env->mesh;
for(i=0; i<mesh->num_modules; i++) {
log_assert(fptr_whitelist_mod_clear(mesh->modfunc[i]->clear));
(*mesh->modfunc[i]->clear)(&mstate->s, i);
mstate->s.minfo[i] = NULL;
mstate->s.ext_state[i] = module_finished;
@ -489,6 +491,8 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
/* make super runnable */
(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,
ref->s->s.curmod, &ref->s->s);
}
@ -596,6 +600,8 @@ void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
verbose(VERB_ALGO, "mesh_run: start");
while(mstate) {
/* run the module */
log_assert(fptr_whitelist_mod_operate(
mesh->modfunc[mstate->s.curmod]->operate));
(*mesh->modfunc[mstate->s.curmod]->operate)
(&mstate->s, ev, mstate->s.curmod, e);

View file

@ -50,9 +50,11 @@
#include "services/outside_network.h"
#include "services/mesh.h"
#include "services/cache/infra.h"
#include "iterator/iterator.h"
#include "iterator/iter_donotq.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include "validator/validator.h"
#include "validator/val_anchor.h"
#include "validator/val_nsec3.h"
#include "validator/val_sigcrypt.h"
@ -204,3 +206,105 @@ fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_t fptr)
else if(fptr == &test_slabhash_deldata) return 1;
return 0;
}
int
fptr_whitelist_modenv_send_packet(int (*fptr)(ldns_buffer* pkt,
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
struct module_qstate* q, int use_tcp))
{
if(fptr == &worker_send_packet) return 1;
return 0;
}
int
fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
uint16_t flags, int dnssec, struct sockaddr_storage* addr,
socklen_t addrlen, struct module_qstate* q))
{
if(fptr == &worker_send_query) return 1;
return 0;
}
int
fptr_whitelist_modenv_detach_subs(void (*fptr)(
struct module_qstate* qstate))
{
if(fptr == &mesh_detach_subs) return 1;
return 0;
}
int
fptr_whitelist_modenv_attach_sub(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, struct module_qstate** newq))
{
if(fptr == &mesh_attach_sub) return 1;
return 0;
}
int
fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq))
{
if(fptr == &mesh_state_delete) return 1;
return 0;
}
int
fptr_whitelist_modenv_detect_cycle(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime))
{
if(fptr == &mesh_detect_cycle) return 1;
return 0;
}
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;
return 0;
}
int
fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
{
if(fptr == &iter_deinit) return 1;
else if(fptr == &val_deinit) return 1;
return 0;
}
int
fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
enum module_ev event, int id, struct outbound_entry* outbound))
{
if(fptr == &iter_operate) return 1;
else if(fptr == &val_operate) return 1;
return 0;
}
int
fptr_whitelist_mod_inform_super(void (*fptr)(
struct module_qstate* qstate, int id, struct module_qstate* super))
{
if(fptr == &iter_inform_super) return 1;
else if(fptr == &val_inform_super) return 1;
return 0;
}
int
fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
int id))
{
if(fptr == &iter_clear) return 1;
else if(fptr == &val_clear) return 1;
return 0;
}
int
fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id))
{
if(fptr == &iter_get_mem) return 1;
return 0;
}

View file

@ -56,6 +56,11 @@
#define UTIL_FPTR_WLIST_H
#include "util/netevent.h"
#include "util/storage/lruhash.h"
struct module_qstate;
struct module_env;
enum module_ev;
struct outbound_entry;
struct query_info;
/**
* Check function pointer whitelist for comm_point callback values.
@ -170,4 +175,113 @@ int fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_t fptr);
*/
int fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_t fptr);
/**
* Check function pointer whitelist for module_env send_packet callback values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_modenv_send_packet(int (*fptr)(ldns_buffer* pkt,
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
struct module_qstate* q, int use_tcp));
/**
* Check function pointer whitelist for module_env send_query callback values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
uint16_t flags, int dnssec, struct sockaddr_storage* addr,
socklen_t addrlen, struct module_qstate* q));
/**
* Check function pointer whitelist for module_env detach_subs callback values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_modenv_detach_subs(void (*fptr)(
struct module_qstate* qstate));
/**
* Check function pointer whitelist for module_env attach_sub callback values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_modenv_attach_sub(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t qflags, int prime, struct module_qstate** newq));
/**
* Check function pointer whitelist for module_env kill_sub callback values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq));
/**
* Check function pointer whitelist for module_env detect_cycle callback values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_modenv_detect_cycle(int (*fptr)(
struct module_qstate* qstate, struct query_info* qinfo,
uint16_t flags, int prime));
/**
* Check function pointer whitelist for module init call values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id));
/**
* Check function pointer whitelist for module deinit 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));
/**
* Check function pointer whitelist for module operate call values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
enum module_ev event, int id, struct outbound_entry* outbound));
/**
* Check function pointer whitelist for module inform_super call values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_mod_inform_super(void (*fptr)(
struct module_qstate* qstate, int id, struct module_qstate* super));
/**
* Check function pointer whitelist for module clear call values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
int id));
/**
* Check function pointer whitelist for module get_mem call values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id));
#endif /* UTIL_FPTR_WLIST_H */

View file

@ -54,6 +54,7 @@
#include "util/net_help.h"
#include "util/region-allocator.h"
#include "util/config_file.h"
#include "util/fptr_wlist.h"
/** fill up nsec3 key iterations config entry */
static int
@ -133,8 +134,7 @@ val_apply_cfg(struct val_env* val_env, struct config_file* cfg)
return 1;
}
/** validator init */
static int
int
val_init(struct module_env* env, int id)
{
struct val_env* val_env = (struct val_env*)calloc(1,
@ -153,8 +153,7 @@ val_init(struct module_env* env, int id)
return 1;
}
/** validator deinit */
static void
void
val_deinit(struct module_env* env, int id)
{
struct val_env* val_env;
@ -297,6 +296,7 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
ask.qtype = qtype;
ask.qclass = qclass;
log_query_info(VERB_ALGO, "generate request", &ask);
log_assert(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &ask,
(uint16_t)(BIT_RD|BIT_CD), 0, &newq)){
log_err("Could not generate request: out of memory");
@ -1579,8 +1579,7 @@ val_handle(struct module_qstate* qstate, struct val_qstate* vq,
}
}
/** validator operate on a query */
static void
void
val_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
@ -2026,14 +2025,14 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
/* the qstate will be reactivated after inform_super is done */
}
/**
/*
* inform validator super.
*
* @param qstate: query state that finished.
* @param id: module id.
* @param super: the qstate to inform.
*/
static void
void
val_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super)
{
@ -2063,8 +2062,7 @@ val_inform_super(struct module_qstate* qstate, int id,
log_err("internal error in validator: no inform_supers possible");
}
/** validator cleanup query state */
static void
void
val_clear(struct module_qstate* qstate, int id)
{
if(!qstate)
@ -2073,14 +2071,7 @@ val_clear(struct module_qstate* qstate, int id)
qstate->minfo[id] = NULL;
}
/**
* Debug helper routine that assists worker in determining memory in
* use.
* @param env: module environment
* @param id: module id.
* @return memory in use in bytes.
*/
static size_t
size_t
val_get_mem(struct module_env* env, int id)
{
struct val_env* ve = (struct val_env*)env->modinfo[id];

View file

@ -43,6 +43,10 @@
#ifndef VALIDATOR_VALIDATOR_H
#define VALIDATOR_VALIDATOR_H
struct module_func_block;
struct module_env;
enum module_ev;
struct outbound_entry;
struct module_qstate;
#include "util/data/msgreply.h"
#include "validator/val_utils.h"
struct val_anchors;
@ -202,4 +206,36 @@ struct module_func_block* val_get_funcblock();
*/
const char* val_state_to_string(enum val_state state);
/** validator init */
int val_init(struct module_env* env, int id);
/** validator deinit */
void val_deinit(struct module_env* env, int id);
/** validator operate on a query */
void val_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound);
/**
* inform validator super.
*
* @param qstate: query state that finished.
* @param id: module id.
* @param super: the qstate to inform.
*/
void val_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** validator cleanup query state */
void val_clear(struct module_qstate* qstate, int id);
/**
* Debug helper routine that assists worker in determining memory in
* use.
* @param env: module environment
* @param id: module id.
* @return memory in use in bytes.
*/
size_t val_get_mem(struct module_env* env, int id);
#endif /* VALIDATOR_VALIDATOR_H */