fixup tests, better stats, nicer api supers_walk().

git-svn-id: file:///svn/unbound/trunk@424 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-06-26 15:24:07 +00:00
parent 06cfef3252
commit ee94589556
11 changed files with 59 additions and 59 deletions

View file

@ -564,6 +564,7 @@ worker_delete(struct worker* worker)
{
if(!worker)
return;
mesh_stats(worker->env.mesh, "mesh has");
server_stats_log(&worker->stats, worker->thread_num);
mesh_delete(worker->env.mesh);
listen_delete(worker->front);

View file

@ -2,6 +2,8 @@
- mesh is called by worker, and iterator uses it.
This removes the hierarchical code.
QueryTargets state and Finished state are merged for iterator.
- forwarder mode no longer sets AA bit on first reply.
- rcode in walk_supers is not needed.
25 June 2007: Wouter
- more mesh work.

View file

@ -161,7 +161,7 @@ iter_handlereply(struct module_qstate* qstate, int id)
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;
@ -177,8 +177,7 @@ perform_forward(struct module_qstate* qstate, enum module_ev event, int id,
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;
}
@ -188,15 +187,13 @@ perform_forward(struct module_qstate* qstate, enum module_ev event, int id,
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;
}
@ -204,15 +201,14 @@ perform_forward(struct module_qstate* qstate, enum module_ev event, int id,
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;
}
@ -264,14 +260,11 @@ final_state(struct iter_qstate* iq)
* @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) {
@ -317,7 +310,7 @@ error_response(struct module_qstate* qstate, int id, int rcode)
/* 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;
}
@ -1248,11 +1241,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* @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];
@ -1260,7 +1251,6 @@ prime_supers(struct module_qstate* qstate, int 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 */
@ -1317,8 +1307,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, LDNS_RCODE_NOERROR,
&prime_supers);
(*qstate->env->walk_supers)(qstate, id, &prime_supers);
return 0;
}
@ -1334,11 +1323,10 @@ processPrimeResponse(struct module_qstate* qstate, int id)
* @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];
@ -1346,8 +1334,6 @@ processTargetResponse(struct module_qstate* qstate, int 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,
@ -1441,8 +1427,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
}
(*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;
}

View file

@ -160,6 +160,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(was_noreply) {
mesh->num_reply_states ++;
}
mesh->num_reply_addrs++;
if(added)
mesh_run(mesh, s, module_event_new, NULL);
}
@ -427,6 +428,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
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;
@ -452,8 +454,8 @@ void mesh_query_done(struct module_qstate* qstate, int rcode,
}
}
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;
@ -465,7 +467,7 @@ void mesh_walk_supers(struct module_qstate* qstate, int id, int rcode,
/* 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);
}
}
@ -536,17 +538,23 @@ void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
(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);
}
}

View file

@ -258,13 +258,11 @@ void mesh_query_done(struct module_qstate* qstate, int rcode,
*
* @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.
@ -342,4 +340,11 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
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 */

View file

@ -36,8 +36,7 @@ ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
; first reply, have AA set.
REPLY QR AA RD RA
REPLY QR RD RA
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER

View file

@ -69,6 +69,15 @@ www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH opcode qname qtype
SECTION QUESTION
www.example.net. IN A
SECTION ANSWER
www.example.net. IN A 10.20.30.40
ENTRY_END
SCENARIO_END
; testbound checks before exit:

View file

@ -36,8 +36,7 @@ ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
; first reply, have AA set.
REPLY QR AA RD RA
REPLY QR RD RA
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
@ -80,8 +79,7 @@ ENTRY_END
STEP 9 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
; first reply, have AA set.
REPLY QR AA RD RA
REPLY QR RD RA
SECTION QUESTION
bla.example.com. IN A
SECTION ANSWER

View file

@ -36,8 +36,7 @@ ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
; first reply, have AA set.
REPLY QR AA RD RA
REPLY QR RD RA
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
@ -83,8 +82,7 @@ ENTRY_END
STEP 9 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
; first reply, have AA set.
REPLY QR AA RD RA
REPLY QR RD RA
SECTION QUESTION
bla.example.com. IN A
SECTION ANSWER

View file

@ -36,8 +36,7 @@ ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
; first reply, have AA set.
REPLY QR AA RD RA
REPLY QR RD RA
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
@ -82,8 +81,7 @@ ENTRY_END
STEP 9 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
; first reply, have AA set.
REPLY QR AA RD RA
REPLY QR RD RA
SECTION QUESTION
bla.example.com. IN A
SECTION ANSWER

View file

@ -190,14 +190,11 @@ struct module_env {
*
* @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 qstate.
* cb(qstate, id, super_qstate) for every super qstate.
*/
void (*walk_supers)(struct module_qstate* qstate, int id,
int rcode, void (*cb)(struct module_qstate*, int,
struct module_qstate*, int));
void (*cb)(struct module_qstate*, int, struct module_qstate*));
/** region for temporary usage. May be cleared after operate() call. */
struct region* scratch;