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) if(!worker)
return; return;
mesh_stats(worker->env.mesh, "mesh has");
server_stats_log(&worker->stats, worker->thread_num); server_stats_log(&worker->stats, worker->thread_num);
mesh_delete(worker->env.mesh); mesh_delete(worker->env.mesh);
listen_delete(worker->front); listen_delete(worker->front);

View file

@ -2,6 +2,8 @@
- mesh is called by worker, and iterator uses it. - mesh is called by worker, and iterator uses it.
This removes the hierarchical code. This removes the hierarchical code.
QueryTargets state and Finished state are merged for iterator. 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 25 June 2007: Wouter
- more mesh work. - more mesh work.

View file

@ -161,7 +161,7 @@ iter_handlereply(struct module_qstate* qstate, int id)
h = query_info_hash(&qstate->qinfo); h = query_info_hash(&qstate->qinfo);
(*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR, reply_msg); (*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR, reply_msg);
/* there should be no dependencies in this forwarding mode */ /* 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); dns_cache_store_msg(qstate->env, &reply_qinfo, h, reply_msg);
qstate->ext_state[id] = module_finished; qstate->ext_state[id] = module_finished;
return 1; return 1;
@ -177,8 +177,7 @@ perform_forward(struct module_qstate* qstate, enum module_ev event, int id,
if(!fwd_new(qstate, id)) { if(!fwd_new(qstate, id)) {
(*qstate->env->query_done)(qstate, (*qstate->env->query_done)(qstate,
LDNS_RCODE_SERVFAIL, NULL); LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, (*qstate->env->walk_supers)(qstate, id, NULL);
LDNS_RCODE_SERVFAIL, NULL);
qstate->ext_state[id] = module_error; qstate->ext_state[id] = module_error;
return; return;
} }
@ -188,15 +187,13 @@ perform_forward(struct module_qstate* qstate, enum module_ev event, int id,
if(!outbound) { if(!outbound) {
verbose(VERB_ALGO, "query reply was not serviced"); verbose(VERB_ALGO, "query reply was not serviced");
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL); (*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, (*qstate->env->walk_supers)(qstate, id, NULL);
LDNS_RCODE_SERVFAIL, NULL);
qstate->ext_state[id] = module_error; qstate->ext_state[id] = module_error;
return; return;
} }
if(event == module_event_timeout || event == module_event_error) { if(event == module_event_timeout || event == module_event_error) {
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL); (*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, (*qstate->env->walk_supers)(qstate, id, NULL);
LDNS_RCODE_SERVFAIL, NULL);
qstate->ext_state[id] = module_error; qstate->ext_state[id] = module_error;
return; return;
} }
@ -204,15 +201,14 @@ perform_forward(struct module_qstate* qstate, enum module_ev event, int id,
if(!iter_handlereply(qstate, id)) { if(!iter_handlereply(qstate, id)) {
(*qstate->env->query_done)(qstate, (*qstate->env->query_done)(qstate,
LDNS_RCODE_SERVFAIL, NULL); LDNS_RCODE_SERVFAIL, NULL);
(*qstate->env->walk_supers)(qstate, id, (*qstate->env->walk_supers)(qstate, id, NULL);
LDNS_RCODE_SERVFAIL, NULL);
qstate->ext_state[id] = module_error; qstate->ext_state[id] = module_error;
} }
return; return;
} }
log_err("bad event for iterator[forwarding]"); log_err("bad event for iterator[forwarding]");
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL); (*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; qstate->ext_state[id] = module_error;
} }
@ -264,14 +260,11 @@ final_state(struct iter_qstate* iq)
* @param qstate: query state that failed. * @param qstate: query state that failed.
* @param id: module id. * @param id: module id.
* @param super: super state. * @param super: super state.
* @param rcode: the error code.
*/ */
static void static void
error_supers(struct module_qstate* qstate, int id, error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
struct module_qstate* super, int rcode)
{ {
struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id]; 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 || if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) { 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 */ /* tell clients that we failed */
(*qstate->env->query_done)(qstate, rcode, NULL); (*qstate->env->query_done)(qstate, rcode, NULL);
/* tell our parents that we failed */ /* 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; qstate->ext_state[id] = module_finished;
return 0; return 0;
} }
@ -1248,11 +1241,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* @param qstate: priming query state that finished. * @param qstate: priming query state that finished.
* @param id: module id. * @param id: module id.
* @param forq: the qstate for which priming has been done. * @param forq: the qstate for which priming has been done.
* @param rcode: error code.
*/ */
static void static void
prime_supers(struct module_qstate* qstate, int id, prime_supers(struct module_qstate* qstate, int id, struct module_qstate* forq)
struct module_qstate* forq, int rcode)
{ {
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
struct iter_qstate* foriq = (struct iter_qstate*)forq->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, enum response_type type = response_type_from_server(iq->response,
&iq->qchase, iq->dp); &iq->qchase, iq->dp);
log_assert(rcode == LDNS_RCODE_NOERROR);
log_assert(iq->priming || iq->priming_stub); log_assert(iq->priming || iq->priming_stub);
if(type == RESPONSE_TYPE_ANSWER) { if(type == RESPONSE_TYPE_ANSWER) {
/* Convert our response to a delegation point */ /* Convert our response to a delegation point */
@ -1317,8 +1307,7 @@ processPrimeResponse(struct module_qstate* qstate, int id)
* bugger off (and retry) */ * bugger off (and retry) */
(*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL); (*qstate->env->query_done)(qstate, LDNS_RCODE_SERVFAIL, NULL);
/* tell interested supers that priming is done */ /* tell interested supers that priming is done */
(*qstate->env->walk_supers)(qstate, id, LDNS_RCODE_NOERROR, (*qstate->env->walk_supers)(qstate, id, &prime_supers);
&prime_supers);
return 0; return 0;
} }
@ -1334,11 +1323,10 @@ processPrimeResponse(struct module_qstate* qstate, int id)
* @param qstate: query state. * @param qstate: query state.
* @param id: module id. * @param id: module id.
* @param forq: super query state. * @param forq: super query state.
* @param rcode: if not NOERROR, an error occurred.
*/ */
static void static void
processTargetResponse(struct module_qstate* qstate, int id, 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* iq = (struct iter_qstate*)qstate->minfo[id];
struct iter_qstate* foriq = (struct iter_qstate*)forq->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; struct delegpt_ns* dpns;
foriq->state = QUERYTARGETS_STATE; 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). */ /* check to see if parent event is still interested (in orig name). */
dpns = delegpt_find_ns(foriq->dp, qstate->qinfo.qname, 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, (*qstate->env->query_done)(qstate, LDNS_RCODE_NOERROR,
iq->response->rep); iq->response->rep);
(*qstate->env->walk_supers)(qstate, id, LDNS_RCODE_NOERROR, (*qstate->env->walk_supers)(qstate, id, &processTargetResponse);
&processTargetResponse);
return 0; return 0;
} }

View file

@ -160,6 +160,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
if(was_noreply) { if(was_noreply) {
mesh->num_reply_states ++; mesh->num_reply_states ++;
} }
mesh->num_reply_addrs++;
if(added) if(added)
mesh_run(mesh, s, module_event_new, NULL); 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); comm_point_send_reply(&r->query_reply);
} }
/* account */ /* account */
m->s.env->mesh->num_reply_addrs--;
if(gettimeofday(&end_time, NULL) < 0) { if(gettimeofday(&end_time, NULL) < 0) {
log_err("gettimeofday: %s", strerror(errno)); log_err("gettimeofday: %s", strerror(errno));
return; 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 mesh_walk_supers(struct module_qstate* qstate, int id,
void (*cb)(struct module_qstate*, int, struct module_qstate*, int)) void (*cb)(struct module_qstate*, int, struct module_qstate*))
{ {
struct mesh_state* m = qstate->mesh_info; struct mesh_state* m = qstate->mesh_info;
struct mesh_area* mesh = m->s.env->mesh; 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 */ /* make super runnable */
(void)rbtree_insert(&mesh->run, &ref->s->run_node); (void)rbtree_insert(&mesh->run, &ref->s->run_node);
/* callback */ /* 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); (void)rbtree_delete(&mesh->run, mstate);
} else mstate = NULL; } else mstate = NULL;
} }
verbose(VERB_ALGO, "mesh_run: end, %u states (%u with reply, " mesh_stats(mesh, "mesh_run: end");
"%u detached), %u total replies", (unsigned)mesh->all.count, }
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_reply_states,
(unsigned)mesh->num_detached_states, (unsigned)mesh->num_detached_states,
(unsigned)mesh->num_reply_addrs); (unsigned)mesh->num_reply_addrs);
if(1) { if(mesh->replies_sent > 0) {
struct timeval avg; struct timeval avg;
timeval_divide(&avg, &mesh->replies_sum_wait, timeval_divide(&avg, &mesh->replies_sum_wait,
mesh->replies_sent); mesh->replies_sent);
verbose(VERB_ALGO, "send %u replies, with average wait " verbose(VERB_ALGO, "sent %u replies, with average wait "
"of %d.%6.6d", (unsigned)mesh->replies_sent, "of %d.%6.6d sec", (unsigned)mesh->replies_sent,
(int)avg.tv_sec, (int)avg.tv_usec); (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 qstate: the state that has results, used to find mesh state.
* @param id: module id. * @param id: module id.
* @param rcode: rcode to pass to callback, for easier error passing to
* parents.
* @param cb: callback function. Called as * @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 mesh_walk_supers(struct module_qstate* qstate, int id,
void (*cb)(struct module_qstate*, int, struct module_qstate*, int)); void (*cb)(struct module_qstate*, int, struct module_qstate*));
/** /**
* Delete mesh state, cleanup and also rbtrees and so on. * 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, void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
enum module_ev ev, struct outbound_entry* e); 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 */ #endif /* SERVICES_MESH_H */

View file

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

View file

@ -69,6 +69,15 @@ www.example.com. IN A
SECTION ANSWER SECTION ANSWER
www.example.com. IN A 10.20.30.40 www.example.com. IN A 10.20.30.40
ENTRY_END 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 SCENARIO_END
; testbound checks before exit: ; testbound checks before exit:

View file

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

View file

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

View file

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

View file

@ -190,14 +190,11 @@ struct module_env {
* *
* @param qstate: the state that has results, used to find mesh state. * @param qstate: the state that has results, used to find mesh state.
* @param id: module id. * @param id: module id.
* @param rcode: rcode to pass to callback, for easier error passing to
* parents.
* @param cb: callback function. Called as * @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, void (*walk_supers)(struct module_qstate* qstate, int id,
int rcode, void (*cb)(struct module_qstate*, int, void (*cb)(struct module_qstate*, int, struct module_qstate*));
struct module_qstate*, int));
/** region for temporary usage. May be cleared after operate() call. */ /** region for temporary usage. May be cleared after operate() call. */
struct region* scratch; struct region* scratch;