]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
further mesh.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 22 Jun 2007 12:39:08 +0000 (12:39 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 22 Jun 2007 12:39:08 +0000 (12:39 +0000)
git-svn-id: file:///svn/unbound/trunk@419 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
iterator/iterator.c
services/mesh.c
services/mesh.h
util/module.h

index 46c3e74fcadb99647d3080cab45f9c2679847032..c4683f72606e36a731419146866287544e8dc4ef 100644 (file)
@@ -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);
index 0c977b33731e6a042f2f78b2b345485cbbce43b7..ba11830ad4cd1d1a724937e633569eb8def48bfb 100644 (file)
@@ -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 */
index d285b34f32d834b6b95c7bf67387392e6b1a1f11..ef185f16236129f2628a02b896bb705b36dd338f 100644 (file)
@@ -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);
+}
index b0883b24fe6034dd95620f3a3d4e95502b8e7966..c1260920fea18e9941b6ec0b9bea1acb56d25932 100644 (file)
 #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 */
index 27aca62a8d70aeb584c680d13f94070440e350be..f10b97bef0c1ed7250d5527ff23bdabb27c175a6 100644 (file)
@@ -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) */