h = query_info_hash(&qstate->qinfo);
(*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR, reply_msg);
/* there should be no dependencies in this forwarding mode */
- (*qstate->env->walk_supers)(qstate, id, LDNS_RCODE_SERVFAIL, NULL);
+ (*qstate->env->walk_supers)(qstate, id, NULL);
dns_cache_store_msg(qstate->env, &reply_qinfo, h, reply_msg);
qstate->ext_state[id] = module_finished;
return 1;
if(!fwd_new(qstate, id)) {
(*qstate->env->query_done)(qstate,
LDNS_RCODE_SERVFAIL, NULL);
- (*qstate->env->walk_supers)(qstate, id,
- LDNS_RCODE_SERVFAIL, NULL);
+ (*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
return;
}
if(!outbound) {
verbose(VERB_ALGO, "query reply was not serviced");
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
- (*qstate->env->walk_supers)(qstate, id,
- LDNS_RCODE_SERVFAIL, NULL);
+ (*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
return;
}
if(event == module_event_timeout || event == module_event_error) {
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
- (*qstate->env->walk_supers)(qstate, id,
- LDNS_RCODE_SERVFAIL, NULL);
+ (*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
return;
}
if(!iter_handlereply(qstate, id)) {
(*qstate->env->query_done)(qstate,
LDNS_RCODE_SERVFAIL, NULL);
- (*qstate->env->walk_supers)(qstate, id,
- LDNS_RCODE_SERVFAIL, NULL);
+ (*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
}
return;
}
log_err("bad event for iterator[forwarding]");
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
- (*qstate->env->walk_supers)(qstate, id, LDNS_RCODE_SERVFAIL, NULL);
+ (*qstate->env->walk_supers)(qstate, id, NULL);
qstate->ext_state[id] = module_error;
}
* @param qstate: query state that failed.
* @param id: module id.
* @param super: super state.
- * @param rcode: the error code.
*/
static void
-error_supers(struct module_qstate* qstate, int id,
- struct module_qstate* super, int rcode)
+error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
{
struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
- log_assert(rcode != LDNS_RCODE_NOERROR);
if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
/* tell clients that we failed */
(*qstate->env->query_done)(qstate, rcode, NULL);
/* tell our parents that we failed */
- (*qstate->env->walk_supers)(qstate, id, rcode, &error_supers);
+ (*qstate->env->walk_supers)(qstate, id, &error_supers);
qstate->ext_state[id] = module_finished;
return 0;
}
* @param qstate: priming query state that finished.
* @param id: module id.
* @param forq: the qstate for which priming has been done.
- * @param rcode: error code.
*/
static void
-prime_supers(struct module_qstate* qstate, int id,
- struct module_qstate* forq, int rcode)
+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];
enum response_type type = response_type_from_server(iq->response,
&iq->qchase, iq->dp);
- log_assert(rcode == LDNS_RCODE_NOERROR);
log_assert(iq->priming || iq->priming_stub);
if(type == RESPONSE_TYPE_ANSWER) {
/* Convert our response to a delegation point */
* 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, LDNS_RCODE_NOERROR,
- &prime_supers);
+ (*qstate->env->walk_supers)(qstate, id, &prime_supers);
return 0;
}
* @param qstate: query state.
* @param id: module id.
* @param forq: super query state.
- * @param rcode: if not NOERROR, an error occurred.
*/
static void
processTargetResponse(struct module_qstate* qstate, int id,
- struct module_qstate* forq, int rcode)
+ 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_ns* dpns;
foriq->state = QUERYTARGETS_STATE;
- /* use error_response for errs*/
- log_assert(rcode == LDNS_RCODE_NOERROR);
/* check to see if parent event is still interested (in orig name). */
dpns = delegpt_find_ns(foriq->dp, qstate->qinfo.qname,
}
(*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR,
iq->response->rep);
- (*qstate->env->walk_supers)(qstate, id, LDNS_RCODE_NOERROR,
- &processTargetResponse);
+ (*qstate->env->walk_supers)(qstate, id, &processTargetResponse);
return 0;
}
if(was_noreply) {
mesh->num_reply_states ++;
}
+ mesh->num_reply_addrs++;
if(added)
mesh_run(mesh, s, module_event_new, NULL);
}
comm_point_send_reply(&r->query_reply);
}
/* account */
+ m->s.env->mesh->num_reply_addrs--;
if(gettimeofday(&end_time, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno));
return;
}
}
-void mesh_walk_supers(struct module_qstate* qstate, int id, int rcode,
- void (*cb)(struct module_qstate*, int, struct module_qstate*, int))
+void mesh_walk_supers(struct module_qstate* qstate, int id,
+ void (*cb)(struct module_qstate*, int, struct module_qstate*))
{
struct mesh_state* m = qstate->mesh_info;
struct mesh_area* mesh = m->s.env->mesh;
/* make super runnable */
(void)rbtree_insert(&mesh->run, &ref->s->run_node);
/* callback */
- (*cb)(qstate, id, &ref->s->s, rcode);
+ (*cb)(qstate, id, &ref->s->s);
}
}
(void)rbtree_delete(&mesh->run, mstate);
} else mstate = NULL;
}
- verbose(VERB_ALGO, "mesh_run: end, %u states (%u with reply, "
- "%u detached), %u total replies", (unsigned)mesh->all.count,
+ mesh_stats(mesh, "mesh_run: end");
+}
+
+void
+mesh_stats(struct mesh_area* mesh, const char* str)
+{
+ verbose(VERB_ALGO, "%s %u states (%u with reply, %u detached), "
+ "%u waiting replies", str, (unsigned)mesh->all.count,
(unsigned)mesh->num_reply_states,
(unsigned)mesh->num_detached_states,
(unsigned)mesh->num_reply_addrs);
- if(1) {
+ if(mesh->replies_sent > 0) {
struct timeval avg;
timeval_divide(&avg, &mesh->replies_sum_wait,
mesh->replies_sent);
- verbose(VERB_ALGO, "send %u replies, with average wait "
- "of %d.%6.6d", (unsigned)mesh->replies_sent,
+ verbose(VERB_ALGO, "sent %u replies, with average wait "
+ "of %d.%6.6d sec", (unsigned)mesh->replies_sent,
(int)avg.tv_sec, (int)avg.tv_usec);
}
}
*
* @param qstate: the state that has results, used to find mesh state.
* @param id: module id.
- * @param rcode: rcode to pass to callback, for easier error passing to
- * parents.
* @param cb: callback function. Called as
- * cb(qstate, id, super_qstate, rcode) for every super query state.
+ * cb(qstate, id, super_qstate) for every super query state.
*/
-void mesh_walk_supers(struct module_qstate* qstate, int id, int rcode,
- void (*cb)(struct module_qstate*, int, struct module_qstate*, int));
+void mesh_walk_supers(struct module_qstate* qstate, int id,
+ void (*cb)(struct module_qstate*, int, struct module_qstate*));
/**
* Delete mesh state, cleanup and also rbtrees and so on.
void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
enum module_ev ev, struct outbound_entry* e);
+/**
+ * Print some stats about the mesh to the log.
+ * @param mesh: the mesh to print it for.
+ * @param str: descriptive string to go with it.
+ */
+void mesh_stats(struct mesh_area* mesh, const char* str);
+
#endif /* SERVICES_MESH_H */