From ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3f Mon Sep 17 00:00:00 2001 From: Michael Graff Date: Fri, 30 Apr 1999 21:52:40 +0000 Subject: [PATCH] snapshot --- bin/tests/wire_test.c | 62 ++++++++++++++++++++++++++++++++++++--- lib/dns/message.c | 68 +++++++++++++++++++++++++++++++------------ 2 files changed, 107 insertions(+), 23 deletions(-) diff --git a/bin/tests/wire_test.c b/bin/tests/wire_test.c index c3f590e976..76a7bea22e 100644 --- a/bin/tests/wire_test.c +++ b/bin/tests/wire_test.c @@ -309,10 +309,6 @@ main(int argc, char *argv[]) { if (need_close) fclose(f); - f = fopen("foo", "w"); - fwrite(b, bp - b, 1, f); - fclose(f); - isc_buffer_init(&source, b, sizeof b, ISC_BUFFERTYPE_BINARY); isc_buffer_add(&source, bp - b); @@ -325,6 +321,64 @@ main(int argc, char *argv[]) { result = printmessage(message); CHECKRESULT(result, "printmessage() failed"); + isc_mem_stats(mctx, stdout); + + /* + * XXXMLG + * Changing this here is a hack, and should not be done in reasonable + * application code, ever. + */ + message->from_to_wire = DNS_MESSAGE_INTENT_RENDER; + memset(&b, 0, sizeof(b)); + isc_buffer_clear(&source); + + result = dns_message_renderbegin(message, &source); + CHECKRESULT(result, "dns_message_renderbegin() failed"); + + result = dns_message_rendersection(message, DNS_SECTION_QUESTION, + 0, 0); + CHECKRESULT(result, "dns_message_rendersection(QUESTION) failed"); + + result = dns_message_rendersection(message, DNS_SECTION_ANSWER, + 0, 0); + CHECKRESULT(result, "dns_message_rendersection(ANSWER) failed"); + + result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, + 0, 0); + CHECKRESULT(result, "dns_message_rendersection(AUTHORITY) failed"); + + result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, + 0, 0); + CHECKRESULT(result, "dns_message_rendersection(ADDITIONAL) failed"); + + result = dns_message_rendersection(message, DNS_SECTION_OPT, + 0, 0); + CHECKRESULT(result, "dns_message_rendersection(OPT) failed"); + + result = dns_message_rendersection(message, DNS_SECTION_TSIG, + 0, 0); + CHECKRESULT(result, "dns_message_rendersection(TSIG) failed"); + + dns_message_renderend(message); + + message->from_to_wire = DNS_MESSAGE_INTENT_PARSE; + dns_message_destroy(&message); + + isc_mem_stats(mctx, stdout); + + for (i = 0 ; i < source.used ; i++) + printf("%02x%c ", b[i], (isprint(b[i]) ? b[i] : ' ')); + printf("\n"); + + result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENT_PARSE); + CHECKRESULT(result, "dns_message_create failed"); + + result = dns_message_parse(message, &source); + CHECKRESULT(result, "dns_message_parse failed"); + + result = printmessage(message); + CHECKRESULT(result, "printmessage() failed"); + dns_message_destroy(&message); isc_mem_stats(mctx, stdout); diff --git a/lib/dns/message.c b/lib/dns/message.c index 1fc52f5d34..0aadf60273 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -433,19 +433,24 @@ msgreset(dns_message_t *msg, isc_boolean_t everything) msgblock = next_msgblock; } - if (msg->from_to_wire == DNS_MESSAGE_INTENT_PARSE) { - msgblock = ISC_LIST_HEAD(msg->rdatalists); - INSIST(msgblock != NULL); - if (everything == ISC_FALSE) { - msgblock_reset(msgblock, RDATALIST_COUNT); - msgblock = ISC_LIST_NEXT(msgblock, link); - } - while (msgblock != NULL) { - next_msgblock = ISC_LIST_NEXT(msgblock, link); - ISC_LIST_UNLINK(msg->rdatalists, msgblock, link); - msgblock_free(msg->mctx, msgblock); - msgblock = next_msgblock; - } + /* + * "rdatalists" is special, since it is possible (but not recommended) + * that the message could be switched from parse into render mode. + * + * Note that the reverse is not possible -- switching to parse after + * render will not work, and should not. + */ + + msgblock = ISC_LIST_HEAD(msg->rdatalists); + if (everything == ISC_FALSE) { + msgblock_reset(msgblock, RDATALIST_COUNT); + msgblock = ISC_LIST_NEXT(msgblock, link); + } + while (msgblock != NULL) { + next_msgblock = ISC_LIST_NEXT(msgblock, link); + ISC_LIST_UNLINK(msg->rdatalists, msgblock, link); + msgblock_free(msg->mctx, msgblock); + msgblock = next_msgblock; } if (msg->need_cctx_cleanup) @@ -1021,6 +1026,8 @@ dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer) */ isc_buffer_add(buffer, DNS_MESSAGE_HEADER_LEN); + msg->buffer = buffer; + return (DNS_R_SUCCESS); } @@ -1137,10 +1144,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, result = dns_name_towire(name, &msg->cctx, &subbuffer); if (result != DNS_R_SUCCESS) { - subbuffer.used = used; msg->counts[sectionid] += total; - isc_buffer_used(&subbuffer, &r); - isc_buffer_add(msg->buffer, r.length); + isc_buffer_add(msg->buffer, used); return (result); } @@ -1159,10 +1164,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, * so far, and return that status. */ if (result != DNS_R_SUCCESS) { - subbuffer.used = used; msg->counts[sectionid] += total; - isc_buffer_used(&subbuffer, &r); - isc_buffer_add(msg->buffer, r.length); + isc_buffer_add(msg->buffer, used); return (result); } @@ -1176,15 +1179,42 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, name = next_name; } + msg->counts[sectionid] += total; + isc_buffer_used(&subbuffer, &r); + isc_buffer_add(msg->buffer, r.length); + return (ISC_R_SUCCESS); } dns_result_t dns_message_renderend(dns_message_t *msg) { + isc_buffer_t tmpbuf; + isc_region_t r; + isc_uint16_t tmpflags; + REQUIRE(VALID_MESSAGE(msg)); REQUIRE(msg->buffer != NULL); + isc_buffer_used(msg->buffer, &r); + if (r.length < DNS_MESSAGE_HEADER_LEN) + return (DNS_R_NOSPACE); /* this is slightly bogus... XXX */ + + isc_buffer_init(&tmpbuf, r.base, r.length, ISC_BUFFERTYPE_BINARY); + + isc_buffer_putuint16(&tmpbuf, msg->id); + + tmpflags = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT) + & DNS_MESSAGE_OPCODE_MASK); + tmpflags |= (msg->rcode & DNS_MESSAGE_RCODE_MASK); /* XXX edns? */ + tmpflags |= (msg->flags & DNS_MESSAGE_FLAG_MASK); + + isc_buffer_putuint16(&tmpbuf, tmpflags); + isc_buffer_putuint16(&tmpbuf, msg->counts[DNS_SECTION_QUESTION]); + isc_buffer_putuint16(&tmpbuf, msg->counts[DNS_SECTION_ANSWER]); + isc_buffer_putuint16(&tmpbuf, msg->counts[DNS_SECTION_AUTHORITY]); + isc_buffer_putuint16(&tmpbuf, msg->counts[DNS_SECTION_ADDITIONAL]); + msg->buffer = NULL; /* forget about this buffer only on success XXX */ dns_compress_invalidate(&msg->cctx);