]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Refactored dns_message_t for using attach/detach semantics
authorDiego Fronza <diego@isc.org>
Mon, 21 Sep 2020 19:16:15 +0000 (16:16 -0300)
committerOndřej Surý <ondrej@isc.org>
Wed, 30 Sep 2020 11:33:43 +0000 (13:33 +0200)
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.

25 files changed:
bin/dig/dighost.c
bin/dig/nslookup.c
bin/named/client.c
bin/named/update.c
bin/named/xfrout.c
bin/nsupdate/nsupdate.c
bin/tests/optional/gsstest.c
bin/tests/optional/sig0_test.c
bin/tests/system/pipelined/pipequeries.c
bin/tests/system/tkey/keycreate.c
bin/tests/system/tkey/keydelete.c
bin/tests/wire_test.c
bin/tools/dnstap-read.c
bin/tools/mdig.c
lib/dns/client.c
lib/dns/dnstap.c
lib/dns/include/dns/message.h
lib/dns/message.c
lib/dns/resolver.c
lib/dns/tests/tsig_test.c
lib/dns/win32/libdns.def.in
lib/dns/xfrin.c
lib/dns/zone.c
lib/samples/nsprobe.c
lib/samples/sample-request.c

index 4ec6c13a4e1e8684c7fd34503d7b87a2aaf43bd8..4043aa3bf123f87905fa26ab7d63659cdf6ab706 100644 (file)
@@ -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);
index 647ed8ce5078bf0bffcf8d2dfb7c84c8aa85f248..c35283177d85236ea1f1e53501bdfab7bb964949 100644 (file)
@@ -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);
index 95dabbf53bcb75dcad718b9eb8852702ea88bb44..4a50ad9bae7fece1a4866c9b2054eaccc0ea4110 100644 (file)
@@ -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);
index 82f9d4a13dac1bd7febae636f6f121db4ec605a6..ffd2caf7e428526b453c59acdaf78a18661b91a3 100644 (file)
@@ -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);
 }
index 1e139f7a346378b42e8908f8b22b9fdbe1a3cd80..7149825a3c71f1f7726e4dd2637f4dff450ace95 100644 (file)
@@ -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);
index bf5ec8fe6b548a5c89d3f24e2bdc99f3e7b5798e..4993265f58173c3f865482554673b10137b8a513 100644 (file)
@@ -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);
 
index 9692c6f42ed3e33b446480c3403b99481c589ff2..901c2bbb91c1d38337f8a52cd8b00ab4a4860135 100644 (file)
@@ -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);
index 4084f226e50bfe814bca210d3e0e18c8e7f5f7bf..a74bea1ba2d818773d75d298b2468b3c80b3d43b 100644 (file)
@@ -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
index 63ee7e9d2fb66402b993b40a1f286b17b4cdb60d..e16ec11681e43e1d0c1bcb66b5c95e763eb96399 100644 (file)
@@ -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);
 
index 0c0b08a90bf2a35f6ac83d680c5a6c1011be3970..85b497f280bb30e4a2b5b99d0f1de0fcc739c58d 100644 (file)
@@ -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();
index ae2667575596e001144d4d754045fa2c179825ac..ea7a09b0140fed0b6204c24b4af4a81931214168 100644 (file)
@@ -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();
index 0d001a2f77de5fbbddc22a3b65006f47230efda1..7fb8446375019f929559ac1714b242318321f98f 100644 (file)
@@ -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);
 }
index 97c2f71346ddd7e91044898f6dd3cb340f58343d..cf0c884c02a993960e1e865d9d20cc131904bca3 100644 (file)
@@ -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);
index 9a105cbd83788ce483e642e1062a810204da426c..4dd12ee6f4e06235092b6660d0688f74b9e7ac74 100644 (file)
@@ -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);
 
index 6e2b1fe34835a34074a8a12a691561ea18e0dbec..c2dca94bada46994b19dfc723b6190bf1b7d76b1 100644 (file)
@@ -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));
index 4b289a9ea75b03975035e3c4a739a56398eaca78..fad1e3b0408a7c3d96f800d83f19d928ca616e70 100644 (file)
@@ -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);
 
index 58de67a8af52f588f79f01d5b4811c1bbc2abaf2..f64522b43ab55556a04c99bf3878a7bab2c5e6bc 100644 (file)
@@ -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
index 6a6d09e219a41e2a65ae7d7dde50802b3603f75b..2812ab5a37a5635f0dbabfee6bce42e04708d5cb 100644 (file)
@@ -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)
index e67393aba929afcd370f1d3c8faa50f84b49f170..daf9a277ec4e0b4002d21780d4dfd177c725d215 100644 (file)
@@ -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);
index 112a0467f8d1aea9039301198457d1fb4a0c9b26..ff0c99f7f60ff21ea306ef04ceb46e651ccb48e4 100644 (file)
@@ -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);
index b426f150dd3ca1d2ce97de5a856fef381aff9925..9c2ef79479295ccc2f058847b1472c7a6b19ca4b 100644 (file)
@@ -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
index 1419d523b0aee7d19db08a0df05e86c303b15a8c..3a3f40728993357292316e87076bd7b206d503f7 100644 (file)
@@ -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");
 }
index fd634af65f572f97a2fb22b295807875b2475c86..6f40ebd636baf5e296b60d2da403bad690a2a567 100644 (file)
@@ -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);
index f5cc6d6feb18dc509ff5ed539c4ec88383b59fac..9bf0e65e0133941a6ae01d0342355c5103e122d6 100644 (file)
@@ -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);
index bfd806d28e9ddb90610f014a4f0aadaa938e4a63..3a4123e2447d0b2c1273ea71c610be7ed32c8343 100644 (file)
@@ -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();