diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index ef983c3814..b89cc6b6d5 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -1486,6 +1486,16 @@ dns_message_setpadding(dns_message_t *msg, uint16_t padding); * \li msg be a valid message. */ +void +dns_message_clonebuffer(dns_message_t *msg); +/*%< + * Clone the query or saved buffers if they where not cloned + * when parsing. + * + * Requires: + * \li msg be a valid message. + */ + ISC_LANG_ENDDECLS #endif /* DNS_MESSAGE_H */ diff --git a/lib/dns/message.c b/lib/dns/message.c index 3c3c537ceb..98fa9177e8 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -4749,3 +4749,21 @@ dns_message_setpadding(dns_message_t *msg, uint16_t padding) { } msg->padding = padding; } + +void +dns_message_clonebuffer(dns_message_t *msg) { + REQUIRE(DNS_MESSAGE_VALID(msg)); + + if (msg->free_saved == 0 && msg->saved.base != NULL) { + msg->saved.base = + memmove(isc_mem_get(msg->mctx, msg->saved.length), + msg->saved.base, msg->saved.length); + msg->free_saved = 1; + } + if (msg->free_query == 0 && msg->query.base != NULL) { + msg->query.base = + memmove(isc_mem_get(msg->mctx, msg->query.length), + msg->query.base, msg->query.length); + msg->free_query = 1; + } +} diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 8b5eecb70f..e3f6aed4ea 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -524,6 +524,7 @@ dns_master_styleflags dns_message_addname dns_message_buildopt dns_message_checksig +dns_message_clonebuffer dns_message_create dns_message_currentname dns_message_destroy diff --git a/lib/ns/query.c b/lib/ns/query.c index 2e1b27d78d..6df111b9ea 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -5897,6 +5897,7 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, return (result); } + dns_message_clonebuffer(client->message); ns_client_recursing(client); } else if ((client->attributes & NS_CLIENTATTR_RECURSING) == 0) { client->attributes |= NS_CLIENTATTR_RECURSING; diff --git a/lib/ns/update.c b/lib/ns/update.c index 0c0546d1d4..ce424ca87f 100644 --- a/lib/ns/update.c +++ b/lib/ns/update.c @@ -1666,6 +1666,7 @@ ns_update_start(ns_client_t *client, isc_nmhandle_t *handle, if (sigresult != ISC_R_SUCCESS) { FAIL(sigresult); } + dns_message_clonebuffer(client->message); CHECK(send_update_event(client, zone)); break; case dns_zone_slave: