]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix bug#452 and another assertion failure in mesh.c, makes
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 20 Jul 2012 13:08:19 +0000 (13:08 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 20 Jul 2012 13:08:19 +0000 (13:08 +0000)
  assertions in mesh.c resist duplicates.  Fixes DS NS search to
  not generate duplicate sub queries.

git-svn-id: file:///svn/unbound/trunk@2718 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iterator.c
services/mesh.c
testdata/iter_ds_locate_ns_detach.rpl [new file with mode: 0644]

index b4e8cf9235b25f7126764c3f92acdab2753ff9b1..56b6c027d4d1de5e7765485d3c15f269646c96a9 100644 (file)
@@ -1,3 +1,8 @@
+20 July 2012: Willem
+       - Fix bug#452 and another assertion failure in mesh.c, makes
+         assertions in mesh.c resist duplicates.  Fixes DS NS search to
+         not generate duplicate sub queries.
+
 19 July 2012: Willem
        - Fix bug#454: Remove ACX_CHECK_COMPILER_FLAG from configure.ac,
          if CFLAGS is specified at configure time then '-g -O2' is not
index e3d3099aa3beedfc70bc59d49e075b82996666f0..6399fdeec0a7dd62fc93f12f9a1a4ebe9dbf288f 100644 (file)
@@ -1539,8 +1539,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
  *         the final state (i.e., on answer).
  */
 static int
-processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq,
-       int id)
+processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
 {
        struct module_qstate* subq = NULL;
        verbose(VERB_ALGO, "processDSNSFind");
@@ -1904,8 +1903,16 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                if(iq->qchase.qtype == LDNS_RR_TYPE_DS && !iq->dsns_point
                        && !(iq->chase_flags&BIT_RD)
                        && iter_ds_toolow(iq->response, iq->dp)
-                       && iter_dp_cangodown(&iq->qchase, iq->dp))
+                       && iter_dp_cangodown(&iq->qchase, iq->dp)) {
+                       /* close down outstanding requests to be discarded */
+                       outbound_list_clear(&iq->outlist);
+                       iq->num_current_queries = 0;
+                       fptr_ok(fptr_whitelist_modenv_detach_subs(
+                               qstate->env->detach_subs));
+                       (*qstate->env->detach_subs)(qstate);
+                       iq->num_target_queries = 0;
                        return processDSNSFind(qstate, iq, id);
+               }
                iter_dns_store(qstate->env, &iq->response->qinfo,
                        iq->response->rep, 0, qstate->prefetch_leeway,
                        iq->dp&&iq->dp->has_parent_side_NS,
@@ -2027,8 +2034,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                if(iq->qchase.qtype == LDNS_RR_TYPE_DS && !iq->dsns_point
                        && !(iq->chase_flags&BIT_RD)
                        && iter_ds_toolow(iq->response, iq->dp)
-                       && iter_dp_cangodown(&iq->qchase, iq->dp))
+                       && iter_dp_cangodown(&iq->qchase, iq->dp)) {
+                       outbound_list_clear(&iq->outlist);
+                       iq->num_current_queries = 0;
+                       fptr_ok(fptr_whitelist_modenv_detach_subs(
+                               qstate->env->detach_subs));
+                       (*qstate->env->detach_subs)(qstate);
+                       iq->num_target_queries = 0;
                        return processDSNSFind(qstate, iq, id);
+               }
                /* Process the CNAME response. */
                if(!handle_cname_response(qstate, iq, iq->response, 
                        &sname, &snamelen))
index d8ac310ef0fa851f3d158c0cb08d4b26cc58007f..5c66caf3236d230a09c569bab6da72753aa1e3e6 100644 (file)
@@ -676,6 +676,7 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
        /* find it, if not, create it */
        struct mesh_area* mesh = qstate->env->mesh;
        struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime);
+       int was_detached;
        if(mesh_detect_cycle_found(qstate, sub)) {
                verbose(VERB_ALGO, "attach failed, cycle detected");
                return 0;
@@ -706,9 +707,12 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
                *newq = &sub->s;
        } else
                *newq = NULL;
+       was_detached = (sub->super_set.count == 0);
        if(!mesh_state_attachment(qstate->mesh_info, sub))
                return 0;
-       if(!sub->reply_list && !sub->cb_list && sub->super_set.count == 1) {
+       /* if it was a duplicate  attachment, the count was not zero before */
+       if(!sub->reply_list && !sub->cb_list && was_detached && 
+               sub->super_set.count == 1) {
                /* it used to be detached, before this one got added */
                log_assert(mesh->num_detached_states > 0);
                mesh->num_detached_states--;
diff --git a/testdata/iter_ds_locate_ns_detach.rpl b/testdata/iter_ds_locate_ns_detach.rpl
new file mode 100644 (file)
index 0000000..9288fe5
--- /dev/null
@@ -0,0 +1,296 @@
+; config options
+server:
+       target-fetch-policy: "3 2 1 0 0"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test locate of NS records for DS and with detached queries
+; the additional targets looked up cause detached queries.
+; hence the target fetch policy is increased above.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id 
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN A
+SECTION ANSWER
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+SECTION AUTHORITY
+root-servers.net. IN NS        K.ROOT-SERVERS.NET.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id 
+REPLY QR AA NOERROR
+SECTION QUESTION
+k.root-servers.net. IN AAAA
+SECTION ANSWER
+SECTION AUTHORITY
+root-servers.net. IN SOA       K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id 
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+. IN SOA       K.ROOT-SERVERS.NET. hostmaster. 1 2 3 4 5
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net.   IN NS   a.server.net.
+net.   IN NS   b.server.net.
+net.   IN NS   c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.server.net.
+; The b.server.net and c.server.net servers are here to cause
+; extra lookups to be generated (to create detached queries in the
+; iterator), there is no IP address that answers for them set up.
+; force DSNSFind, we host a grandchild zone.
+; also, this range of steps is without responses for b and c, so that
+; they can be force to happen later (after the DSNS is activated).
+RANGE_BEGIN 0 20
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net.   IN NS   a.server.net.
+net.   IN NS   b.server.net.
+net.   IN NS   c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.server.net. IN A
+SECTION ANSWER
+a.server.net. IN A 192.5.6.30
+SECTION AUTHORITY
+net.   IN NS   a.server.net.
+net.   IN NS   b.server.net.
+net.   IN NS   c.server.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.net. IN DS
+SECTION AUTHORITY
+sub.example.net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.net. IN NS
+SECTION ANSWER
+sub.example.net. IN NS a.server.net.
+sub.example.net. IN NS b.server.net.
+sub.example.net. IN NS c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.sub.example.net. IN A
+SECTION AUTHORITY
+sub.example.net. IN NS a.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.server.net range with all the answers (to finish the test).
+RANGE_BEGIN 30 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net.   IN NS   a.server.net.
+net.   IN NS   b.server.net.
+net.   IN NS   c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.server.net. IN A
+SECTION ANSWER
+a.server.net. IN A 192.5.6.30
+SECTION AUTHORITY
+net.   IN NS   a.server.net.
+net.   IN NS   b.server.net.
+net.   IN NS   c.server.net.
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.server.net. IN AAAA
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.server.net. IN A
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+b.server.net. IN AAAA
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.server.net. IN A
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+c.server.net. IN AAAA
+SECTION AUTHORITY
+net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+a.sub.example.net. IN DS
+SECTION AUTHORITY
+sub.example.net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+sub.example.net. IN NS
+SECTION ANSWER
+sub.example.net. IN NS a.server.net.
+sub.example.net. IN NS b.server.net.
+sub.example.net. IN NS c.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+a.sub.example.net. IN A
+SECTION AUTHORITY
+sub.example.net. IN NS a.server.net.
+SECTION ADDITIONAL
+a.server.net. IN A 192.5.6.30
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+a.sub.example.net. IN DS
+ENTRY_END
+
+; make traffic flow at this time
+STEP 15 TRAFFIC
+
+STEP 20 TRAFFIC
+
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+a.sub.example.net. IN DS
+SECTION ANSWER
+SECTION AUTHORITY
+sub.example.net. IN SOA a.gtld-servers.net. hostmaster. 2 3 4 5 6
+SECTION ADDITIONAL
+ENTRY_END
+
+STEP 50 TRAFFIC
+
+SCENARIO_END