processClassResponse(struct module_qstate* qstate, int id,
	struct module_qstate* forq)
{
	struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id];
	struct dns_msg* from = qstate->return_msg;
	log_query_info(VERB_ALGO, "processClassResponse", &qstate->qinfo);
	log_query_info(VERB_ALGO, "processClassResponse super", &forq->qinfo);
	if(qstate->return_rcode != LDNS_RCODE_NOERROR) {
		/* cause servfail for qclass ANY query */
		foriq->response = NULL;
		foriq->state = FINISHED_STATE;
		return;
	}
	/* append result */
	if(!foriq->response) {
		/* allocate the response: copy RCODE, sec_state */
		foriq->response = dns_copy_msg(from, forq->region);
		if(!foriq->response) {
			log_err("malloc failed for qclass ANY response"); 
			foriq->state = FINISHED_STATE;
			return;
		}
		foriq->response->qinfo.qclass = forq->qinfo.qclass;
		/* qclass ANY does not receive the AA flag on replies */
		foriq->response->rep->authoritative = 0; 
	} else {
		struct dns_msg* to = foriq->response;
		/* add _from_ this response _to_ existing collection */
		/* if there are records, copy RCODE */
		/* lower sec_state if this message is lower */
		if(from->rep->rrset_count != 0) {
			size_t n = from->rep->rrset_count+to->rep->rrset_count;
			struct ub_packed_rrset_key** dest, **d;
			/* copy appropriate rcode */
			to->rep->flags = from->rep->flags;
			/* copy rrsets */
			if(from->rep->rrset_count > RR_COUNT_MAX ||
				to->rep->rrset_count > RR_COUNT_MAX) {
				log_err("malloc failed (too many rrsets) in collect ANY"); 
				foriq->state = FINISHED_STATE;
				return; /* integer overflow protection */
			}
			dest = regional_alloc(forq->region, sizeof(dest[0])*n);
			if(!dest) {
				log_err("malloc failed in collect ANY"); 
				foriq->state = FINISHED_STATE;
				return;
			}
			d = dest;
			/* copy AN */
			memcpy(dest, to->rep->rrsets, to->rep->an_numrrsets
				* sizeof(dest[0]));
			dest += to->rep->an_numrrsets;
			memcpy(dest, from->rep->rrsets, from->rep->an_numrrsets
				* sizeof(dest[0]));
			dest += from->rep->an_numrrsets;
			/* copy NS */
			memcpy(dest, to->rep->rrsets+to->rep->an_numrrsets,
				to->rep->ns_numrrsets * sizeof(dest[0]));
			dest += to->rep->ns_numrrsets;
			memcpy(dest, from->rep->rrsets+from->rep->an_numrrsets,
				from->rep->ns_numrrsets * sizeof(dest[0]));
			dest += from->rep->ns_numrrsets;
			/* copy AR */
			memcpy(dest, to->rep->rrsets+to->rep->an_numrrsets+
				to->rep->ns_numrrsets,
				to->rep->ar_numrrsets * sizeof(dest[0]));
			dest += to->rep->ar_numrrsets;
			memcpy(dest, from->rep->rrsets+from->rep->an_numrrsets+
				from->rep->ns_numrrsets,
				from->rep->ar_numrrsets * sizeof(dest[0]));
			/* update counts */
			to->rep->rrsets = d;
			to->rep->an_numrrsets += from->rep->an_numrrsets;
			to->rep->ns_numrrsets += from->rep->ns_numrrsets;
			to->rep->ar_numrrsets += from->rep->ar_numrrsets;
			to->rep->rrset_count = n;
		}
		if(from->rep->security < to->rep->security) /* lowest sec */
			to->rep->security = from->rep->security;
		if(from->rep->qdcount != 0) /* insert qd if appropriate */
			to->rep->qdcount = from->rep->qdcount;
		if(from->rep->ttl < to->rep->ttl) /* use smallest TTL */
			to->rep->ttl = from->rep->ttl;
		if(from->rep->prefetch_ttl < to->rep->prefetch_ttl)
			to->rep->prefetch_ttl = from->rep->prefetch_ttl;
		if(from->rep->serve_expired_ttl < to->rep->serve_expired_ttl)
			to->rep->serve_expired_ttl = from->rep->serve_expired_ttl;
	}
	/* are we done? */
	foriq->num_current_queries --;
	if(foriq->num_current_queries == 0)
		foriq->state = FINISHED_STATE;
}
processClassResponse(struct module_qstate* qstate, int id,
	struct module_qstate* forq)
{
	struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id];
	struct dns_msg* from = qstate->return_msg;
	log_query_info(VERB_ALGO, "processClassResponse", &qstate->qinfo);
	log_query_info(VERB_ALGO, "processClassResponse super", &forq->qinfo);
	if(qstate->return_rcode != LDNS_RCODE_NOERROR) {
		 
		foriq->response = NULL;
		foriq->state = FINISHED_STATE;
		return;
	}
	 
	if(!foriq->response) {
		 
		foriq->response = dns_copy_msg(from, forq->region);
		if(!foriq->response) {
			log_err("malloc failed for qclass ANY response"); 
			foriq->state = FINISHED_STATE;
			return;
		}
		foriq->response->qinfo.qclass = forq->qinfo.qclass;
		 
		foriq->response->rep->authoritative = 0; 
	} else {
		struct dns_msg* to = foriq->response;
		 
		 
		 
		if(from->rep->rrset_count != 0) {
			size_t n = from->rep->rrset_count+to->rep->rrset_count;
			struct ub_packed_rrset_key** dest, **d;
			 
			to->rep->flags = from->rep->flags;
			 
			if(from->rep->rrset_count > RR_COUNT_MAX ||
				to->rep->rrset_count > RR_COUNT_MAX) {
				log_err("malloc failed (too many rrsets) in collect ANY"); 
				foriq->state = FINISHED_STATE;
				return;  
			}
			dest = regional_alloc(forq->region, sizeof(dest[0])*n);
			if(!dest) {
				log_err("malloc failed in collect ANY"); 
				foriq->state = FINISHED_STATE;
				return;
			}
			d = dest;
			 
			memcpy(dest, to->rep->rrsets, to->rep->an_numrrsets
				* sizeof(dest[0]));
			dest += to->rep->an_numrrsets;
			memcpy(dest, from->rep->rrsets, from->rep->an_numrrsets
				* sizeof(dest[0]));
			dest += from->rep->an_numrrsets;
			 
			memcpy(dest, to->rep->rrsets+to->rep->an_numrrsets,
				to->rep->ns_numrrsets * sizeof(dest[0]));
			dest += to->rep->ns_numrrsets;
			memcpy(dest, from->rep->rrsets+from->rep->an_numrrsets,
				from->rep->ns_numrrsets * sizeof(dest[0]));
			dest += from->rep->ns_numrrsets;
			 
			memcpy(dest, to->rep->rrsets+to->rep->an_numrrsets+
				to->rep->ns_numrrsets,
				to->rep->ar_numrrsets * sizeof(dest[0]));
			dest += to->rep->ar_numrrsets;
			memcpy(dest, from->rep->rrsets+from->rep->an_numrrsets+
				from->rep->ns_numrrsets,
				from->rep->ar_numrrsets * sizeof(dest[0]));
			 
			to->rep->rrsets = d;
			to->rep->an_numrrsets += from->rep->an_numrrsets;
			to->rep->ns_numrrsets += from->rep->ns_numrrsets;
			to->rep->ar_numrrsets += from->rep->ar_numrrsets;
			to->rep->rrset_count = n;
		}
		if(from->rep->security < to->rep->security)  
			to->rep->security = from->rep->security;
		if(from->rep->qdcount != 0)  
			to->rep->qdcount = from->rep->qdcount;
		if(from->rep->ttl < to->rep->ttl)  
			to->rep->ttl = from->rep->ttl;
		if(from->rep->prefetch_ttl < to->rep->prefetch_ttl)
			to->rep->prefetch_ttl = from->rep->prefetch_ttl;
		if(from->rep->serve_expired_ttl < to->rep->serve_expired_ttl)
			to->rep->serve_expired_ttl = from->rep->serve_expired_ttl;
	}
	 
	foriq->num_current_queries --;
	if(foriq->num_current_queries == 0)
		foriq->state = FINISHED_STATE;
}