]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix serve-stale hang at shutdown
authorMatthijs Mekking <matthijs@isc.org>
Thu, 1 Jun 2023 08:03:48 +0000 (10:03 +0200)
committerMichal Nowak <mnowak@isc.org>
Fri, 9 Jun 2023 13:53:10 +0000 (15:53 +0200)
The 'refresh_rrset' variable is used to determine if we can detach from
the client. This can cause a hang on shutdown. To fix this, move setting
of the 'nodetach' variable up to where 'refresh_rrset' is set (in
query_lookup(), and thus not in ns_query_done()), and set it to false
when actually refreshing the RRset, so that when this lookup is
completed, the client will be detached.

lib/ns/query.c

index 28bef2d99c9c01142c0adce28a5861dd8561b4f5..5cf502eef006ffce4a90c8f834579371fe3ab208 100644 (file)
@@ -5719,6 +5719,7 @@ query_refresh_rrset(query_ctx_t *orig_qctx) {
        qctx.client->query.dboptions &= ~(DNS_DBFIND_STALETIMEOUT |
                                          DNS_DBFIND_STALEOK |
                                          DNS_DBFIND_STALEENABLED);
+       qctx.client->nodetach = false;
 
        /*
         * We'll need some resources...
@@ -5976,7 +5977,14 @@ query_lookup(query_ctx_t *qctx) {
                                        "%s stale answer used, an attempt to "
                                        "refresh the RRset will still be made",
                                        namebuf);
+
                                qctx->refresh_rrset = STALE(qctx->rdataset);
+
+                               /*
+                                * If we are refreshing the RRSet, we must not
+                                * detach from the client in query_send().
+                                */
+                               qctx->client->nodetach = qctx->refresh_rrset;
                        }
                } else {
                        /*
@@ -11565,12 +11573,7 @@ ns_query_done(query_ctx_t *qctx) {
        /*
         * Client may have been detached after query_send(), so
         * we test and store the flag state here, for safety.
-        * If we are refreshing the RRSet, we must not detach from the client
-        * in the query_send(), so we need to override the flag.
         */
-       if (qctx->refresh_rrset) {
-               qctx->client->nodetach = true;
-       }
        nodetach = qctx->client->nodetach;
        query_send(qctx->client);