From: Wouter Wijngaards Date: Wed, 3 Oct 2007 08:36:47 +0000 (+0000) Subject: loopfix. X-Git-Tag: release-0.6~91 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a73089c5f08496c238aaad9deb419f2064b175b0;p=thirdparty%2Funbound.git loopfix. git-svn-id: file:///svn/unbound/trunk@653 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 5b71780f0..3ff110e30 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,4 +1,7 @@ 3 October 2007: Wouter + - fix for multiple empty nonterminals, after multiple DSes in the + chain of trust. + - mesh checks if modules are looping, and stops them. - refetch with CNAMEd nameserver address regression test added. 1 October 2007: Wouter diff --git a/services/mesh.c b/services/mesh.c index e1f800b2c..0934f7ba6 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -215,6 +215,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo, mstate->reply_list = NULL; rbtree_init(&mstate->super_set, &mesh_state_ref_compare); rbtree_init(&mstate->sub_set, &mesh_state_ref_compare); + mstate->num_activated = 0; /* init module qstate */ mstate->s.qinfo.qtype = qinfo->qtype; mstate->s.qinfo.qclass = qinfo->qclass; @@ -550,6 +551,14 @@ static int mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate, enum module_ext_state s, enum module_ev* ev) { + mstate->num_activated++; + if(mstate->num_activated > MESH_MAX_ACTIVATION) { + /* module is looping. Stop it. */ + log_err("internal error: looping module stopped"); + log_query_info(VERB_DETAIL, "pass error for qstate", + &mstate->s.qinfo); + s = module_error; + } if(s == module_wait_module) { /* start next module */ mstate->s.curmod++; @@ -557,7 +566,6 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate, log_err("Cannot pass to next module; at last module"); log_query_info(VERB_DETAIL, "pass error for qstate", &mstate->s.qinfo); - log_assert(0); /* catch this for now */ mstate->s.curmod--; return mesh_continue(mesh, mstate, module_error, ev); } diff --git a/services/mesh.h b/services/mesh.h index 7bc505b07..80693dcad 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -57,6 +57,12 @@ struct reply_info; struct outbound_entry; struct timehist; +/** + * Maximum number of mesh state activations. Any more is likely an + * infinite loop in the module. It is then terminated. + */ +#define MESH_MAX_ACTIVATION 1000 + /** * Mesh of query states */ @@ -117,6 +123,8 @@ struct mesh_state { /** set of substates (that this state needs to continue) * contains struct mesh_state_ref* */ rbtree_t sub_set; + /** number of activations for the mesh state */ + size_t num_activated; }; /** diff --git a/validator/validator.c b/validator/validator.c index 7cb651fd9..3aab0b7e3 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -1240,7 +1240,11 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id) return 1; } - if(vq->empty_DS_name) { + if(vq->empty_DS_name && dname_strict_subdomain_c(vq->empty_DS_name, + current_key_name)) { + /* if the last empty nonterminal/emptyDS name we detected is + * below the current key, use that name to make progress + * along the chain of trust */ if(query_dname_compare(target_key_name, vq->empty_DS_name) == 0) { /* do not query for empty_DS_name again */