]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
dns_request_cancel needs to be callable from any thread
authorMark Andrews <marka@isc.org>
Wed, 6 Dec 2023 00:34:52 +0000 (11:34 +1100)
committerMark Andrews <marka@isc.org>
Wed, 20 Dec 2023 21:11:59 +0000 (08:11 +1100)
Check the tid and cancel the request immediately or pass it to the
appropriate loop for processing.  Call request->cb directly from
req_sendevent as it is now always called with the correct tid.

lib/dns/request.c

index c7e6a4061d9330d1f403ac89e1bf0bb63a05dc1a..14a96058c2ab8a311fca4f9029b9d83f19a73416 100644 (file)
@@ -745,8 +745,8 @@ cleanup:
        return (result);
 }
 
-void
-dns_request_cancel(dns_request_t *request) {
+static void
+request_cancel(dns_request_t *request) {
        REQUIRE(VALID_REQUEST(request));
        REQUIRE(request->tid == isc_tid());
 
@@ -759,6 +759,26 @@ dns_request_cancel(dns_request_t *request) {
        req_sendevent(request, ISC_R_CANCELED); /* call asynchronously */
 }
 
+static void
+req_cancel_cb(void *arg) {
+       dns_request_t *request = arg;
+
+       request_cancel(request);
+       dns_request_unref(request);
+}
+
+void
+dns_request_cancel(dns_request_t *request) {
+       REQUIRE(VALID_REQUEST(request));
+
+       if (request->tid == isc_tid()) {
+               request_cancel(request);
+       } else {
+               dns_request_ref(request);
+               isc_async_run(request->loop, req_cancel_cb, request);
+       }
+}
+
 isc_result_t
 dns_request_getresponse(dns_request_t *request, dns_message_t *message,
                        unsigned int options) {
@@ -959,6 +979,11 @@ req_sendevent(dns_request_t *request, isc_result_t result) {
 
        request->result = result;
 
+       /*
+        * Do not call request->cb directly as it introduces a dead lock
+        * between dns_zonemgr_shutdown and sendtoprimary in lib/dns/zone.c
+        * zone->lock.
+        */
        dns_request_ref(request);
        isc_async_run(request->loop, req_sendevent_cb, request);
 }