]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
callbacks via module specific function for walk_supers.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 1 Aug 2007 14:01:34 +0000 (14:01 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 1 Aug 2007 14:01:34 +0000 (14:01 +0000)
part of a move towards multiple modules for meshes.

git-svn-id: file:///svn/unbound/trunk@471 be551aaa-1e26-0410-a405-d3ace91eadb9

iterator/iterator.c
services/mesh.c
util/module.h
validator/validator.c

index c195f92c73bd6abe13b46653dd277c2853c40114..413e4f3ec6fffbdcfcc74891f7b25f93a100c314 100644 (file)
@@ -215,10 +215,12 @@ error_response(struct module_qstate* qstate, int id, int rcode)
        verbose(VERB_DETAIL, "return error response %s", 
                ldns_lookup_by_id(ldns_rcodes, rcode)?
                ldns_lookup_by_id(ldns_rcodes, rcode)->name:"??");
+       qstate->return_rcode = rcode;
+       qstate->return_msg = NULL;
        /* tell clients that we failed */
        (*qstate->env->query_done)(qstate, rcode, NULL);
        /* tell our parents that we failed */
-       (*qstate->env->walk_supers)(qstate, id, &error_supers);
+       (*qstate->env->walk_supers)(qstate, id, NULL);
        qstate->ext_state[id] = module_finished;
        return 0;
 }
@@ -1179,17 +1181,13 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
 static void
 prime_supers(struct module_qstate* qstate, int id, struct module_qstate* forq)
 {
-       struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
        struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id];
        struct delegpt* dp = NULL;
-       enum response_type type = response_type_from_server(iq->response, 
-               &iq->qchase, iq->dp);
 
        log_assert(qstate->is_priming || foriq->wait_priming_stub);
-       if(type == RESPONSE_TYPE_ANSWER) {
-               /* Convert our response to a delegation point */
-               dp = delegpt_from_message(iq->response, forq->region);
-       }
+       log_assert(qstate->return_rcode == LDNS_RCODE_NOERROR);
+       /* Convert our response to a delegation point */
+       dp = delegpt_from_message(qstate->return_msg, forq->region);
        if(!dp) {
                /* if there is no convertable delegation point, then 
                 * the ANSWER type was (presumably) a negative answer. */
@@ -1200,10 +1198,10 @@ prime_supers(struct module_qstate* qstate, int id, struct module_qstate* forq)
                return;
        }
 
-       log_query_info(VERB_DETAIL, "priming successful for", &iq->qchase);
+       log_query_info(VERB_DETAIL, "priming successful for", &qstate->qinfo);
        delegpt_log(dp);
        foriq->dp = dp;
-       foriq->deleg_msg = dns_copy_msg(iq->response, forq->region);
+       foriq->deleg_msg = dns_copy_msg(qstate->return_msg, forq->region);
        if(!foriq->deleg_msg) {
                log_err("copy prime response: out of memory");
                foriq->dp = NULL;
@@ -1235,6 +1233,17 @@ prime_supers(struct module_qstate* qstate, int id, struct module_qstate* forq)
 static int
 processPrimeResponse(struct module_qstate* qstate, int id)
 {
+       struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
+       enum response_type type = response_type_from_server(iq->response, 
+               &iq->qchase, iq->dp);
+       if(type == RESPONSE_TYPE_ANSWER) {
+               qstate->return_rcode = LDNS_RCODE_NOERROR;
+               qstate->return_msg = iq->response;
+       } else {
+               qstate->return_rcode = LDNS_RCODE_SERVFAIL;
+               qstate->return_msg = NULL;
+       }
+
        /* This event is finished. */
        qstate->ext_state[id] = module_finished;
 
@@ -1242,7 +1251,7 @@ processPrimeResponse(struct module_qstate* qstate, int id)
         * bugger off (and retry) */
        (*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
        /* tell interested supers that priming is done */
-       (*qstate->env->walk_supers)(qstate, id, &prime_supers);
+       (*qstate->env->walk_supers)(qstate, id, NULL);
        return 0;
 }
 
@@ -1267,6 +1276,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
        struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id];
        struct ub_packed_rrset_key* rrset;
        struct delegpt_ns* dpns;
+       log_assert(qstate->return_rcode == LDNS_RCODE_NOERROR);
 
        foriq->state = QUERYTARGETS_STATE;
 
@@ -1293,7 +1303,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
         * the original event. 
         * NOTE: we could only look for the AnswerRRset if the 
         * response type was ANSWER. */
-       rrset = reply_find_answer_rrset(&iq->qchase, iq->response->rep);
+       rrset = reply_find_answer_rrset(&iq->qchase, qstate->return_msg->rep);
        if(rrset) {
                /* if CNAMEs have been followed - add new NS to delegpt. */
                /* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */
@@ -1363,13 +1373,36 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
                /* use server supplied upper/lower case */
                qstate->qinfo.qname = iq->response->qinfo.qname;
        }
+       qstate->return_rcode = LDNS_RCODE_NOERROR;
+       qstate->return_msg = iq->response;
        (*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR, 
                iq->response->rep);
-       (*qstate->env->walk_supers)(qstate, id, &processTargetResponse);
+       (*qstate->env->walk_supers)(qstate, id, NULL);
 
        return 0;
 }
 
+/**
+ * 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.
+ */
+static void
+iter_inform_super(struct module_qstate* qstate, int id, 
+       struct module_qstate* super)
+{
+       if(qstate->return_rcode != LDNS_RCODE_NOERROR)
+               error_supers(qstate, id, super);
+       if(qstate->is_priming)
+               prime_supers(qstate, id, super);
+       else    processTargetResponse(qstate, id, super);
+}
+
 /**
  * Handle iterator state.
  * Handle events. This is the real processing loop for events, responsible
@@ -1567,7 +1600,8 @@ iter_clear(struct module_qstate* qstate, int id)
  */
 static struct module_func_block iter_block = {
        "iterator",
-       &iter_init, &iter_deinit, &iter_operate, &iter_clear
+       &iter_init, &iter_deinit, &iter_operate, &iter_inform_super, 
+       &iter_clear
 };
 
 struct module_func_block* 
index 8c7ff7e3b1d14e3a012bf7b3b2892df068edc19a..defa8b560dbec67aa283fc8761774793742fb001 100644 (file)
@@ -231,7 +231,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
        mstate->s.reply = NULL;
        mstate->s.region = region;
        mstate->s.curmod = 0;
-       mstate->s.return_rep = 0;
+       mstate->s.return_msg = 0;
        mstate->s.return_rcode = LDNS_RCODE_NOERROR;
        mstate->s.env = env;
        mstate->s.mesh_info = mstate;
@@ -483,12 +483,14 @@ void mesh_walk_supers(struct module_qstate* qstate, int id,
        struct mesh_state_ref* ref;
        log_assert(!(m->debug_flags&2)); /* not twice! */
        m->debug_flags |= 2;
+       (void)cb;
        RBTREE_FOR(ref, struct mesh_state_ref*, &qstate->mesh_info->super_set)
        {
                /* make super runnable */
                (void)rbtree_insert(&mesh->run, &ref->s->run_node);
-               /* callback */
-               (*cb)(qstate, id, &ref->s->s);
+               /* callback the function to inform super of result */
+               (*mesh->modfunc[ref->s->s.curmod]->inform_super)(qstate, 
+                       id, &ref->s->s);
        }
 }
 
index 340e37c477503aa1ade3a24bce13749708d29e84..be912bf0097c32034f05e10ffb486a1cb6b2a29c 100644 (file)
@@ -276,9 +276,9 @@ struct module_qstate {
 
        /** comm_reply contains server replies */
        struct comm_reply* reply;
-       /** the reply info, with message for client, calling module */
-       struct reply_info* return_rep;
-       /** the rcode, in case of error, instead of a reply info message */
+       /** the reply message, with message for client and calling module */
+       struct dns_msg* return_msg;
+       /** the rcode, in case of error, instead of a reply message */
        int return_rcode;
        /** region for this query. Cleared when query process finishes. */
        struct region* region;
@@ -339,6 +339,19 @@ struct module_func_block {
         */
        void (*operate)(struct module_qstate* qstate, enum module_ev event, 
                int id, struct outbound_entry* outbound);
+
+       /**
+        * inform super querystate about the results from this subquerystate.
+        * Is called when the querystate is finished.
+        * @param qstate: the query state that is finished.
+        *      Examine return_rcode and return_reply in the qstate.
+        * @param id: module id for this module.
+        *      This coincides with the current module for the super qstate.
+        * @param super: the super querystate that needs to be informed.
+        */
+       void (*inform_super)(struct module_qstate* qstate, int id,
+               struct module_qstate* super);
+
        /**
         * clear module specific data
         */
index adf472aaba8406dc72d15ec3c6af5d9438f20b5b..371c15120681e47f67fa1c19944ce87fb4d1aad2 100644 (file)
@@ -89,6 +89,20 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
        (void)outbound;
 }
 
+/** 
+ * inform validator super.
+ * 
+ * @param qstate: query state that finished.
+ * @param id: module id.
+ * @param super: the qstate to inform.
+ */
+static void
+val_inform_super(struct module_qstate* qstate, int id,
+       struct module_qstate* super)
+{
+}
+
+
 /** validator cleanup query state */
 static void
 val_clear(struct module_qstate* qstate, int id)
@@ -104,7 +118,7 @@ val_clear(struct module_qstate* qstate, int id)
  */
 static struct module_func_block val_block = {
        "validator",
-       &val_init, &val_deinit, &val_operate, &val_clear
+       &val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear
 };
 
 struct module_func_block*