bind/backport-0061-Refactored-dns_message_t-for-using-attach-detach-sem.patch
jiangheng ad37c37958 backport some patches from community
(cherry picked from commit a9fd9ece9b9436b6103d084920c6897ef1adbae6)
2022-09-03 21:36:21 +08:00

1060 lines
32 KiB
Diff

From 8781aef52e6d5498d6007df3ca466d7e23641836 Mon Sep 17 00:00:00 2001
From: Diego Fronza <diego@isc.org>
Date: Mon, 21 Sep 2020 16:16:15 -0300
Subject: [PATCH] Refactored dns_message_t for using attach/detach semantics
This commit will be used as a base for the next code updates in order
to have a better control of dns_message_t objects' lifetime.
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/8781aef52e6d5498d6007df3ca466d7e23641836
---
bin/dig/dighost.c | 28 ++++++++---------
bin/dig/nslookup.c | 2 +-
bin/named/client.c | 4 +--
bin/named/update.c | 2 +-
bin/named/xfrout.c | 2 +-
bin/nsupdate/nsupdate.c | 32 +++++++++----------
bin/tests/optional/gsstest.c | 10 +++---
bin/tests/optional/sig0_test.c | 4 +--
bin/tests/system/pipelined/pipequeries.c | 4 +--
bin/tests/system/tkey/keycreate.c | 4 +--
bin/tests/system/tkey/keydelete.c | 4 +--
bin/tests/wire_test.c | 4 +--
bin/tools/dnstap-read.c | 2 +-
bin/tools/mdig.c | 4 +--
lib/dns/client.c | 14 ++++-----
lib/dns/dnstap.c | 4 +--
lib/dns/include/dns/message.h | 25 ++++++++++-----
lib/dns/message.c | 40 ++++++++++++++++++------
lib/dns/resolver.c | 8 ++---
lib/dns/tests/tsig_test.c | 8 ++---
lib/dns/win32/libdns.def.in | 3 +-
lib/dns/xfrin.c | 8 ++---
lib/dns/zone.c | 32 +++++++++----------
lib/samples/nsprobe.c | 4 +--
lib/samples/sample-request.c | 6 ++--
25 files changed, 144 insertions(+), 114 deletions(-)
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 4ec6c13a4e..4043aa3bf1 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -1907,7 +1907,7 @@ destroy_lookup(dig_lookup_t *lookup) {
isc_mem_free(mctx, ptr);
}
if (lookup->sendmsg != NULL)
- dns_message_destroy(&lookup->sendmsg);
+ dns_message_detach(&lookup->sendmsg);
if (lookup->querysig != NULL) {
debug("freeing buffer %p", lookup->querysig);
isc_buffer_free(&lookup->querysig);
@@ -4013,7 +4013,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
printf(";; Got bad packet: %s\n", isc_result_totext(result));
hex_dump(b);
query->waiting_connect = false;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
@@ -4036,7 +4036,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
printf(";; Warning: Opcode mismatch: expected %s, got %s",
expect, got);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (l->tcp_mode) {
isc_event_free(&event);
clear_query(query);
@@ -4083,7 +4083,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
}
if (!match) {
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (l->tcp_mode) {
isc_event_free(&event);
clear_query(query);
@@ -4107,7 +4107,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
n = requeue_lookup(l, true);
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
@@ -4125,7 +4125,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
n->tcp_mode = true;
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
@@ -4146,7 +4146,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
n->seenbadcookie = true;
if (l->trace && l->trace_root)
n->rdtype = l->qrdtype;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
clear_query(query);
cancel_lookup(l);
@@ -4185,7 +4185,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
query->servname);
clear_query(query);
check_next_lookup(l);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
UNLOCK_LOOKUP;
return;
@@ -4360,7 +4360,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
debug("still pending.");
if (l->doing_xfr) {
if (query != l->xfr_q) {
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
query->waiting_connect = false;
UNLOCK_LOOKUP;
@@ -4369,7 +4369,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
if (!docancel)
docancel = check_for_more_data(query, msg, sevent);
if (docancel) {
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
clear_query(query);
cancel_lookup(l);
check_next_lookup(l);
@@ -4391,7 +4391,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
#ifdef DIG_SIGCHASE
if (!do_sigchase)
#endif
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
cancel_lookup(l);
}
@@ -4404,7 +4404,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
msg = NULL;
else
#endif
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
}
isc_event_free(&event);
UNLOCK_LOOKUP;
@@ -4658,7 +4658,7 @@ destroy_libs(void) {
while (chase_msg != NULL) {
INSIST(chase_msg->msg != NULL);
- dns_message_destroy(&(chase_msg->msg));
+ dns_message_detach(&(chase_msg->msg));
ptr = chase_msg;
chase_msg = ISC_LIST_NEXT(chase_msg, link);
isc_mem_free(mctx, ptr);
@@ -4668,7 +4668,7 @@ destroy_libs(void) {
while (chase_msg != NULL) {
INSIST(chase_msg->msg != NULL);
- dns_message_destroy(&(chase_msg->msg));
+ dns_message_detach(&(chase_msg->msg));
ptr = chase_msg;
chase_msg = ISC_LIST_NEXT(chase_msg, link);
isc_mem_free(mctx, ptr);
diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c
index 647ed8ce50..c35283177d 100644
--- a/bin/dig/nslookup.c
+++ b/bin/dig/nslookup.c
@@ -983,7 +983,7 @@ flush_lookup_list(void) {
}
if (l->sendmsg != NULL)
- dns_message_destroy(&l->sendmsg);
+ dns_message_detach(&l->sendmsg);
lp = l;
l = ISC_LIST_NEXT(l, link);
ISC_LIST_DEQUEUE(lookup_list, lp, link);
diff --git a/bin/named/client.c b/bin/named/client.c
index 95dabbf53b..4a50ad9bae 100644
--- a/bin/named/client.c
+++ b/bin/named/client.c
@@ -758,7 +758,7 @@ exit_check(ns_client_t *client) {
client->keytag_len = 0;
}
- dns_message_destroy(&client->message);
+ dns_message_detach(&client->message);
/*
* Detaching the task must be done after unlinking from
@@ -3375,7 +3375,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
client->magic = 0;
cleanup_message:
- dns_message_destroy(&client->message);
+ dns_message_detach(&client->message);
cleanup_timer:
isc_timer_detach(&client->timer);
diff --git a/bin/named/update.c b/bin/named/update.c
index 82f9d4a13d..ffd2caf7e4 100644
--- a/bin/named/update.c
+++ b/bin/named/update.c
@@ -3440,7 +3440,7 @@ forward_done(isc_task_t *task, isc_event_t *event) {
INSIST(client->nupdates > 0);
client->nupdates--;
ns_client_sendraw(client, uev->answer);
- dns_message_destroy(&uev->answer);
+ dns_message_detach(&uev->answer);
isc_event_free(&event);
ns_client_detach(&client);
}
diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c
index 1e139f7a34..7149825a3c 100644
--- a/bin/named/xfrout.c
+++ b/bin/named/xfrout.c
@@ -1580,7 +1580,7 @@ sendstream(xfrout_ctx_t *xfr) {
}
if (tcpmsg != NULL)
- dns_message_destroy(&tcpmsg);
+ dns_message_detach(&tcpmsg);
if (cleanup_cctx)
dns_compress_invalidate(&cctx);
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
index bf5ec8fe6b..4993265f58 100644
--- a/bin/nsupdate/nsupdate.c
+++ b/bin/nsupdate/nsupdate.c
@@ -807,7 +807,7 @@ doshutdown(void) {
}
if (updatemsg != NULL)
- dns_message_destroy(&updatemsg);
+ dns_message_detach(&updatemsg);
if (is_dst_up) {
ddebug("Destroy DST lib");
@@ -2556,7 +2556,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
if (shuttingdown) {
dns_request_destroy(&request);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
isc_mem_put(gmctx, reqinfo, sizeof(nsu_requestinfo_t));
isc_event_free(&event);
maybeshutdown();
@@ -2587,7 +2587,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
result = dns_request_getresponse(request, rcvmsg,
DNS_MESSAGEPARSE_PRESERVEORDER);
if (result == DNS_R_TSIGERRORSET && servers != NULL) {
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
ddebug("Destroying request [%p]", request);
dns_request_destroy(&request);
reqinfo = isc_mem_get(gmctx, sizeof(nsu_requestinfo_t));
@@ -2628,9 +2628,9 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
dns_name_format(userzone, namebuf, sizeof(namebuf));
error("specified zone '%s' does not exist (NXDOMAIN)",
namebuf);
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
dns_request_destroy(&request);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
ddebug("Out of recvsoa");
done_update();
seenerror = true;
@@ -2760,11 +2760,11 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
setzoneclass(dns_rdataclass_none);
#endif
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
dns_request_destroy(&request);
out:
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
ddebug("Out of recvsoa");
return;
@@ -2973,7 +2973,7 @@ start_gssrequest(dns_name_t *master) {
failure:
if (rmsg != NULL)
- dns_message_destroy(&rmsg);
+ dns_message_detach(&rmsg);
if (err_message != NULL)
isc_mem_free(gmctx, err_message);
failed_gssrequest();
@@ -3047,7 +3047,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
if (shuttingdown) {
dns_request_destroy(&request);
- dns_message_destroy(&tsigquery);
+ dns_message_detach(&tsigquery);
isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t));
isc_event_free(&event);
maybeshutdown();
@@ -3058,7 +3058,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
ddebug("Destroying request [%p]", request);
dns_request_destroy(&request);
if (!next_master("recvgss", addr, eresult)) {
- dns_message_destroy(&tsigquery);
+ dns_message_detach(&tsigquery);
failed_gssrequest();
} else {
dns_message_renderreset(tsigquery);
@@ -3117,7 +3117,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
switch (result) {
case DNS_R_CONTINUE:
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
dns_request_destroy(&request);
send_gssrequest(kserver, tsigquery, &request, context);
ddebug("Out of recvgss");
@@ -3165,9 +3165,9 @@ recvgss(isc_task_t *task, isc_event_t *event) {
done:
dns_request_destroy(&request);
- dns_message_destroy(&tsigquery);
+ dns_message_detach(&tsigquery);
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
ddebug("Out of recvgss");
}
#endif
@@ -3186,7 +3186,7 @@ start_update(void) {
LOCK(&answer_lock);
if (answer != NULL) {
- dns_message_destroy(&answer);
+ dns_message_detach(&answer);
}
UNLOCK(&answer_lock);
@@ -3231,7 +3231,7 @@ start_update(void) {
dns_message_puttempname(soaquery, &name);
dns_rdataset_disassociate(rdataset);
dns_message_puttemprdataset(soaquery, &rdataset);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
done_update();
return;
}
@@ -3268,7 +3268,7 @@ cleanup(void) {
LOCK(&answer_lock);
if (answer != NULL) {
- dns_message_destroy(&answer);
+ dns_message_detach(&answer);
}
UNLOCK(&answer_lock);
diff --git a/bin/tests/optional/gsstest.c b/bin/tests/optional/gsstest.c
index 9692c6f42e..901c2bbb91 100644
--- a/bin/tests/optional/gsstest.c
+++ b/bin/tests/optional/gsstest.c
@@ -157,11 +157,11 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
CHECK("dns_request_getresponse", result2);
if (response != NULL)
- dns_message_destroy(&response);
+ dns_message_detach(&response);
end:
if (query != NULL)
- dns_message_destroy(&query);
+ dns_message_detach(&query);
if (reqev->request != NULL)
dns_request_destroy(&reqev->request);
@@ -248,7 +248,7 @@ sendquery(isc_task_t *task, isc_event_t *event)
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
}
static void
@@ -314,11 +314,11 @@ initctx2(isc_task_t *task, isc_event_t *event) {
tsigkey = NULL;
}
- dns_message_destroy(&response);
+ dns_message_detach(&response);
end:
if (query != NULL)
- dns_message_destroy(&query);
+ dns_message_detach(&query);
if (reqev->request != NULL)
dns_request_destroy(&reqev->request);
diff --git a/bin/tests/optional/sig0_test.c b/bin/tests/optional/sig0_test.c
index 4084f226e5..a74bea1ba2 100644
--- a/bin/tests/optional/sig0_test.c
+++ b/bin/tests/optional/sig0_test.c
@@ -114,7 +114,7 @@ recvdone(isc_task_t *task, isc_event_t *event) {
printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf),
(char *)isc_buffer_base(&outbuf));
- dns_message_destroy(&response);
+ dns_message_detach(&response);
isc_event_free(&event);
isc_app_shutdown();
@@ -190,7 +190,7 @@ buildquery(void) {
inr.length = sizeof(rdata);
result = isc_socket_recv(s, &inr, 1, task1, recvdone, NULL);
CHECK("isc_socket_recv", result);
- dns_message_destroy(&query);
+ dns_message_detach(&query);
}
int
diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c
index 63ee7e9d2f..e16ec11681 100644
--- a/bin/tests/system/pipelined/pipequeries.c
+++ b/bin/tests/system/pipelined/pipequeries.c
@@ -117,8 +117,8 @@ recvresponse(isc_task_t *task, isc_event_t *event) {
(char *)isc_buffer_base(&outbuf));
fflush(stdout);
- dns_message_destroy(&query);
- dns_message_destroy(&response);
+ dns_message_detach(&query);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c
index 0c0b08a90b..85b497f280 100644
--- a/bin/tests/system/tkey/keycreate.c
+++ b/bin/tests/system/tkey/keycreate.c
@@ -117,8 +117,8 @@ recvquery(isc_task_t *task, isc_event_t *event) {
result = dst_key_tofile(tsigkey->key, type, "");
CHECK("dst_key_tofile", result);
- dns_message_destroy(&query);
- dns_message_destroy(&response);
+ dns_message_detach(&query);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
isc_app_shutdown();
diff --git a/bin/tests/system/tkey/keydelete.c b/bin/tests/system/tkey/keydelete.c
index ae26675755..ea7a09b014 100644
--- a/bin/tests/system/tkey/keydelete.c
+++ b/bin/tests/system/tkey/keydelete.c
@@ -96,8 +96,8 @@ recvquery(isc_task_t *task, isc_event_t *event) {
result = dns_tkey_processdeleteresponse(query, response, ring);
CHECK("dns_tkey_processdhresponse", result);
- dns_message_destroy(&query);
- dns_message_destroy(&response);
+ dns_message_detach(&query);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
isc_app_shutdown();
diff --git a/bin/tests/wire_test.c b/bin/tests/wire_test.c
index 0d001a2f77..7fb8446375 100644
--- a/bin/tests/wire_test.c
+++ b/bin/tests/wire_test.c
@@ -328,7 +328,7 @@ process_message(isc_buffer_t *source) {
dns_compress_invalidate(&cctx);
message->from_to_wire = DNS_MESSAGE_INTENTPARSE;
- dns_message_destroy(&message);
+ dns_message_detach(&message);
printf("Message rendered.\n");
if (printmemstats)
@@ -344,5 +344,5 @@ process_message(isc_buffer_t *source) {
result = printmessage(message);
CHECKRESULT(result, "printmessage() failed");
}
- dns_message_destroy(&message);
+ dns_message_detach(&message);
}
diff --git a/bin/tools/dnstap-read.c b/bin/tools/dnstap-read.c
index 97c2f71346..cf0c884c02 100644
--- a/bin/tools/dnstap-read.c
+++ b/bin/tools/dnstap-read.c
@@ -362,7 +362,7 @@ main(int argc, char *argv[]) {
if (handle != NULL)
dns_dt_close(&handle);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
if (b != NULL)
isc_buffer_free(&b);
isc_mem_destroy(&mctx);
diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c
index 9a105cbd83..4dd12ee6f4 100644
--- a/bin/tools/mdig.c
+++ b/bin/tools/mdig.c
@@ -478,9 +478,9 @@ cleanup:
if (style != NULL)
dns_master_styledestroy(&style, mctx);
if (query != NULL)
- dns_message_destroy(&query);
+ dns_message_detach(&query);
if (response != NULL)
- dns_message_destroy(&response);
+ dns_message_detach(&response);
dns_request_destroy(&reqev->request);
isc_event_free(&event);
diff --git a/lib/dns/client.c b/lib/dns/client.c
index 6e2b1fe348..c2dca94bad 100644
--- a/lib/dns/client.c
+++ b/lib/dns/client.c
@@ -1961,7 +1961,7 @@ static void
update_sendevent(updatectx_t *uctx, isc_result_t result) {
isc_task_t *task;
- dns_message_destroy(&uctx->updatemsg);
+ dns_message_detach(&uctx->updatemsg);
if (uctx->tsigkey != NULL)
dns_tsigkey_detach(&uctx->tsigkey);
if (uctx->sig0key != NULL)
@@ -2012,7 +2012,7 @@ update_done(isc_task_t *task, isc_event_t *event) {
out:
if (answer != NULL)
- dns_message_destroy(&answer);
+ dns_message_detach(&answer);
isc_event_free(&event);
LOCK(&uctx->lock);
@@ -2354,7 +2354,7 @@ receive_soa(isc_task_t *task, isc_event_t *event) {
dns_request_t *newrequest = NULL;
/* Retry SOA request without TSIG */
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
dns_message_renderreset(uctx->soaquery);
reqoptions = 0;
if (uctx->want_tcp)
@@ -2477,14 +2477,14 @@ receive_soa(isc_task_t *task, isc_event_t *event) {
}
if (!droplabel || result != ISC_R_SUCCESS) {
- dns_message_destroy(&uctx->soaquery);
+ dns_message_detach(&uctx->soaquery);
LOCK(&uctx->lock);
dns_request_destroy(&uctx->soareq);
UNLOCK(&uctx->lock);
}
if (rcvmsg != NULL)
- dns_message_destroy(&rcvmsg);
+ dns_message_detach(&rcvmsg);
if (result != ISC_R_SUCCESS)
update_sendevent(uctx, result);
@@ -2541,7 +2541,7 @@ request_soa(updatectx_t *uctx) {
}
if (name != NULL)
dns_message_puttempname(soaquery, &name);
- dns_message_destroy(&soaquery);
+ dns_message_detach(&soaquery);
return (result);
}
@@ -3040,7 +3040,7 @@ dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
UNLOCK(&client->lock);
}
if (uctx->updatemsg != NULL)
- dns_message_destroy(&uctx->updatemsg);
+ dns_message_detach(&uctx->updatemsg);
while ((sa = ISC_LIST_HEAD(uctx->servers)) != NULL) {
ISC_LIST_UNLINK(uctx->servers, sa, link);
isc_mem_put(client->mctx, sa, sizeof(*sa));
diff --git a/lib/dns/dnstap.c b/lib/dns/dnstap.c
index 4b289a9ea7..fad1e3b040 100644
--- a/lib/dns/dnstap.c
+++ b/lib/dns/dnstap.c
@@ -1041,7 +1041,7 @@ dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp) {
result = dns_message_parse(d->msg, &b, 0);
if (result != ISC_R_SUCCESS) {
if (result != DNS_R_RECOVERABLE)
- dns_message_destroy(&d->msg);
+ dns_message_detach(&d->msg);
result = ISC_R_SUCCESS;
}
@@ -1248,7 +1248,7 @@ dns_dtdata_free(dns_dtdata_t **dp) {
d = *dp;
if (d->msg != NULL)
- dns_message_destroy(&d->msg);
+ dns_message_detach(&d->msg);
if (d->frame != NULL)
dnstap__dnstap__free_unpacked(d->frame, NULL);
diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index 58de67a8af..f64522b43a 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -21,6 +21,7 @@
#include <isc/lang.h>
#include <isc/magic.h>
+#include <isc/refcount.h>
#include <dns/compress.h>
#include <dns/masterdump.h>
@@ -194,6 +195,7 @@ typedef struct dns_msgblock dns_msgblock_t;
struct dns_message {
/* public from here down */
unsigned int magic;
+ isc_refcount_t refcount;
dns_messageid_t id;
unsigned int flags;
@@ -310,8 +312,8 @@ dns_message_reset(dns_message_t *msg, unsigned int intent);
/*%<
* Reset a message structure to default state. All internal lists are freed
* or reset to a default state as well. This is simply a more efficient
- * way to call dns_message_destroy() followed by dns_message_allocate(),
- * since it avoid many memory allocations.
+ * way to call dns_message_detach() (assuming last reference is hold),
+ * followed by dns_message_create(), since it avoid many memory allocations.
*
* If any data loanouts (buffers, names, rdatas, etc) were requested,
* the caller must no longer use them after this call.
@@ -326,16 +328,23 @@ dns_message_reset(dns_message_t *msg, unsigned int intent);
*/
void
-dns_message_destroy(dns_message_t **msgp);
+dns_message_attach(dns_message_t *source, dns_message_t **target);
/*%<
- * Destroy all state in the message.
+ * Attach to message 'source'.
*
* Requires:
+ *\li 'source' to be a valid message.
+ *\li 'target' to be non NULL and '*target' to be NULL.
+ */
+
+void
+dns_message_detach(dns_message_t **messagep);
+/*%<
+ * Detach *messagep from its message.
+ * list.
*
- *\li 'msgp' be valid.
- *
- * Ensures:
- *\li '*msgp' == NULL
+ * Requires:
+ *\li '*messagep' to be a valid message.
*/
isc_result_t
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 6a6d09e219..2812ab5a37 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -23,6 +23,7 @@
#include <isc/buffer.h>
#include <isc/mem.h>
#include <isc/print.h>
+#include <isc/refcount.h>
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/utf8.h>
#include <isc/util.h>
@@ -554,7 +555,7 @@ msgresetsigs(dns_message_t *msg, bool replying) {
/*
* Free all but one (or everything) for this message. This is used by
- * both dns_message_reset() and dns_message_destroy().
+ * both dns_message_reset() and dns__message_destroy().
*/
static void
msgreset(dns_message_t *msg, bool everything) {
@@ -794,6 +795,8 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
m->cctx = NULL;
+ isc_refcount_init(&m->refcount, 1);
+
*msgp = m;
return (ISC_R_SUCCESS);
@@ -826,23 +829,40 @@ dns_message_reset(dns_message_t *msg, unsigned int intent) {
msg->from_to_wire = intent;
}
-void
-dns_message_destroy(dns_message_t **msgp) {
- dns_message_t *msg;
-
- REQUIRE(msgp != NULL);
- REQUIRE(DNS_MESSAGE_VALID(*msgp));
-
- msg = *msgp;
- *msgp = NULL;
+static void
+dns__message_destroy(dns_message_t *msg) {
+ REQUIRE(msg != NULL);
+ REQUIRE(DNS_MESSAGE_VALID(msg));
msgreset(msg, true);
isc_mempool_destroy(&msg->namepool);
isc_mempool_destroy(&msg->rdspool);
+ isc_refcount_destroy(&msg->refcount);
msg->magic = 0;
isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t));
}
+void
+dns_message_attach(dns_message_t *source, dns_message_t **target) {
+ REQUIRE(DNS_MESSAGE_VALID(source));
+
+ isc_refcount_increment(&source->refcount, NULL);
+ *target = source;
+}
+
+void
+dns_message_detach(dns_message_t **messagep) {
+ REQUIRE(messagep != NULL && DNS_MESSAGE_VALID(*messagep));
+ dns_message_t *msg = *messagep;
+ *messagep = NULL;
+ int32_t refs;
+
+ isc_refcount_decrement(&msg->refcount, &refs);
+ if (refs == 0) {
+ dns__message_destroy(msg);
+ }
+}
+
static isc_result_t
findname(dns_name_t **foundname, dns_name_t *target,
dns_namelist_t *section)
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index e67393aba9..daf9a277ec 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -3966,8 +3966,8 @@ fctx_destroy(fetchctx_t *fctx) {
isc_counter_detach(&fctx->qc);
fcount_decr(fctx);
isc_timer_detach(&fctx->timer);
- dns_message_destroy(&fctx->rmessage);
- dns_message_destroy(&fctx->qmessage);
+ dns_message_detach(&fctx->rmessage);
+ dns_message_detach(&fctx->qmessage);
if (dns_name_countlabels(&fctx->domain) > 0)
dns_name_free(&fctx->domain, fctx->mctx);
if (dns_rdataset_isassociated(&fctx->nameservers))
@@ -4578,10 +4578,10 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
return (ISC_R_SUCCESS);
cleanup_rmessage:
- dns_message_destroy(&fctx->rmessage);
+ dns_message_detach(&fctx->rmessage);
cleanup_qmessage:
- dns_message_destroy(&fctx->qmessage);
+ dns_message_detach(&fctx->qmessage);
cleanup_fcount:
fcount_decr(fctx);
diff --git a/lib/dns/tests/tsig_test.c b/lib/dns/tests/tsig_test.c
index 112a0467f8..ff0c99f7f6 100644
--- a/lib/dns/tests/tsig_test.c
+++ b/lib/dns/tests/tsig_test.c
@@ -261,7 +261,7 @@ render(isc_buffer_t *buf, unsigned flags, dns_tsigkey_t *key,
}
dns_compress_invalidate(&cctx);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
}
/*
@@ -354,7 +354,7 @@ tsig_tcp_test(void **state) {
tsigctx = msg->tsigctx;
msg->tsigctx = NULL;
isc_buffer_free(&buf);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
result = dst_context_create3(key->key, mctx, DNS_LOGCATEGORY_DNSSEC,
false, &outctx);
@@ -412,7 +412,7 @@ tsig_tcp_test(void **state) {
tsigctx = msg->tsigctx;
msg->tsigctx = NULL;
isc_buffer_free(&buf);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
/*
* Create response message 3.
@@ -464,7 +464,7 @@ tsig_tcp_test(void **state) {
assert_int_equal(result, ISC_R_SUCCESS);
isc_buffer_free(&buf);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (outctx != NULL) {
dst_context_destroy(&outctx);
diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in
index b426f150dd..9c2ef79479 100644
--- a/lib/dns/win32/libdns.def.in
+++ b/lib/dns/win32/libdns.def.in
@@ -514,11 +514,12 @@ dns_master_stylecreate2
dns_master_styledestroy
dns_master_styleflags
dns_message_addname
+dns_message_attach
dns_message_buildopt
dns_message_checksig
dns_message_create
dns_message_currentname
-dns_message_destroy
+dns_message_detach
dns_message_find
dns_message_findname
dns_message_findtype
diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c
index 1419d523b0..3a3f407289 100644
--- a/lib/dns/xfrin.c
+++ b/lib/dns/xfrin.c
@@ -1198,7 +1198,7 @@ xfrin_send_request(dns_xfrin_ctx_t *xfr) {
if (qrdataset != NULL)
dns_message_puttemprdataset(msg, &qrdataset);
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (soatuple != NULL)
dns_difftuple_free(&soatuple);
if (ver != NULL)
@@ -1307,7 +1307,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
xfrin_log(xfr, ISC_LOG_DEBUG(3), "got %s, retrying with AXFR",
isc_result_totext(result));
try_axfr:
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
xfrin_reset(xfr);
xfr->reqtype = dns_rdatatype_soa;
xfr->state = XFRST_SOAQUERY;
@@ -1419,7 +1419,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
xfr->tsigctx = msg->tsigctx;
msg->tsigctx = NULL;
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
switch (xfr->state) {
case XFRST_GOTSOA:
@@ -1464,7 +1464,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
failure:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
if (result != ISC_R_SUCCESS)
xfrin_fail(xfr, result, "failed while receiving responses");
}
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index fd634af65f..6f40ebd636 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -11338,7 +11338,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
if (key != NULL)
dns_tsigkey_detach(&key);
cleanup_message:
- dns_message_destroy(&message);
+ dns_message_detach(&message);
cleanup:
UNLOCK_ZONE(notify->zone);
isc_event_free(&event);
@@ -11887,7 +11887,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
dns_db_detach(&stub->db);
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
@@ -11909,7 +11909,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
if (stub->db != NULL)
dns_db_detach(&stub->db);
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
/*
@@ -11956,7 +11956,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
same_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
ns_query(zone, NULL, stub);
@@ -12352,7 +12352,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
ns_query(zone, rdataset, NULL);
}
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
} else if (isc_serial_eq(soa.serial, oldserial)) {
isc_time_t expiretime;
uint32_t expire;
@@ -12387,12 +12387,12 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
goto next_master;
}
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
goto detach;
next_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
/*
@@ -12444,7 +12444,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
same_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
dns_request_destroy(&zone->request);
queue_soa_query(zone);
@@ -12541,7 +12541,7 @@ create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
return (result);
}
@@ -12751,7 +12751,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_SUCCESS)
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
if (cancel)
cancel_refresh(zone);
isc_event_free(&event);
@@ -12762,7 +12762,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
skip_master:
if (key != NULL)
dns_tsigkey_detach(&key);
- dns_message_destroy(&message);
+ dns_message_detach(&message);
/*
* Skip to next failed / untried master.
*/
@@ -12983,7 +12983,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
dns_result_totext(result));
goto cleanup;
}
- dns_message_destroy(&message);
+ dns_message_detach(&message);
goto unlock;
cleanup:
@@ -13000,7 +13000,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
isc_mem_put(stub->mctx, stub, sizeof(*stub));
}
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
unlock:
if (key != NULL)
dns_tsigkey_detach(&key);
@@ -13436,7 +13436,7 @@ notify_createmessage(dns_zone_t *zone, unsigned int flags,
dns_message_puttempname(message, &tempname);
if (temprdataset != NULL)
dns_message_puttemprdataset(message, &temprdataset);
- dns_message_destroy(&message);
+ dns_message_detach(&message);
return (result);
}
@@ -14251,7 +14251,7 @@ notify_done(isc_task_t *task, isc_event_t *event) {
notify_destroy(notify, false);
}
if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_detach(&message);
}
struct secure_event {
@@ -16247,7 +16247,7 @@ forward_callback(isc_task_t *task, isc_event_t *event) {
next_master:
if (msg != NULL)
- dns_message_destroy(&msg);
+ dns_message_detach(&msg);
isc_event_free(&event);
forward->which++;
dns_request_destroy(&forward->request);
diff --git a/lib/samples/nsprobe.c b/lib/samples/nsprobe.c
index f5cc6d6feb..9bf0e65e01 100644
--- a/lib/samples/nsprobe.c
+++ b/lib/samples/nsprobe.c
@@ -1203,8 +1203,8 @@ main(int argc, char *argv[]) {
/* Cleanup */
for (i = 0; i < MAX_PROBES; i++) {
- dns_message_destroy(&probes[i].qmessage);
- dns_message_destroy(&probes[i].rmessage);
+ dns_message_detach(&probes[i].qmessage);
+ dns_message_detach(&probes[i].rmessage);
}
isc_task_detach(&probe_task);
dns_client_destroy(&client);
diff --git a/lib/samples/sample-request.c b/lib/samples/sample-request.c
index bfd806d28e..3a4123e244 100644
--- a/lib/samples/sample-request.c
+++ b/lib/samples/sample-request.c
@@ -115,7 +115,7 @@ make_querymessage(dns_message_t *message, const char *namestr,
dns_message_puttempname(message, &qname);
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
- dns_message_destroy(&message);
+ dns_message_detach(&message);
return (result);
}
@@ -255,8 +255,8 @@ main(int argc, char *argv[]) {
isc_buffer_free(&outputbuf);
/* Cleanup */
- dns_message_destroy(&qmessage);
- dns_message_destroy(&rmessage);
+ dns_message_detach(&qmessage);
+ dns_message_detach(&rmessage);
isc_mem_destroy(&mctx);
dns_client_destroy(&client);
dns_lib_shutdown();
--
2.23.0