Beispiel #1
0
static inline isc_result_t
towire_ch_a(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t sregion;
	isc_region_t tregion;

	REQUIRE(rdata->type == 1);
	REQUIRE(rdata->rdclass == dns_rdataclass_ch);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);

	dns_name_init(&name, offsets);

	dns_rdata_toregion(rdata, &sregion);

	dns_name_fromregion(&name, &sregion);
	isc_region_consume(&sregion, name_length(&name));
	RETERR(dns_name_towire(&name, cctx, target));

	isc_buffer_availableregion(target, &tregion);
	if (tregion.length < 2)
		return (ISC_R_NOSPACE);

	memcpy(tregion.base, sregion.base, 2);
	isc_buffer_add(target, 2);
	return (ISC_R_SUCCESS);
}
Beispiel #2
0
static inline isc_result_t
towire_rp(ARGS_TOWIRE) {
	isc_region_t region;
	dns_name_t rmail;
	dns_name_t email;
	dns_offsets_t roffsets;
	dns_offsets_t eoffsets;

	REQUIRE(rdata->type == dns_rdatatype_rp);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	dns_name_init(&rmail, roffsets);
	dns_name_init(&email, eoffsets);

	dns_rdata_toregion(rdata, &region);

	dns_name_fromregion(&rmail, &region);
	isc_region_consume(&region, rmail.length);

	RETERR(dns_name_towire(&rmail, cctx, target));

	dns_name_fromregion(&rmail, &region);
	isc_region_consume(&region, rmail.length);

	return (dns_name_towire(&rmail, cctx, target));
}
Beispiel #3
0
static inline isc_result_t
towire_in_px(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t region;

	REQUIRE(rdata->type == dns_rdatatype_px);
	REQUIRE(rdata->rdclass == dns_rdataclass_in);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	/*
	 * Preference.
	 */
	dns_rdata_toregion(rdata, &region);
	RETERR(mem_tobuffer(target, region.base, 2));
	isc_region_consume(&region, 2);

	/*
	 * MAP822.
	 */
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &region);
	RETERR(dns_name_towire(&name, cctx, target));
	isc_region_consume(&region, name_length(&name));

	/*
	 * MAPX400.
	 */
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &region);
	return (dns_name_towire(&name, cctx, target));
}
Beispiel #4
0
static inline isc_result_t
towire_soa(ARGS_TOWIRE) {
	isc_region_t sregion;
	isc_region_t tregion;
	dns_name_t mname;
	dns_name_t rname;
	dns_offsets_t moffsets;
	dns_offsets_t roffsets;

	REQUIRE(rdata->type == 6);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);

	dns_name_init(&mname, moffsets);
	dns_name_init(&rname, roffsets);

	dns_rdata_toregion(rdata, &sregion);

	dns_name_fromregion(&mname, &sregion);
	isc_region_consume(&sregion, name_length(&mname));
	RETERR(dns_name_towire(&mname, cctx, target));

	dns_name_fromregion(&rname, &sregion);
	isc_region_consume(&sregion, name_length(&rname));
	RETERR(dns_name_towire(&rname, cctx, target));

	isc_buffer_availableregion(target, &tregion);
	if (tregion.length < 20)
		return (ISC_R_NOSPACE);

	memmove(tregion.base, sregion.base, 20);
	isc_buffer_add(target, 20);
	return (ISC_R_SUCCESS);
}
Beispiel #5
0
static inline isc_result_t
towire_dname(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t region;

	REQUIRE(rdata->type == 39);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	dns_name_init(&name, offsets);
	dns_rdata_toregion(rdata, &region);
	dns_name_fromregion(&name, &region);

	return (dns_name_towire(&name, cctx, target));
}
Beispiel #6
0
static inline isc_result_t
towire_naptr(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t sr;

	REQUIRE(rdata->type == dns_rdatatype_naptr);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	/*
	 * Order, preference.
	 */
	dns_rdata_toregion(rdata, &sr);
	RETERR(mem_tobuffer(target, sr.base, 4));
	isc_region_consume(&sr, 4);

	/*
	 * Flags.
	 */
	RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
	isc_region_consume(&sr, sr.base[0] + 1);

	/*
	 * Service.
	 */
	RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
	isc_region_consume(&sr, sr.base[0] + 1);

	/*
	 * Regexp.
	 */
	RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
	isc_region_consume(&sr, sr.base[0] + 1);

	/*
	 * Replacement.
	 */
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &sr);
	return (dns_name_towire(&name, cctx, target));
}
Beispiel #7
0
static inline isc_result_t
towire_mx(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t region;

	REQUIRE(rdata->type == 15);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);

	dns_rdata_toregion(rdata, &region);
	RETERR(mem_tobuffer(target, region.base, 2));
	isc_region_consume(&region, 2);

	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &region);

	return (dns_name_towire(&name, cctx, target));
}
Beispiel #8
0
static inline isc_result_t
towire_tkey(ARGS_TOWIRE) {
	isc_region_t sr;
	dns_name_t name;
	dns_offsets_t offsets;

	REQUIRE(rdata->type == 249);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	/*
	 * Algorithm.
	 */
	dns_rdata_toregion(rdata, &sr);
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &sr);
	RETERR(dns_name_towire(&name, cctx, target));
	isc_region_consume(&sr, name_length(&name));

	return (mem_tobuffer(target, sr.base, sr.length));
}
Beispiel #9
0
static inline isc_result_t
towire_in_srv(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t sr;

	REQUIRE(rdata->type == 33);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	/*
	 * Priority, weight, port.
	 */
	dns_rdata_toregion(rdata, &sr);
	RETERR(mem_tobuffer(target, sr.base, 6));
	isc_region_consume(&sr, 6);

	/*
	 * Target.
	 */
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &sr);
	return (dns_name_towire(&name, cctx, target));
}
Beispiel #10
0
static inline isc_result_t
towire_sig(ARGS_TOWIRE) {
	isc_region_t sr;
	dns_name_t name;
	dns_offsets_t offsets;

	REQUIRE(rdata->type == dns_rdatatype_sig);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	dns_rdata_toregion(rdata, &sr);
	/*
	 * type covered: 2
	 * algorithm: 1
	 * labels: 1
	 * original ttl: 4
	 * signature expiration: 4
	 * time signed: 4
	 * key footprint: 2
	 */
	RETERR(mem_tobuffer(target, sr.base, 18));
	isc_region_consume(&sr, 18);

	/*
	 * Signer.
	 */
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &sr);
	isc_region_consume(&sr, name_length(&name));
	RETERR(dns_name_towire(&name, cctx, target));

	/*
	 * Signature.
	 */
	return (mem_tobuffer(target, sr.base, sr.length));
}
static inline isc_result_t
towire_rt(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t region;
	isc_region_t tr;

	REQUIRE(rdata->type == 21);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	isc_buffer_availableregion(target, &tr);
	dns_rdata_toregion(rdata, &region);
	if (tr.length < 2)
		return (ISC_R_NOSPACE);
	memmove(tr.base, region.base, 2);
	isc_region_consume(&region, 2);
	isc_buffer_add(target, 2);

	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &region);

	return (dns_name_towire(&name, cctx, target));
}
Beispiel #12
0
isc_result_t
dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
		  isc_buffer_t *target, unsigned int options,
		  unsigned int *countp)
{
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_result_t result;
	isc_region_t remaining, tavailable;
	isc_buffer_t source, savedbuffer, rdlen;
	dns_name_t name;
	dns_rdatatype_t type;
	unsigned int i, rcount, count;

	/*
	 * Convert the negative caching rdataset 'rdataset' to wire format,
	 * compressing names as specified in 'cctx', and storing the result in
	 * 'target'.
	 */

	REQUIRE(rdataset != NULL);
	REQUIRE(rdataset->type == 0);
	REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);

	savedbuffer = *target;
	count = 0;

	result = dns_rdataset_first(rdataset);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(rdataset, &rdata);
		isc_buffer_init(&source, rdata.data, rdata.length);
		isc_buffer_add(&source, rdata.length);
		dns_name_init(&name, NULL);
		isc_buffer_remainingregion(&source, &remaining);
		dns_name_fromregion(&name, &remaining);
		INSIST(remaining.length >= name.length);
		isc_buffer_forward(&source, name.length);
		remaining.length -= name.length;

		INSIST(remaining.length >= 5);
		type = isc_buffer_getuint16(&source);
		isc_buffer_forward(&source, 1);
		rcount = isc_buffer_getuint16(&source);

		for (i = 0; i < rcount; i++) {
			/*
			 * Get the length of this rdata and set up an
			 * rdata structure for it.
			 */
			isc_buffer_remainingregion(&source, &remaining);
			INSIST(remaining.length >= 2);
			dns_rdata_reset(&rdata);
			rdata.length = isc_buffer_getuint16(&source);
			isc_buffer_remainingregion(&source, &remaining);
			rdata.data = remaining.base;
			rdata.type = type;
			rdata.rdclass = rdataset->rdclass;
			INSIST(remaining.length >= rdata.length);
			isc_buffer_forward(&source, rdata.length);

			if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
			    dns_rdatatype_isdnssec(type))
				continue;

			/*
			 * Write the name.
			 */
			dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
			result = dns_name_towire(&name, cctx, target);
			if (result != ISC_R_SUCCESS)
				goto rollback;

			/*
			 * See if we have space for type, class, ttl, and
			 * rdata length.  Write the type, class, and ttl.
			 */
			isc_buffer_availableregion(target, &tavailable);
			if (tavailable.length < 10) {
				result = ISC_R_NOSPACE;
				goto rollback;
			}
			isc_buffer_putuint16(target, type);
			isc_buffer_putuint16(target, rdataset->rdclass);
			isc_buffer_putuint32(target, rdataset->ttl);

			/*
			 * Save space for rdata length.
			 */
			rdlen = *target;
			isc_buffer_add(target, 2);

			/*
			 * Write the rdata.
			 */
			result = dns_rdata_towire(&rdata, cctx, target);
			if (result != ISC_R_SUCCESS)
				goto rollback;

			/*
			 * Set the rdata length field to the compressed
			 * length.
			 */
			INSIST((target->used >= rdlen.used + 2) &&
			       (target->used - rdlen.used - 2 < 65536));
			isc_buffer_putuint16(&rdlen,
					     (isc_uint16_t)(target->used -
							    rdlen.used - 2));

			count++;
		}
		INSIST(isc_buffer_remaininglength(&source) == 0);
		result = dns_rdataset_next(rdataset);
		dns_rdata_reset(&rdata);
	}
	if (result != ISC_R_NOMORE)
		goto rollback;

	*countp = count;

	return (ISC_R_SUCCESS);

 rollback:
	INSIST(savedbuffer.used < 65536);
	dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
	*countp = 0;
	*target = savedbuffer;

	return (result);
}
Beispiel #13
0
static isc_result_t
towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
	     dns_compress_t *cctx, isc_buffer_t *target,
	     dns_rdatasetorderfunc_t order, const void *order_arg,
	     isc_boolean_t partial, unsigned int options,
	     unsigned int *countp, void **state)
{
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_region_t r;
	isc_result_t result;
	unsigned int i, count = 0, added, choice;
	isc_buffer_t savedbuffer, rdlen, rrbuffer;
	unsigned int headlen;
	isc_boolean_t question = ISC_FALSE;
	isc_boolean_t shuffle = ISC_FALSE;
	dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE];
	struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE];

	/* count processed auswer ips */
	int answer_count = 0;
	int is_no_auth_answer    = 0;
	/* tmp count for record */
	int tmp_count = 0;

	UNUSED(state);

	/*
	 * Convert 'rdataset' to wire format, compressing names as specified
	 * in cctx, and storing the result in 'target'.
	 */

	REQUIRE(DNS_RDATASET_VALID(rdataset));
	REQUIRE(countp != NULL);
	REQUIRE((order == NULL) == (order_arg == NULL));
	REQUIRE(cctx != NULL && cctx->mctx != NULL);

	if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
		question = ISC_TRUE;
		count = 1;
		result = dns_rdataset_first(rdataset);
		INSIST(result == ISC_R_NOMORE);
	} else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
		/*
		 * This is a negative caching rdataset.
		 */
		unsigned int ncache_opts = 0;
		if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0)
			ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
		return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
					  countp));
	} else {
		count = (rdataset->methods->count)(rdataset);
		result = dns_rdataset_first(rdataset);
		if (result == ISC_R_NOMORE)
			return (ISC_R_SUCCESS);
		if (result != ISC_R_SUCCESS)
			return (result);
	}

	/*
	 * Do we want to shuffle this answer?
	 */
	if (!question && count > 1 &&
	    (!WANT_FIXED(rdataset) || order != NULL) &&
	    rdataset->type != dns_rdatatype_rrsig)
		shuffle = ISC_TRUE;

	if (shuffle && count > MAX_SHUFFLE) {
		shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled));
		sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted));
		if (shuffled == NULL || sorted == NULL)
			shuffle = ISC_FALSE;
	} else {
		shuffled = shuffled_fixed;
		sorted = sorted_fixed;
	}

	if (shuffle) {
		/*
		 * First we get handles to all of the rdata.
		 */
		i = 0;
		do {
			INSIST(i < count);
			dns_rdata_init(&shuffled[i]);
			dns_rdataset_current(rdataset, &shuffled[i]);
			i++;
			result = dns_rdataset_next(rdataset);
		} while (result == ISC_R_SUCCESS);
		if (result != ISC_R_NOMORE)
			goto cleanup;
		INSIST(i == count);

		/*
		 * Now we shuffle.
		 */
		if (WANT_FIXED(rdataset)) {
			/*
			 * 'Fixed' order.
			 */
			INSIST(order != NULL);
			for (i = 0; i < count; i++) {
				sorted[i].key = (*order)(&shuffled[i],
							 order_arg);
				sorted[i].rdata = &shuffled[i];
			}
		} else if (WANT_RANDOM(rdataset)) {
			/*
			 * 'Random' order.
			 */
			for (i = 0; i < count; i++) {
				dns_rdata_t rdata;
				isc_uint32_t val;

				isc_random_get(&val);
				choice = i + (val % (count - i));
				rdata = shuffled[i];
				shuffled[i] = shuffled[choice];
				shuffled[choice] = rdata;
				if (order != NULL)
					sorted[i].key = (*order)(&shuffled[i],
								 order_arg);
				else
					sorted[i].key = 0; /* Unused */
				sorted[i].rdata = &shuffled[i];
			}
		} else {
			/*
			 * "Cyclic" order.
			 */
			isc_uint32_t val;
			unsigned int j;

			val = rdataset->count;
			if (val == ISC_UINT32_MAX)
				isc_random_get(&val);
			j = val % count;
			for (i = 0; i < count; i++) {
				if (order != NULL)
					sorted[i].key = (*order)(&shuffled[j],
								 order_arg);
				else
					sorted[i].key = 0; /* Unused */
				sorted[i].rdata = &shuffled[j];
				j++;
				if (j == count)
					j = 0; /* Wrap around. */
			}
		}

		/*
		 * Sorted order.
		 */
		if (order != NULL)
			qsort(sorted, count, sizeof(sorted[0]),
			      towire_compare);
	}

	savedbuffer = *target;
	i = 0;
	added = 0;

	// save the count here
	tmp_count = count;

	do {
		/*
		 * Copy out the name, type, class, ttl.
		 */
			/* mark if is answer data. */
			is_no_auth_answer = 0;
			/* Answer from a non-authoritative server,we set the ttl fixed as 500. */
			if(rdataset->attributes == DNS_RDATASETATTR_LOADORDER && 
					rdataset->type == dns_rdatatype_a){
				/* Answer from a non-authoritative server,we set the ttl fixed as 500. */
				if(rdataset->trust == dns_trust_answer ){
					is_no_auth_answer = 1;
				}

				/* for all multi-ip answer,if set DNS_ANSWER_ONLY_ONE_IP flag, return only 1 ip. */
				if(answer_count == 0){
					answer_count ++;
				}else{
					if( DNS_ANSWER_ONLY_ONE_IP ){
						//fprintf(stderr,"DNS_ANSWER_ONLY_ONE_IP set,skip. \n");
						if (shuffle) {
							tmp_count--;
							if (i == tmp_count)
								result = ISC_R_NOMORE;
							else
								result = ISC_R_SUCCESS;
						} else {
							result = dns_rdataset_next(rdataset);
						}
						continue;
					}
				}
			}


			rrbuffer = *target;
		dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
		result = dns_name_towire(owner_name, cctx, target);
		if (result != ISC_R_SUCCESS)
			goto rollback;
		headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
		if (!question)
			headlen += sizeof(dns_ttl_t)
				+ 2;  /* XXX 2 for rdata len */
		isc_buffer_availableregion(target, &r);
		if (r.length < headlen) {
			result = ISC_R_NOSPACE;
			goto rollback;
		}

		isc_buffer_putuint16(target, rdataset->type);
		isc_buffer_putuint16(target, rdataset->rdclass);
		if (!question) {
			
			if( is_no_auth_answer ){
					isc_buffer_putuint32(target, DNS_DEFAULT_TTL_FOR_NO_AUTH_NAME);
			}else{
					isc_buffer_putuint32(target, rdataset->ttl);
			}
			//fprintf(stderr,"xxxxxxxxx:trust : %d artr: %d ttl:%d  cover: %d type: %d count: %d class: %d\n", rdataset->trust,rdataset->attributes,rdataset->ttl, rdataset->covers,rdataset->type, rdataset->count, rdataset->rdclass);

			/*
			 * Save space for rdlen.
			 */
			rdlen = *target;
			isc_buffer_add(target, 2);

			/*
			 * Copy out the rdata
			 */
			if (shuffle)
				rdata = *(sorted[i].rdata);
			else {
				dns_rdata_reset(&rdata);
				dns_rdataset_current(rdataset, &rdata);
			}
			result = dns_rdata_towire(&rdata, cctx, target);
			if (result != ISC_R_SUCCESS)
				goto rollback;
			INSIST((target->used >= rdlen.used + 2) &&
			       (target->used - rdlen.used - 2 < 65536));
			isc_buffer_putuint16(&rdlen,
					     (isc_uint16_t)(target->used -
							    rdlen.used - 2));
			added++;
		}

		if (shuffle) {
			i++;
			if (i == tmp_count)
				result = ISC_R_NOMORE;
			else
				result = ISC_R_SUCCESS;
		} else {
			result = dns_rdataset_next(rdataset);
		}
	} while (result == ISC_R_SUCCESS);

	if (result != ISC_R_NOMORE)
		goto rollback;

	*countp += tmp_count;

	result = ISC_R_SUCCESS;
	goto cleanup;

 rollback:
	if (partial && result == ISC_R_NOSPACE) {
		INSIST(rrbuffer.used < 65536);
		dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used);
		*countp += added;
		*target = rrbuffer;
		goto cleanup;
	}
	INSIST(savedbuffer.used < 65536);
	dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
	*countp = 0;
	*target = savedbuffer;

 cleanup:
	if (sorted != NULL && sorted != sorted_fixed)
		isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted));
	if (shuffled != NULL && shuffled != shuffled_fixed)
		isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled));
	return (result);
}
Beispiel #14
0
ATF_TC_BODY(send, tc) {
	isc_result_t result;
	dns_dtenv_t *dtenv = NULL;
	dns_dthandle_t handle;
	isc_uint8_t *data;
	size_t dsize;
	unsigned char zone[DNS_NAME_MAXWIRE];
	unsigned char qambuffer[4096], rambuffer[4096];
	unsigned char qrmbuffer[4096], rrmbuffer[4096];
	isc_buffer_t zb, qamsg, ramsg, qrmsg, rrmsg;
	size_t qasize, qrsize, rasize, rrsize;
	dns_fixedname_t zfname;
	dns_name_t *zname;
	dns_dtmsgtype_t dt;
	dns_view_t *view = NULL;
	dns_compress_t cctx;
	isc_region_t zr;
	isc_sockaddr_t addr;
	struct in_addr in;
	isc_stdtime_t now;
	isc_time_t p, f;

	UNUSED(tc);

	cleanup();

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE(result == ISC_R_SUCCESS);

	result = dns_test_makeview("test", &view);

	result = dns_dt_create(mctx, dns_dtmode_file, TAPFILE, 1, &dtenv);
	ATF_REQUIRE(result == ISC_R_SUCCESS);

	dns_dt_attach(dtenv, &view->dtenv);
	view->dttypes = DNS_DTTYPE_ALL;

	/*
	 * Set up some test data
	 */
	dns_fixedname_init(&zfname);
	zname = dns_fixedname_name(&zfname);
	isc_buffer_constinit(&zb, "example.com.", 12);
	isc_buffer_add(&zb, 12);
	result = dns_name_fromtext(zname, &zb, NULL, 0, NULL);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	memset(&zr, 0, sizeof(zr));
	isc_buffer_init(&zb, zone, sizeof(zone));
	result = dns_compress_init(&cctx, -1, mctx);
	dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE);
	result = dns_name_towire(zname, &cctx, &zb);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	dns_compress_invalidate(&cctx);
	isc_buffer_usedregion(&zb, &zr);

	in.s_addr = inet_addr("10.53.0.1");
	isc_sockaddr_fromin(&addr, &in, 2112);

	isc_stdtime_get(&now);
	isc_time_set(&p, now - 3600, 0); /* past */
	isc_time_set(&f, now + 3600, 0); /* future */

	result = dns_test_getdata("testdata/dnstap/query.auth",
				  qambuffer, sizeof(qambuffer), &qasize);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_buffer_init(&qamsg, qambuffer, qasize);
	isc_buffer_add(&qamsg, qasize);

	result = dns_test_getdata("testdata/dnstap/response.auth",
				  rambuffer, sizeof(rambuffer), &rasize);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_buffer_init(&ramsg, rambuffer, rasize);
	isc_buffer_add(&ramsg, rasize);

	result = dns_test_getdata("testdata/dnstap/query.recursive", qrmbuffer,
				  sizeof(qrmbuffer), &qrsize);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_buffer_init(&qrmsg, qrmbuffer, qrsize);
	isc_buffer_add(&qrmsg, qrsize);

	result = dns_test_getdata("testdata/dnstap/response.recursive",
				  rrmbuffer, sizeof(rrmbuffer), &rrsize);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_buffer_init(&rrmsg, rrmbuffer, rrsize);
	isc_buffer_add(&rrmsg, rrsize);

	for (dt = DNS_DTTYPE_SQ; dt <= DNS_DTTYPE_TR; dt <<= 1) {
		isc_buffer_t *m;

		switch (dt) {
		case DNS_DTTYPE_AQ:
			m = &qamsg;
			break;
		case DNS_DTTYPE_AR:
			m = &ramsg;
			break;
		default:
			m = &qrmsg;
			if ((dt & DNS_DTTYPE_RESPONSE) != 0)
				m = &ramsg;
			break;
		}

		dns_dt_send(view, dt, &addr, ISC_FALSE, &zr, &p, &f, m);
		dns_dt_send(view, dt, &addr, ISC_FALSE, &zr, NULL, &f, m);
		dns_dt_send(view, dt, &addr, ISC_FALSE, &zr, &p, NULL, m);
		dns_dt_send(view, dt, &addr, ISC_FALSE, &zr, NULL, NULL, m);
		dns_dt_send(view, dt, &addr, ISC_TRUE, &zr, &p, &f, m);
		dns_dt_send(view, dt, &addr, ISC_TRUE, &zr, NULL, &f, m);
		dns_dt_send(view, dt, &addr, ISC_TRUE, &zr, &p, NULL, m);
		dns_dt_send(view, dt, &addr, ISC_TRUE, &zr, NULL, NULL, m);
	}

	dns_dt_detach(&view->dtenv);
	dns_dt_detach(&dtenv);
	dns_dt_shutdown();
	dns_view_detach(&view);

	/*
	 * XXX now read back and check content.
	 */

	result = dns_dt_open(TAPFILE, dns_dtmode_file, &handle);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	while (dns_dt_getframe(&handle, &data, &dsize) == ISC_R_SUCCESS) {
		dns_dtdata_t *dtdata = NULL;
		isc_region_t r;
		static dns_dtmsgtype_t expected = DNS_DTTYPE_SQ;
		static int n = 0;

		r.base = data;
		r.length = dsize;

		result = dns_dt_parse(mctx, &r, &dtdata);
		ATF_CHECK_EQ(result, ISC_R_SUCCESS);
		if (result != ISC_R_SUCCESS) {
			n++;
			continue;
		}

		ATF_CHECK_EQ(dtdata->type, expected);
		if (++n % 8 == 0)
			expected <<= 1;

		dns_dtdata_free(&dtdata);
	}

	dns_dt_close(&handle);
	cleanup();

	dns_test_end();
}
Beispiel #15
0
void
test(unsigned int allowed, dns_name_t *name1, dns_name_t *name2,
     dns_name_t *name3, unsigned char *result, unsigned int length)
{
	isc_mem_t *mctx = NULL;
	dns_compress_t cctx;
	dns_decompress_t dctx;
	isc_buffer_t source;
	isc_buffer_t target;
	dns_name_t name;
	unsigned char buf1[1024];
	unsigned char buf2[1024];

	if (verbose) {
		const char *s;
		switch (allowed) {
		case DNS_COMPRESS_NONE: s = "DNS_COMPRESS_NONE"; break;
		case DNS_COMPRESS_GLOBAL14: s = "DNS_COMPRESS_GLOBAL14"; break;
		/* case DNS_COMPRESS_ALL: s = "DNS_COMPRESS_ALL"; break; */
		default: s = "UNKNOWN"; break;
		}
		fprintf(stdout, "Allowed = %s\n", s);
	}
	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	isc_buffer_init(&source, buf1, sizeof(buf1));
	RUNTIME_CHECK(dns_compress_init(&cctx, -1, mctx) == ISC_R_SUCCESS);

	RUNTIME_CHECK(dns_name_towire(name1, &cctx, &source) == ISC_R_SUCCESS);

	/*
	RUNTIME_CHECK(dns_compress_localinit(&cctx, name1, &source) ==
		      ISC_R_SUCCESS);
	*/
	dns_compress_setmethods(&cctx, allowed);
	RUNTIME_CHECK(dns_name_towire(name2, &cctx, &source) == ISC_R_SUCCESS);
	RUNTIME_CHECK(dns_name_towire(name2, &cctx, &source) == ISC_R_SUCCESS);
	RUNTIME_CHECK(dns_name_towire(name3, &cctx, &source) == ISC_R_SUCCESS);

	/*
	dns_compress_localinvalidate(&cctx);
	*/
	dns_compress_rollback(&cctx, 0);	/* testing only */
	dns_compress_invalidate(&cctx);

	if (raw) {
		unsigned int i;
		for (i = 0; i < source.used; /* */ ) {
			fprintf(stdout, "%02x",
				((unsigned char *)source.base)[i]);
			if ((++i % 20) == 0)
				fputs("\n", stdout);
			else
				if (i == source.used)
					fputs("\n", stdout);
				else
					fputs(" ", stdout);
		}
	}

	isc_buffer_setactive(&source, source.used);
	isc_buffer_init(&target, buf2, sizeof(buf2));
	dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);

	dns_name_init(&name, NULL);
	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
					&target) == ISC_R_SUCCESS);
	dns_decompress_setmethods(&dctx, allowed);
	/*
	dns_decompress_localinit(&dctx, &name, &source);
	*/
	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
					&target) == ISC_R_SUCCESS);
	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
					&target) == ISC_R_SUCCESS);
	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
					&target) == ISC_R_SUCCESS);
	/*
	dns_decompress_localinvalidate(&dctx);
	*/
	dns_decompress_invalidate(&dctx);

	if (raw) {
		unsigned int i;
		for (i = 0; i < target.used; /* */ ) {
			fprintf(stdout, "%02x",
				((unsigned char *)target.base)[i]);
			if ((++i % 20) == 0)
				fputs("\n", stdout);
			else
				if (i == target.used)
					fputs("\n", stdout);
				else
					fputs(" ", stdout);
		}
		fputs("\n", stdout);
		fflush(stdout);
	}

	RUNTIME_CHECK(target.used == length);
	RUNTIME_CHECK(memcmp(target.base, result, target.used) == 0);
	isc_mem_destroy(&mctx);
}