From: Wouter Wijngaards Date: Wed, 1 Aug 2007 14:01:34 +0000 (+0000) Subject: callbacks via module specific function for walk_supers. X-Git-Tag: release-0.5~170 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2122b961d3cfef332d4c208a4db12e48483b3952;p=thirdparty%2Funbound.git callbacks via module specific function for walk_supers. part of a move towards multiple modules for meshes. git-svn-id: file:///svn/unbound/trunk@471 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/iterator/iterator.c b/iterator/iterator.c index c195f92c7..413e4f3ec 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -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* diff --git a/services/mesh.c b/services/mesh.c index 8c7ff7e3b..defa8b560 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -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); } } diff --git a/util/module.h b/util/module.h index 340e37c47..be912bf00 100644 --- a/util/module.h +++ b/util/module.h @@ -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 */ diff --git a/validator/validator.c b/validator/validator.c index adf472aab..371c15120 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -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*