mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-26 16:42:54 -05:00
further mesh.
git-svn-id: file:///svn/unbound/trunk@419 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
fcd489a12a
commit
e939a7689f
5 changed files with 133 additions and 35 deletions
|
|
@ -54,6 +54,7 @@
|
|||
#include "services/outside_network.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/mesh.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgencode.h"
|
||||
|
||||
|
|
@ -734,7 +735,6 @@ reqs_init(struct worker* worker)
|
|||
sizeof(struct work_query));
|
||||
if(!q) return 0;
|
||||
q->state.buf = worker->front->udp_buff;
|
||||
q->state.scratch = worker->scratchpad;
|
||||
q->state.region = region_create_custom(malloc, free, 1024,
|
||||
64, 16, 0);
|
||||
if(!q->state.region) {
|
||||
|
|
@ -869,6 +869,13 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
|||
worker->env.worker = worker;
|
||||
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);
|
||||
if(!worker->env.mesh) {
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -884,6 +891,7 @@ worker_delete(struct worker* worker)
|
|||
if(!worker)
|
||||
return;
|
||||
server_stats_log(&worker->stats, worker->thread_num);
|
||||
mesh_delete(worker->env.mesh);
|
||||
reqs_delete(worker);
|
||||
qstate_free_recurs_list(worker, worker->slumber_list);
|
||||
listen_delete(worker->front);
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ iter_handlereply(struct module_qstate* qstate, int id,
|
|||
struct edns_data reply_edns;
|
||||
int r;
|
||||
if((r=reply_info_parse(qstate->reply->c->buffer, env->alloc,
|
||||
&reply_qinfo, &reply_msg, qstate->scratch,
|
||||
&reply_qinfo, &reply_msg, qstate->env->scratch,
|
||||
&reply_edns))!=0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ iter_handlereply(struct module_qstate* qstate, int id,
|
|||
qstate->edns.bits &= EDNS_DO;
|
||||
if(!reply_info_answer_encode(&reply_qinfo, reply_msg, 0,
|
||||
qstate->query_flags, qstate->buf, 0, 0,
|
||||
qstate->scratch, us, &qstate->edns,
|
||||
qstate->env->scratch, us, &qstate->edns,
|
||||
(int)(qstate->edns.bits&EDNS_DO)))
|
||||
return 0;
|
||||
dns_cache_store_msg(qstate->env, &reply_qinfo, qstate->query_hash,
|
||||
|
|
@ -345,7 +345,7 @@ iter_encode_respmsg(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
edns.ext_rcode = 0;
|
||||
edns.bits = qstate->edns.bits & EDNS_DO;
|
||||
if(!reply_info_answer_encode(&qinf, msg->rep, 0, iq->orig_qflags,
|
||||
qstate->buf, 0, 1, qstate->scratch, qstate->edns.udp_size,
|
||||
qstate->buf, 0, 1, qstate->env->scratch, qstate->edns.udp_size,
|
||||
&edns, (int)(qstate->edns.bits & EDNS_DO))) {
|
||||
/* encode servfail */
|
||||
error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
|
|
@ -473,7 +473,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
|||
subq->query_flags = 0; /* OPCODE QUERY, no flags */
|
||||
subq->edns.udp_size = 65535;
|
||||
subq->buf = qstate->buf;
|
||||
subq->scratch = qstate->scratch;
|
||||
subq->env->scratch = qstate->env->scratch;
|
||||
subq->region = region_create(malloc, free);
|
||||
if(!subq->region) {
|
||||
free(subq->qinfo.qname);
|
||||
|
|
@ -673,7 +673,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
|
||||
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len, qstate->qinfo.qtype,
|
||||
qstate->qinfo.qclass, qstate->region, qstate->scratch);
|
||||
qstate->qinfo.qclass, qstate->region, qstate->env->scratch);
|
||||
if(msg) {
|
||||
/* handle positive cache response */
|
||||
enum response_type type = response_type_from_cache(msg,
|
||||
|
|
@ -1536,7 +1536,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
}
|
||||
|
||||
/* parse message */
|
||||
prs = (struct msg_parse*)region_alloc(qstate->scratch,
|
||||
prs = (struct msg_parse*)region_alloc(qstate->env->scratch,
|
||||
sizeof(struct msg_parse));
|
||||
if(!prs) {
|
||||
log_err("out of memory on incoming message");
|
||||
|
|
@ -1547,7 +1547,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
memset(&edns, 0, sizeof(edns));
|
||||
pkt = qstate->reply->c->buffer;
|
||||
ldns_buffer_set_position(pkt, 0);
|
||||
if(parse_packet(pkt, prs, qstate->scratch) != LDNS_RCODE_NOERROR) {
|
||||
if(parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) {
|
||||
verbose(VERB_ALGO, "parse error on reply packet");
|
||||
goto handle_it;
|
||||
}
|
||||
|
|
@ -1557,7 +1557,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
|
||||
/* normalize and sanitize: easy to delete items from linked lists */
|
||||
if(!scrub_message(pkt, prs, &qstate->qinfo, iq->dp->name,
|
||||
qstate->scratch))
|
||||
qstate->env->scratch))
|
||||
goto handle_it;
|
||||
|
||||
/* allocate response dns_msg in region */
|
||||
|
|
|
|||
|
|
@ -61,12 +61,12 @@ mesh_state_compare(const void* ap, const void* bp)
|
|||
if(!a->is_priming && b->is_priming)
|
||||
return 1;
|
||||
|
||||
if((a->state->query_flags&BIT_RD) && !(b->state->query_flags&BIT_RD))
|
||||
if((a->s.query_flags&BIT_RD) && !(b->s.query_flags&BIT_RD))
|
||||
return -1;
|
||||
if(!(a->state->query_flags&BIT_RD) && (b->state->query_flags&BIT_RD))
|
||||
if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD))
|
||||
return 1;
|
||||
|
||||
return query_info_compare(&a->state->qinfo, &b->state->qinfo);
|
||||
return query_info_compare(&a->s.qinfo, &b->s.qinfo);
|
||||
}
|
||||
|
||||
/** compare two mesh references */
|
||||
|
|
@ -79,14 +79,15 @@ mesh_state_ref_compare(const void* ap, const void* bp)
|
|||
}
|
||||
|
||||
struct mesh_area*
|
||||
mesh_create(struct worker* worker)
|
||||
mesh_create(int num_modules, struct module_func_block** modfunc)
|
||||
{
|
||||
struct mesh_area* mesh = calloc(1, sizeof(struct mesh_area));
|
||||
if(!mesh) {
|
||||
log_err("mesh area alloc: out of memory");
|
||||
return NULL;
|
||||
}
|
||||
mesh->worker = worker;
|
||||
mesh->num_modules = num_modules;
|
||||
mesh->modfunc = modfunc;
|
||||
rbtree_init(&mesh->run, &mesh_state_compare);
|
||||
rbtree_init(&mesh->all, &mesh_state_compare);
|
||||
mesh->num_reply_addrs = 0;
|
||||
|
|
@ -98,8 +99,77 @@ mesh_create(struct worker* worker)
|
|||
void
|
||||
mesh_delete(struct mesh_area* mesh)
|
||||
{
|
||||
struct mesh_state* mstate;
|
||||
if(!mesh)
|
||||
return;
|
||||
/* free all query states */
|
||||
RBTREE_FOR(mstate, struct mesh_state*, &mesh->all) {
|
||||
mesh_state_cleanup(mstate);
|
||||
}
|
||||
free(mesh);
|
||||
}
|
||||
|
||||
struct mesh_state*
|
||||
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime)
|
||||
{
|
||||
region_type* region = region_create(malloc, free);
|
||||
struct mesh_state* mstate;
|
||||
int i;
|
||||
if(!region)
|
||||
return NULL;
|
||||
mstate = (struct mesh_state*)region_alloc(region,
|
||||
sizeof(struct mesh_state));
|
||||
if(!mstate) {
|
||||
region_destroy(region);
|
||||
return NULL;
|
||||
}
|
||||
mstate->node = *RBTREE_NULL;
|
||||
mstate->run_node = *RBTREE_NULL;
|
||||
mstate->node.key = mstate;
|
||||
mstate->run_node.key = mstate;
|
||||
mstate->is_priming = prime;
|
||||
mstate->reply_list = NULL;
|
||||
rbtree_init(&mstate->super_set, &mesh_state_ref_compare);
|
||||
rbtree_init(&mstate->sub_set, &mesh_state_ref_compare);
|
||||
/* init module qstate */
|
||||
mstate->s.qinfo.qtype = qinfo->qtype;
|
||||
mstate->s.qinfo.qclass = qinfo->qclass;
|
||||
mstate->s.qinfo.qname_len = qinfo->qname_len;
|
||||
mstate->s.qinfo.qname = region_alloc_init(region, qinfo->qname,
|
||||
qinfo->qname_len);
|
||||
if(!mstate->s.qinfo.qname) {
|
||||
region_destroy(region);
|
||||
return NULL;
|
||||
}
|
||||
/* remove all weird bits from qflags */
|
||||
mstate->s.query_flags = (qflags & BIT_RD);
|
||||
mstate->s.reply = NULL;
|
||||
mstate->s.region = region;
|
||||
mstate->s.curmod = 0;
|
||||
mstate->s.env = env;
|
||||
mstate->s.mesh_info = mstate;
|
||||
/* init modules */
|
||||
for(i=0; i<env->mesh->num_modules; i++) {
|
||||
mstate->s.minfo[i] = NULL;
|
||||
mstate->s.ext_state[i] = module_state_initial;
|
||||
}
|
||||
return mstate;
|
||||
}
|
||||
|
||||
void
|
||||
mesh_state_cleanup(struct mesh_state* mstate)
|
||||
{
|
||||
struct mesh_area* mesh;
|
||||
int i;
|
||||
if(!mstate)
|
||||
return;
|
||||
/* de-init modules */
|
||||
mesh = mstate->s.env->mesh;
|
||||
for(i=0; i<mesh->num_modules; i++) {
|
||||
(*mesh->modfunc[i]->clear)(&mstate->s, i);
|
||||
mstate->s.minfo[i] = NULL;
|
||||
mstate->s.ext_state[i] = module_finished;
|
||||
}
|
||||
region_destroy(mstate->s.region);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,9 @@
|
|||
#include "util/rbtree.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/data/msgparse.h"
|
||||
struct module_qstate;
|
||||
#include "util/module.h"
|
||||
struct mesh_state;
|
||||
struct mesh_reply;
|
||||
struct worker;
|
||||
struct query_info;
|
||||
struct reply_info;
|
||||
struct outbound_entry;
|
||||
|
|
@ -61,8 +60,11 @@ struct outbound_entry;
|
|||
* Mesh of query states
|
||||
*/
|
||||
struct mesh_area {
|
||||
/** what worker this is a part of */
|
||||
struct worker* worker;
|
||||
/** the number of modules */
|
||||
int num_modules;
|
||||
/** the module callbacks, array of num_modules length (ref only) */
|
||||
struct module_func_block** modfunc;
|
||||
|
||||
/** set of runnable queries (mesh_state.run_node) */
|
||||
rbtree_t run;
|
||||
/** rbtree of all current queries (mesh_state.node)*/
|
||||
|
|
@ -90,7 +92,7 @@ struct mesh_area {
|
|||
* region. All parts (rbtree nodes etc) are also allocated in the region.
|
||||
*/
|
||||
struct mesh_state {
|
||||
/** node in mesh_area all tree, key is this struct */
|
||||
/** node in mesh_area all tree, key is this struct. Must be first. */
|
||||
rbnode_t node;
|
||||
/** node in mesh_area runnable tree, key is this struct */
|
||||
rbnode_t run_node;
|
||||
|
|
@ -98,7 +100,7 @@ struct mesh_state {
|
|||
int is_priming;
|
||||
/** the query state. Note that the qinfo and query_flags
|
||||
* may not change. */
|
||||
struct module_qstate* state;
|
||||
struct module_qstate s;
|
||||
/** the list of replies to clients for the results */
|
||||
struct mesh_reply* reply_list;
|
||||
/** set of superstates (that want this state's result)
|
||||
|
|
@ -142,10 +144,13 @@ struct mesh_reply {
|
|||
|
||||
/**
|
||||
* Allocate mesh, to empty.
|
||||
* @param worker: what worker it is part of.
|
||||
* @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.
|
||||
* @return mesh: the new mesh or NULL on error.
|
||||
*/
|
||||
struct mesh_area* mesh_create(struct worker* worker);
|
||||
struct mesh_area* mesh_create(int num_modules,
|
||||
struct module_func_block** modfunc);
|
||||
|
||||
/**
|
||||
* Delete mesh, and all query states and replies in it.
|
||||
|
|
@ -253,11 +258,22 @@ void mesh_walk_supers(struct module_qstate* qstate, int id, int rcode,
|
|||
|
||||
/**
|
||||
* Create and initialize a new mesh state and its query state
|
||||
* Does not put the mesh state into rbtrees and so on.
|
||||
* @param env: module environment to set.
|
||||
* @param qinfo: query info that the mesh is for.
|
||||
* @param qflags: flags for query (RD flag).
|
||||
* @param prime: if true, it is a priming query, set is_priming on mesh state.
|
||||
* @return: new mesh state or NULL on allocation error.
|
||||
*/
|
||||
struct mesh_state* mesh_state_create(struct module_env* env,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime);
|
||||
|
||||
/**
|
||||
* Cleanup a mesh state and its query state. Does not do rbtree or
|
||||
* reference cleanup.
|
||||
* @param mstate: mesh state to cleanup. Its pointer may no longer be used
|
||||
* afterwards. Cleanup rbtrees before calling this function.
|
||||
*/
|
||||
void mesh_state_cleanup(struct mesh_state* mstate);
|
||||
|
||||
#endif /* SERVICES_MESH_H */
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ struct region;
|
|||
struct worker;
|
||||
struct module_qstate;
|
||||
struct ub_randstate;
|
||||
struct mesh_area;
|
||||
struct mesh_state;
|
||||
|
||||
/** Maximum number of modules in operation */
|
||||
#define MAX_MODULE 2
|
||||
|
|
@ -127,8 +129,12 @@ struct module_env {
|
|||
*/
|
||||
void (*remove_subqueries)(struct module_qstate* qstate);
|
||||
|
||||
/** region for temporary usage. May be cleared after operate() call. */
|
||||
struct region* scratch;
|
||||
/** internal data for daemon - worker thread. */
|
||||
struct worker* worker;
|
||||
/** mesh area with query state dependencies */
|
||||
struct mesh_area* mesh;
|
||||
/** allocation service */
|
||||
struct alloc_cache* alloc;
|
||||
/** random table to generate random numbers */
|
||||
|
|
@ -185,20 +191,11 @@ enum module_ev {
|
|||
struct module_qstate {
|
||||
/** which query is being answered: name, type, class */
|
||||
struct query_info qinfo;
|
||||
/** hash value of the query qinfo */
|
||||
hashvalue_t query_hash;
|
||||
/** flags uint16 from query */
|
||||
uint16_t query_flags;
|
||||
/** edns data from the query */
|
||||
struct edns_data edns;
|
||||
|
||||
/** buffer, store resulting reply here.
|
||||
* May be cleared when module blocks. */
|
||||
ldns_buffer* buf;
|
||||
/** comm_reply contains server replies */
|
||||
struct comm_reply* reply;
|
||||
/** region for temporary usage. May be cleared when module blocks. */
|
||||
struct region* scratch;
|
||||
/** region for this query. Cleared when query process finishes. */
|
||||
struct region* region;
|
||||
|
||||
|
|
@ -210,15 +207,22 @@ struct module_qstate {
|
|||
void* minfo[MAX_MODULE];
|
||||
/** environment for this query */
|
||||
struct module_env* env;
|
||||
/** worker related state for this query. NULL for (sub)queries that do
|
||||
* not need to have answers sent to a client. */
|
||||
struct work_query* work_info;
|
||||
/** mesh related information for this query */
|
||||
struct mesh_state* mesh_info;
|
||||
|
||||
/** ----- TO DELETE */
|
||||
struct work_query* work_info;
|
||||
/** hash value of the query qinfo */
|
||||
hashvalue_t query_hash;
|
||||
/** edns data from the query */
|
||||
struct edns_data edns;
|
||||
/** buffer, store resulting reply here.
|
||||
* May be cleared when module blocks. */
|
||||
ldns_buffer* buf;
|
||||
/** parent query, only nonNULL for subqueries */
|
||||
struct module_qstate* parent;
|
||||
/** pointer to first subquery below this one; makes list with next */
|
||||
struct module_qstate* subquery_first;
|
||||
|
||||
/** pointer to next sibling subquery (not above or below this one) */
|
||||
struct module_qstate* subquery_next;
|
||||
/** pointer to prev sibling subquery (not above or below this one) */
|
||||
|
|
|
|||
Loading…
Reference in a new issue