/* * Load test data into the RBT. */ static void add_test_data(isc_mem_t *mymctx, dns_rbt_t *rbt) { char buffer[1024]; isc_buffer_t b; isc_result_t result; dns_fixedname_t fname; dns_name_t *name; dns_compress_t cctx; rbt_testdata_t *testdatap = testdata; dns_compress_init(&cctx, -1, mymctx); while (testdatap->name != NULL && testdatap->data.data != NULL) { memmove(buffer, testdatap->name, testdatap->name_len); isc_buffer_init(&b, buffer, testdatap->name_len); isc_buffer_add(&b, testdatap->name_len); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { testdatap++; continue; } if (name != NULL) { result = dns_rbt_addname(rbt, name, &testdatap->data); ATF_CHECK_STREQ(dns_result_totext(result), "success"); } testdatap++; } dns_compress_invalidate(&cctx); }
/* * Arrange to send as much as we can of "stream" without blocking. * * Requires: * The stream iterator is initialized and points at an RR, * or possibly at the end of the stream (that is, the * _first method of the iterator has been called). */ static void sendstream(xfrout_ctx_t *xfr) { dns_message_t *tcpmsg = NULL; dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ isc_result_t result; isc_region_t used; isc_region_t region; dns_rdataset_t *qrdataset; dns_name_t *msgname = NULL; dns_rdata_t *msgrdata = NULL; dns_rdatalist_t *msgrdl = NULL; dns_rdataset_t *msgrds = NULL; dns_compress_t cctx; isc_boolean_t cleanup_cctx = ISC_FALSE; isc_boolean_t is_tcp; int n_rrs; isc_buffer_clear(&xfr->buf); isc_buffer_clear(&xfr->txlenbuf); isc_buffer_clear(&xfr->txbuf); is_tcp = ISC_TF((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0); if (!is_tcp) { /* * In the UDP case, we put the response data directly into * the client message. */ msg = xfr->client->message; CHECK(dns_message_reply(msg, ISC_TRUE)); } else { /* * TCP. Build a response dns_message_t, temporarily storing * the raw, uncompressed owner names and RR data contiguously * in xfr->buf. We know that if the uncompressed data fits * in xfr->buf, the compressed data will surely fit in a TCP * message. */ CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &tcpmsg)); msg = tcpmsg; msg->id = xfr->id; msg->rcode = dns_rcode_noerror; msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) msg->flags |= DNS_MESSAGEFLAG_RA; CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); /* * Add a EDNS option to the message? */ if ((xfr->client->attributes & NS_CLIENTATTR_WANTOPT) != 0) { dns_rdataset_t *opt = NULL; CHECK(ns_client_addopt(xfr->client, msg, &opt)); CHECK(dns_message_setopt(msg, opt)); /* * Add to first message only. */ xfr->client->attributes &= ~NS_CLIENTATTR_WANTNSID; xfr->client->attributes &= ~NS_CLIENTATTR_HAVEEXPIRE; } /* * Account for reserved space. */ if (xfr->tsigkey != NULL) INSIST(msg->reserved != 0U); isc_buffer_add(&xfr->buf, msg->reserved); /* * Include a question section in the first message only. * BIND 8.2.1 will not recognize an IXFR if it does not * have a question section. */ if (xfr->nmsg == 0) { dns_name_t *qname = NULL; isc_region_t r; /* * Reserve space for the 12-byte message header * and 4 bytes of question. */ isc_buffer_add(&xfr->buf, 12 + 4); qrdataset = NULL; result = dns_message_gettemprdataset(msg, &qrdataset); if (result != ISC_R_SUCCESS) goto failure; dns_rdataset_makequestion(qrdataset, xfr->client->message->rdclass, xfr->qtype); result = dns_message_gettempname(msg, &qname); if (result != ISC_R_SUCCESS) goto failure; dns_name_init(qname, NULL); isc_buffer_availableregion(&xfr->buf, &r); INSIST(r.length >= xfr->qname->length); r.length = xfr->qname->length; isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, xfr->qname->length); dns_name_fromregion(qname, &r); ISC_LIST_INIT(qname->list); ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(msg, qname, DNS_SECTION_QUESTION); } else { /* * Reserve space for the 12-byte message header */ isc_buffer_add(&xfr->buf, 12); msg->tcp_continuation = 1; } } /* * Try to fit in as many RRs as possible, unless "one-answer" * format has been requested. */ for (n_rrs = 0; ; n_rrs++) { dns_name_t *name = NULL; isc_uint32_t ttl; dns_rdata_t *rdata = NULL; unsigned int size; isc_region_t r; msgname = NULL; msgrdata = NULL; msgrdl = NULL; msgrds = NULL; xfr->stream->methods->current(xfr->stream, &name, &ttl, &rdata); size = name->length + 10 + rdata->length; isc_buffer_availableregion(&xfr->buf, &r); if (size >= r.length) { /* * RR would not fit. If there are other RRs in the * buffer, send them now and leave this RR to the * next message. If this RR overflows the buffer * all by itself, fail. * * In theory some RRs might fit in a TCP message * when compressed even if they do not fit when * uncompressed, but surely we don't want * to send such monstrosities to an unsuspecting * slave. */ if (n_rrs == 0) { xfrout_log(xfr, ISC_LOG_WARNING, "RR too large for zone transfer " "(%d bytes)", size); /* XXX DNS_R_RRTOOLARGE? */ result = ISC_R_NOSPACE; goto failure; } break; } if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) log_rr(name, rdata, ttl); /* XXX */ result = dns_message_gettempname(msg, &msgname); if (result != ISC_R_SUCCESS) goto failure; dns_name_init(msgname, NULL); isc_buffer_availableregion(&xfr->buf, &r); INSIST(r.length >= name->length); r.length = name->length; isc_buffer_putmem(&xfr->buf, name->ndata, name->length); dns_name_fromregion(msgname, &r); /* Reserve space for RR header. */ isc_buffer_add(&xfr->buf, 10); result = dns_message_gettemprdata(msg, &msgrdata); if (result != ISC_R_SUCCESS) goto failure; isc_buffer_availableregion(&xfr->buf, &r); r.length = rdata->length; isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); dns_rdata_init(msgrdata); dns_rdata_fromregion(msgrdata, rdata->rdclass, rdata->type, &r); result = dns_message_gettemprdatalist(msg, &msgrdl); if (result != ISC_R_SUCCESS) goto failure; msgrdl->type = rdata->type; msgrdl->rdclass = rdata->rdclass; msgrdl->ttl = ttl; if (rdata->type == dns_rdatatype_sig || rdata->type == dns_rdatatype_rrsig) msgrdl->covers = dns_rdata_covers(rdata); else msgrdl->covers = dns_rdatatype_none; ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); result = dns_message_gettemprdataset(msg, &msgrds); if (result != ISC_R_SUCCESS) goto failure; result = dns_rdatalist_tordataset(msgrdl, msgrds); INSIST(result == ISC_R_SUCCESS); ISC_LIST_APPEND(msgname->list, msgrds, link); dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); msgname = NULL; result = xfr->stream->methods->next(xfr->stream); if (result == ISC_R_NOMORE) { xfr->end_of_stream = ISC_TRUE; break; } CHECK(result); if (! xfr->many_answers) break; /* * At this stage, at least 1 RR has been rendered into * the message. Check if we want to clamp this message * here (TCP only). 20480 was set as an upper limit to * improve message compression. */ if ((isc_buffer_usedlength(&xfr->buf) >= 20480) && is_tcp) break; } if (is_tcp) { CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); dns_compress_setsensitive(&cctx, ISC_TRUE); cleanup_cctx = ISC_TRUE; CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); CHECK(dns_message_renderend(msg)); dns_compress_invalidate(&cctx); cleanup_cctx = ISC_FALSE; isc_buffer_usedregion(&xfr->txbuf, &used); isc_buffer_putuint16(&xfr->txlenbuf, (isc_uint16_t)used.length); region.base = xfr->txlenbuf.base; region.length = 2 + used.length; xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending TCP message of %d bytes", used.length); CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ ®ion, xfr->client->task, xfrout_senddone, xfr)); xfr->sends++; } else { xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); ns_client_send(xfr->client); xfr->stream->methods->pause(xfr->stream); xfrout_ctx_destroy(&xfr); return; } /* Advance lasttsig to be the last TSIG generated */ CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); xfr->nmsg++; failure: if (msgname != NULL) { if (msgrds != NULL) { if (dns_rdataset_isassociated(msgrds)) dns_rdataset_disassociate(msgrds); dns_message_puttemprdataset(msg, &msgrds); } if (msgrdl != NULL) { ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); dns_message_puttemprdatalist(msg, &msgrdl); } if (msgrdata != NULL) dns_message_puttemprdata(msg, &msgrdata); dns_message_puttempname(msg, &msgname); } if (tcpmsg != NULL) dns_message_destroy(&tcpmsg); if (cleanup_cctx) dns_compress_invalidate(&cctx); /* * Make sure to release any locks held by database * iterators before returning from the event handler. */ xfr->stream->methods->pause(xfr->stream); if (result == ISC_R_SUCCESS) return; xfrout_fail(xfr, result, "sending zone data"); }
static void buildquery(void) { isc_result_t result; dns_rdataset_t *question = NULL; dns_name_t *qname = NULL; isc_region_t r, inr; dns_message_t *query; char nametext[] = "host.example"; isc_buffer_t namesrc, namedst; unsigned char namedata[256]; isc_sockaddr_t sa; dns_compress_t cctx; query = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query); CHECK("dns_message_create", result); result = dns_message_setsig0key(query, key); CHECK("dns_message_setsig0key", result); result = dns_message_gettemprdataset(query, &question); CHECK("dns_message_gettemprdataset", result); dns_rdataset_init(question); dns_rdataset_makequestion(question, dns_rdataclass_in, dns_rdatatype_a); result = dns_message_gettempname(query, &qname); CHECK("dns_message_gettempname", result); isc_buffer_init(&namesrc, nametext, strlen(nametext)); isc_buffer_add(&namesrc, strlen(nametext)); isc_buffer_init(&namedst, namedata, sizeof(namedata)); dns_name_init(qname, NULL); result = dns_name_fromtext(qname, &namesrc, dns_rootname, ISC_FALSE, &namedst); CHECK("dns_name_fromtext", result); ISC_LIST_APPEND(qname->list, question, link); dns_message_addname(query, qname, DNS_SECTION_QUESTION); isc_buffer_init(&qbuffer, qdata, sizeof(qdata)); result = dns_compress_init(&cctx, -1, mctx); CHECK("dns_compress_init", result); result = dns_message_renderbegin(query, &cctx, &qbuffer); CHECK("dns_message_renderbegin", result); result = dns_message_rendersection(query, DNS_SECTION_QUESTION, 0); CHECK("dns_message_rendersection(question)", result); result = dns_message_rendersection(query, DNS_SECTION_ANSWER, 0); CHECK("dns_message_rendersection(answer)", result); result = dns_message_rendersection(query, DNS_SECTION_AUTHORITY, 0); CHECK("dns_message_rendersection(auth)", result); result = dns_message_rendersection(query, DNS_SECTION_ADDITIONAL, 0); CHECK("dns_message_rendersection(add)", result); result = dns_message_renderend(query); CHECK("dns_message_renderend", result); dns_compress_invalidate(&cctx); isc_buffer_init(&outbuf, output, sizeof(output)); result = dns_message_totext(query, style, 0, &outbuf); CHECK("dns_message_totext", result); printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf), (char *)isc_buffer_base(&outbuf)); isc_buffer_usedregion(&qbuffer, &r); isc_sockaddr_any(&sa); result = isc_socket_bind(s, &sa); CHECK("isc_socket_bind", result); result = isc_socket_sendto(s, &r, task1, senddone, NULL, &address, NULL); CHECK("isc_socket_sendto", result); inr.base = rdata; inr.length = sizeof(rdata); result = isc_socket_recv(s, &inr, 1, task1, recvdone, NULL); CHECK("isc_socket_recv", result); dns_message_destroy(&query); }
static void process_message(isc_buffer_t *source) { dns_message_t *message; isc_result_t result; int i; message = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); CHECKRESULT(result, "dns_message_create failed"); result = dns_message_parse(message, source, parseflags); if (result == DNS_R_RECOVERABLE) result = ISC_R_SUCCESS; CHECKRESULT(result, "dns_message_parse failed"); result = printmessage(message); CHECKRESULT(result, "printmessage() failed"); if (printmemstats) isc_mem_stats(mctx, stdout); if (dorender) { unsigned char b2[64 * 1024]; isc_buffer_t buffer; dns_compress_t cctx; isc_buffer_init(&buffer, b2, sizeof(b2)); /* * XXXMLG * Changing this here is a hack, and should not be done in * reasonable application code, ever. */ message->from_to_wire = DNS_MESSAGE_INTENTRENDER; for (i = 0; i < DNS_SECTION_MAX; i++) message->counts[i] = 0; /* Another hack XXX */ result = dns_compress_init(&cctx, -1, mctx); CHECKRESULT(result, "dns_compress_init() failed"); result = dns_message_renderbegin(message, &cctx, &buffer); CHECKRESULT(result, "dns_message_renderbegin() failed"); result = dns_message_rendersection(message, DNS_SECTION_QUESTION, 0); CHECKRESULT(result, "dns_message_rendersection(QUESTION) failed"); result = dns_message_rendersection(message, DNS_SECTION_ANSWER, 0); CHECKRESULT(result, "dns_message_rendersection(ANSWER) failed"); result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, 0); CHECKRESULT(result, "dns_message_rendersection(AUTHORITY) failed"); result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, 0); CHECKRESULT(result, "dns_message_rendersection(ADDITIONAL) failed"); dns_message_renderend(message); dns_compress_invalidate(&cctx); message->from_to_wire = DNS_MESSAGE_INTENTPARSE; dns_message_destroy(&message); printf("Message rendered.\n"); if (printmemstats) isc_mem_stats(mctx, stdout); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); CHECKRESULT(result, "dns_message_create failed"); result = dns_message_parse(message, &buffer, parseflags); CHECKRESULT(result, "dns_message_parse failed"); result = printmessage(message); CHECKRESULT(result, "printmessage() failed"); } dns_message_destroy(&message); }
static isc_result_t add_tsig(dst_context_t *tsigctx, dns_tsigkey_t *key, isc_buffer_t *target) { dns_compress_t cctx; dns_rdata_any_tsig_t tsig; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdatalist_t rdatalist; dns_rdataset_t rdataset; isc_buffer_t *dynbuf = NULL; isc_buffer_t databuf; isc_buffer_t sigbuf; isc_region_t r; isc_result_t result = ISC_R_SUCCESS; isc_stdtime_t now; unsigned char tsigbuf[1024]; unsigned int count; unsigned int sigsize; isc_boolean_t invalidate_ctx = ISC_FALSE; CHECK(dns_compress_init(&cctx, -1, mctx)); invalidate_ctx = ISC_TRUE; memset(&tsig, 0, sizeof(tsig)); tsig.common.rdclass = dns_rdataclass_any; tsig.common.rdtype = dns_rdatatype_tsig; ISC_LINK_INIT(&tsig.common, link); dns_name_init(&tsig.algorithm, NULL); dns_name_clone(key->algorithm, &tsig.algorithm); isc_stdtime_get(&now); tsig.timesigned = now; tsig.fudge = DNS_TSIG_FUDGE; tsig.originalid = 50; tsig.error = dns_rcode_noerror; tsig.otherlen = 0; tsig.other = NULL; isc_buffer_init(&databuf, tsigbuf, sizeof(tsigbuf)); isc_buffer_putuint48(&databuf, tsig.timesigned); isc_buffer_putuint16(&databuf, tsig.fudge); isc_buffer_usedregion(&databuf, &r); CHECK(dst_context_adddata(tsigctx, &r)); CHECK(dst_key_sigsize(key->key, &sigsize)); tsig.signature = (unsigned char *) isc_mem_get(mctx, sigsize); if (tsig.signature == NULL) CHECK(ISC_R_NOMEMORY); isc_buffer_init(&sigbuf, tsig.signature, sigsize); CHECK(dst_context_sign(tsigctx, &sigbuf)); tsig.siglen = isc_buffer_usedlength(&sigbuf); CHECK(isc_buffer_allocate(mctx, &dynbuf, 512)); CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_any, dns_rdatatype_tsig, &tsig, dynbuf)); dns_rdatalist_init(&rdatalist); rdatalist.rdclass = dns_rdataclass_any; rdatalist.type = dns_rdatatype_tsig; ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); dns_rdataset_init(&rdataset); CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset)); CHECK(dns_rdataset_towire(&rdataset, &key->name, &cctx, target, 0, &count)); /* * Fixup additional record count. */ ((unsigned char*)target->base)[11]++; if (((unsigned char*)target->base)[11] == 0) ((unsigned char*)target->base)[10]++; cleanup: if (tsig.signature != NULL) isc_mem_put(mctx, tsig.signature, sigsize); if (dynbuf != NULL) isc_buffer_free(&dynbuf); if (invalidate_ctx) dns_compress_invalidate(&cctx); return (result); }
static void render(isc_buffer_t *buf, unsigned flags, dns_tsigkey_t *key, isc_buffer_t **tsigin, isc_buffer_t **tsigout, dst_context_t *tsigctx) { dns_message_t *msg = NULL; dns_compress_t cctx; isc_result_t result; result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &msg); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_create: %s", dns_result_totext(result)); msg->id = 50; msg->rcode = dns_rcode_noerror; msg->flags = flags; if (tsigin == tsigout) msg->tcp_continuation = 1; if (tsigctx == NULL) { result = dns_message_settsigkey(msg, key); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_settsigkey: %s", dns_result_totext(result)); result = dns_message_setquerytsig(msg, *tsigin); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_setquerytsig: %s", dns_result_totext(result)); } result = dns_compress_init(&cctx, -1, mctx); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_compress_init: %s", dns_result_totext(result)); result = dns_message_renderbegin(msg, &cctx, buf); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_renderbegin: %s", dns_result_totext(result)); result = dns_message_renderend(msg); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_renderend: %s", dns_result_totext(result)); if (tsigctx != NULL) { isc_region_t r; isc_buffer_usedregion(buf, &r); result = dst_context_adddata(tsigctx, &r); } else { if (tsigin == tsigout && *tsigin != NULL) isc_buffer_free(tsigin); result = dns_message_getquerytsig(msg, mctx, tsigout); ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "dns_message_getquerytsig: %s", dns_result_totext(result)); } dns_compress_invalidate(&cctx); dns_message_destroy(&msg); }
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); }