val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
{
	if(!qstate->return_msg || qstate->return_rcode != LDNS_RCODE_NOERROR) {
		/* create a message to verify */
		verbose(VERB_ALGO, "constructing reply for validation");
		vq->orig_msg = (struct dns_msg*)regional_alloc(qstate->region,
			sizeof(struct dns_msg));
		if(!vq->orig_msg)
			return NULL;
		vq->orig_msg->qinfo = qstate->qinfo;
		vq->orig_msg->rep = (struct reply_info*)regional_alloc(
			qstate->region, sizeof(struct reply_info));
		if(!vq->orig_msg->rep)
			return NULL;
		memset(vq->orig_msg->rep, 0, sizeof(struct reply_info));
		vq->orig_msg->rep->flags = (uint16_t)(qstate->return_rcode&0xf)
			|BIT_QR|BIT_RA|(qstate->query_flags|(BIT_CD|BIT_RD));
		vq->orig_msg->rep->qdcount = 1;
		vq->orig_msg->rep->reason_bogus = LDNS_EDE_NONE;
	} else {
		vq->orig_msg = qstate->return_msg;
	}
	vq->qchase = qstate->qinfo;
	/* chase reply will be an edited (sub)set of the orig msg rrset ptrs */
	vq->chase_reply = regional_alloc_init(qstate->region, 
		vq->orig_msg->rep, 
		sizeof(struct reply_info) - sizeof(struct rrset_ref));
	if(!vq->chase_reply)
		return NULL;
	if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX)
		return NULL; /* protect against integer overflow */
	vq->chase_reply->rrsets = regional_alloc_init(qstate->region,
		vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*)
			* vq->orig_msg->rep->rrset_count);
	if(!vq->chase_reply->rrsets)
		return NULL;
	vq->rrset_skip = 0;
	return vq;
}
val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
{
	if(!qstate->return_msg || qstate->return_rcode != LDNS_RCODE_NOERROR) {
		 
		verbose(VERB_ALGO, "constructing reply for validation");
		vq->orig_msg = (struct dns_msg*)regional_alloc(qstate->region,
			sizeof(struct dns_msg));
		if(!vq->orig_msg)
			return NULL;
		vq->orig_msg->qinfo = qstate->qinfo;
		vq->orig_msg->rep = (struct reply_info*)regional_alloc(
			qstate->region, sizeof(struct reply_info));
		if(!vq->orig_msg->rep)
			return NULL;
		memset(vq->orig_msg->rep, 0, sizeof(struct reply_info));
		vq->orig_msg->rep->flags = (uint16_t)(qstate->return_rcode&0xf)
			|BIT_QR|BIT_RA|(qstate->query_flags|(BIT_CD|BIT_RD));
		vq->orig_msg->rep->qdcount = 1;
		vq->orig_msg->rep->reason_bogus = LDNS_EDE_NONE;
	} else {
		vq->orig_msg = qstate->return_msg;
	}
	vq->qchase = qstate->qinfo;
	 
	vq->chase_reply = regional_alloc_init(qstate->region, 
		vq->orig_msg->rep, 
		sizeof(struct reply_info) - sizeof(struct rrset_ref));
	if(!vq->chase_reply)
		return NULL;
	if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX)
		return NULL;  
	vq->chase_reply->rrsets = regional_alloc_init(qstate->region,
		vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*)
			* vq->orig_msg->rep->rrset_count);
	if(!vq->chase_reply->rrsets)
		return NULL;
	vq->rrset_skip = 0;
	return vq;
}