From efcd38346161b10d60368411cfb2c0d1c22b5fb1 Mon Sep 17 00:00:00 2001 From: Brian Wellington Date: Fri, 5 Jan 2001 00:17:33 +0000 Subject: [PATCH] Update forwarding when the message buffer was no longer copied. Fix this by having the update forwarding code tell dns_message_parse to copy the buffer. --- lib/dns/include/dns/message.h | 6 +++++- lib/dns/message.c | 34 +++++++++++++++++++++++++++------- lib/dns/zone.c | 5 +++-- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index 2ee2a6ebfa..d72c9493e8 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.h,v 1.85 2001/01/04 01:25:08 bwelling Exp $ */ +/* $Id: message.h,v 1.86 2001/01/05 00:17:33 bwelling Exp $ */ #ifndef DNS_MESSAGE_H #define DNS_MESSAGE_H 1 @@ -149,6 +149,8 @@ typedef int dns_messagetextflag_t; #define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /* return a message if a recoverable parse error occurs */ +#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /* save a copy of the + source buffer */ /* * Control behavior of rendering @@ -185,6 +187,8 @@ struct dns_message { unsigned int tcp_continuation : 1; unsigned int verified_sig : 1; unsigned int verify_attempted : 1; + unsigned int free_query : 1; + unsigned int free_saved : 1; unsigned int opt_reserved; unsigned int sig_reserved; diff --git a/lib/dns/message.c b/lib/dns/message.c index cf48d0514a..5e1428a937 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.c,v 1.167 2001/01/04 01:55:22 bwelling Exp $ */ +/* $Id: message.c,v 1.168 2001/01/05 00:17:29 bwelling Exp $ */ /*** *** Imports @@ -355,11 +355,6 @@ msginittsig(dns_message_t *m) { m->sigstart = -1; m->sig0key = NULL; m->sig0status = dns_rcode_noerror; - m->query.base = NULL; - m->query.length = 0; - m->saved.base = NULL; - m->saved.length = 0; - m->querytsig = NULL; } /* @@ -378,6 +373,13 @@ msginit(dns_message_t *m) { m->verify_attempted = 0; m->order = NULL; m->order_arg = NULL; + m->query.base = NULL; + m->query.length = 0; + m->free_query = 0; + m->saved.base = NULL; + m->saved.length = 0; + m->free_saved = 0; + m->querytsig = NULL; } static inline void @@ -558,11 +560,17 @@ msgreset(dns_message_t *msg, isc_boolean_t everything) { } if (msg->query.base != NULL) { + if (msg->free_query != 0) + isc_mem_put(msg->mctx, msg->query.base, + msg->query.length); msg->query.base = NULL; msg->query.length = 0; } if (msg->saved.base != NULL) { + if (msg->free_saved != 0) + isc_mem_put(msg->mctx, msg->saved.base, + msg->saved.length); msg->saved.base = NULL; msg->saved.length = 0; } @@ -1538,7 +1546,17 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, r.length); } - isc_buffer_usedregion(&origsource, &msg->saved); + if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) + isc_buffer_usedregion(&origsource, &msg->saved); + else { + msg->saved.length = isc_buffer_usedlength(&origsource); + msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); + if (msg->saved.base == NULL) + return (ISC_R_NOMEMORY); + memcpy(msg->saved.base, isc_buffer_base(&origsource), + msg->saved.length); + msg->free_saved = 1; + } if (seen_problem == ISC_TRUE) return (DNS_R_RECOVERABLE); @@ -2255,8 +2273,10 @@ dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) { if (msg->saved.base != NULL) { msg->query.base = msg->saved.base; msg->query.length = msg->saved.length; + msg->free_query = msg->free_saved; msg->saved.base = NULL; msg->saved.length = 0; + msg->free_saved = 0; } return (ISC_R_SUCCESS); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 9a250f01f3..8aaa53e669 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.287 2001/01/04 04:10:59 marka Exp $ */ +/* $Id: zone.c,v 1.288 2001/01/05 00:17:31 bwelling Exp $ */ #include @@ -4993,7 +4993,8 @@ forward_callback(isc_task_t *task, isc_event_t *event) { goto next_master; result = dns_request_getresponse(revent->request, msg, - DNS_MESSAGEPARSE_PRESERVEORDER); + DNS_MESSAGEPARSE_PRESERVEORDER | + DNS_MESSAGEPARSE_CLONEBUFFER); if (result != ISC_R_SUCCESS) goto next_master;