dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk, 
		      const struct packed_rrset_data* fd, 
		      struct ub_packed_rrset_key *dk, 
		      struct packed_rrset_data **dd_out, struct regional *region, 
		      struct dns64_env* dns64_env )
{
	struct packed_rrset_data *dd;
	size_t i;
	/*
	 * Create synthesized AAAA RR set data. We need to allocated extra memory
	 * for the RRs themselves. Each RR has a length, TTL, pointer to wireformat
	 * data, 2 bytes of data length, and 16 bytes of IPv6 address.
	 */
	if(fd->count > RR_COUNT_MAX) {
		*dd_out = NULL;
		return; /* integer overflow protection in alloc */
	}
	if (!(dd = *dd_out = regional_alloc_zero(region,
		  sizeof(struct packed_rrset_data)
		  + fd->count * (sizeof(size_t) + sizeof(time_t) +
			     sizeof(uint8_t*) + 2 + 16)))) {
		log_err("out of memory");
		return;
	}

	/* Copy attributes from A RR set. */
	dd->ttl = fd->ttl;
	dd->count = fd->count;
	dd->rrsig_count = 0;
	dd->trust = fd->trust;
	dd->security = fd->security;

	/*
	 * Synthesize AAAA records. Adjust pointers in structure.
	 */
	dd->rr_len =
	    (size_t*)((uint8_t*)dd + sizeof(struct packed_rrset_data));
	dd->rr_data = (uint8_t**)&dd->rr_len[dd->count];
	dd->rr_ttl = (time_t*)&dd->rr_data[dd->count];
	for(i = 0; i < fd->count; ++i) {
		if (fd->rr_len[i] != 6 || fd->rr_data[i][0] != 0
		    || fd->rr_data[i][1] != 4) {
			*dd_out = NULL;
			return;
		}
		dd->rr_len[i] = 18;
		dd->rr_data[i] =
		    (uint8_t*)&dd->rr_ttl[dd->count] + 18*i;
		dd->rr_data[i][0] = 0;
		dd->rr_data[i][1] = 16;
		synthesize_aaaa(
				((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
				sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr),
				dns64_env->prefix_net, &fd->rr_data[i][2],
				fd->rr_len[i]-2, &dd->rr_data[i][2],
				dd->rr_len[i]-2);
		dd->rr_ttl[i] = fd->rr_ttl[i];
	}

	/*
	 * Create synthesized AAAA RR set key. This is mostly just bookkeeping,
	 * nothing interesting here.
	 */
	if(!dk) {
		log_err("no key");
		*dd_out = NULL;
		return;
	}

	dk->rk.dname = (uint8_t*)regional_alloc_init(region,
		     fk->rk.dname, fk->rk.dname_len);

	if(!dk->rk.dname) {
		log_err("out of memory");
		*dd_out = NULL;
		return;
	}

	dk->rk.type = htons(LDNS_RR_TYPE_AAAA);
	memset(&dk->entry, 0, sizeof(dk->entry));
	dk->entry.key = dk;
	dk->entry.hash = rrset_key_hash(&dk->rk);
	dk->entry.data = dd;

}
dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk, 
		      const struct packed_rrset_data* fd, 
		      struct ub_packed_rrset_key *dk, 
		      struct packed_rrset_data **dd_out, struct regional *region, 
		      struct dns64_env* dns64_env )
{
	struct packed_rrset_data *dd;
	size_t i;
	 
	if(fd->count > RR_COUNT_MAX) {
		*dd_out = NULL;
		return;  
	}
	if (!(dd = *dd_out = regional_alloc_zero(region,
		  sizeof(struct packed_rrset_data)
		  + fd->count * (sizeof(size_t) + sizeof(time_t) +
			     sizeof(uint8_t*) + 2 + 16)))) {
		log_err("out of memory");
		return;
	}

	 
	dd->ttl = fd->ttl;
	dd->count = fd->count;
	dd->rrsig_count = 0;
	dd->trust = fd->trust;
	dd->security = fd->security;

	 
	dd->rr_len =
	    (size_t*)((uint8_t*)dd + sizeof(struct packed_rrset_data));
	dd->rr_data = (uint8_t**)&dd->rr_len[dd->count];
	dd->rr_ttl = (time_t*)&dd->rr_data[dd->count];
	for(i = 0; i < fd->count; ++i) {
		if (fd->rr_len[i] != 6 || fd->rr_data[i][0] != 0
		    || fd->rr_data[i][1] != 4) {
			*dd_out = NULL;
			return;
		}
		dd->rr_len[i] = 18;
		dd->rr_data[i] =
		    (uint8_t*)&dd->rr_ttl[dd->count] + 18*i;
		dd->rr_data[i][0] = 0;
		dd->rr_data[i][1] = 16;
		synthesize_aaaa(
				((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
				sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr),
				dns64_env->prefix_net, &fd->rr_data[i][2],
				fd->rr_len[i]-2, &dd->rr_data[i][2],
				dd->rr_len[i]-2);
		dd->rr_ttl[i] = fd->rr_ttl[i];
	}

	 
	if(!dk) {
		log_err("no key");
		*dd_out = NULL;
		return;
	}

	dk->rk.dname = (uint8_t*)regional_alloc_init(region,
		     fk->rk.dname, fk->rk.dname_len);

	if(!dk->rk.dname) {
		log_err("out of memory");
		*dd_out = NULL;
		return;
	}

	dk->rk.type = htons(LDNS_RR_TYPE_AAAA);
	memset(&dk->entry, 0, sizeof(dk->entry));
	dk->entry.key = dk;
	dk->entry.hash = rrset_key_hash(&dk->rk);
	dk->entry.data = dd;

}