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, ®ion); RETERR(mem_tobuffer(target, region.base, 2)); isc_region_consume(®ion, 2); /* * MAP822. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); RETERR(dns_name_towire(&name, cctx, target)); isc_region_consume(®ion, name_length(&name)); /* * MAPX400. */ dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); }
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, ®ion); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, rmail.length); RETERR(dns_name_towire(&rmail, cctx, target)); dns_name_fromregion(&rmail, ®ion); isc_region_consume(®ion, rmail.length); return (dns_name_towire(&rmail, cctx, target)); }
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); }
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); }
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, ®ion); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); }
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)); }
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, ®ion); RETERR(mem_tobuffer(target, region.base, 2)); isc_region_consume(®ion, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); }
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)); }
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)); }
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, ®ion); if (tr.length < 2) return (ISC_R_NOSPACE); memmove(tr.base, region.base, 2); isc_region_consume(®ion, 2); isc_buffer_add(target, 2); dns_name_init(&name, offsets); dns_name_fromregion(&name, ®ion); return (dns_name_towire(&name, cctx, target)); }
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); }
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); }
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(); }
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); }