]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
loopfix.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 3 Oct 2007 08:36:47 +0000 (08:36 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 3 Oct 2007 08:36:47 +0000 (08:36 +0000)
git-svn-id: file:///svn/unbound/trunk@653 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/mesh.c
services/mesh.h
validator/validator.c

index 5b71780f0c77fbad4e2cb90f47a03a6c2ae08b13..3ff110e30dac963108d97c9f41e82fab99352dc5 100644 (file)
@@ -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
index e1f800b2c4066c688fff88a99fbdaec690dbb4d1..0934f7ba6a8ef542bb9da8245320f9b3da56cb00 100644 (file)
@@ -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);
                }
index 7bc505b07b47b8da7b99bc65fbb8c99c863e34ca..80693dcad61792909cf6d34c0a39067f0fd58f07 100644 (file)
@@ -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;
 };
 
 /**
index 7cb651fd96b85155731574aa72c5f877874f786c..3aab0b7e3afae095f8ef5b202c5f7b2737e95d7e 100644 (file)
@@ -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 */