#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),
{
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;
+}
#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. */
{
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;
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);
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);
#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
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);
}
#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,
return 1;
}
-/** iterator deinit */
-static void
+void
iter_deinit(struct module_env* env, int id)
{
struct iter_env* iter_env;
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;
}
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;
}
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 */
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,
/* 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);
*/
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");
*/
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");
return 0;
}
-/**
+/*
* Return priming query results to interestes super querystates.
*
* Sets the delegation point and delegation message (not nonRD queries).
* @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)
{
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)
{
(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;
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)
#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;
*/
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 */
#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)
/* 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;
/* 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);
}
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);
#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"
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;
+}
#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.
*/
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 */
#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
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,
return 1;
}
-/** validator deinit */
-static void
+void
val_deinit(struct module_env* env, int id)
{
struct val_env* val_env;
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");
}
}
-/** validator operate on a query */
-static void
+void
val_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
/* 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)
{
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)
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];
#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;
*/
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 */