zbyszek / rpms / unbound

Forked from rpms/unbound 4 years ago
Clone
Blob Blame History Raw
diff -aur unbound-1.4.17-orig/iterator/iterator.c unbound-1.4.17/iterator/iterator.c
--- unbound-1.4.17-orig/iterator/iterator.c	2012-03-21 11:01:01.000000000 -0400
+++ unbound-1.4.17/iterator/iterator.c	2012-07-23 13:29:05.755093317 -0400
@@ -1541,8 +1541,7 @@
  *         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");
@@ -1906,8 +1905,16 @@
 		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);
+		}
 		if(!iter_dns_store(qstate->env, &iq->response->qinfo,
 			iq->response->rep, 0, qstate->prefetch_leeway,
 			iq->dp&&iq->dp->has_parent_side_NS,
@@ -2032,8 +2039,15 @@
 		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))
diff -aur unbound-1.4.17-orig/services/mesh.c unbound-1.4.17/services/mesh.c
--- unbound-1.4.17-orig/services/mesh.c	2011-11-10 13:44:06.000000000 -0500
+++ unbound-1.4.17/services/mesh.c	2012-07-23 13:27:08.163096837 -0400
@@ -676,6 +676,7 @@
 	/* 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 @@
 		*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--;
@@ -735,16 +739,20 @@
 	superref->s = super;
 	subref->node.key = subref;
 	subref->s = sub;
-#ifdef UNBOUND_DEBUG
-	n =
-#endif
-	rbtree_insert(&sub->super_set, &superref->node);
-	log_assert(n != NULL);
+	if(!rbtree_insert(&sub->super_set, &superref->node)) {
+		/* this should not happen, iterator and validator do not
+		 * attach subqueries that are identical. */
+		/* already attached, we are done, nothing todo.
+		 * since superref and subref already allocated in region,
+		 * we cannot free them */
+		return 1;
+	}
 #ifdef UNBOUND_DEBUG
 	n =
 #endif
 	rbtree_insert(&super->sub_set, &subref->node);
-	log_assert(n != NULL);
+	log_assert(n != NULL); /* we checked above if statement, the reverse
+	  administration should not fail now, unless they are out of sync */
 	return 1;
 }