]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2036. [bug] 'rndc recursing' could cause trigger a REQUIRE.
authorMark Andrews <marka@isc.org>
Sun, 4 Jun 2006 23:59:33 +0000 (23:59 +0000)
committerMark Andrews <marka@isc.org>
Sun, 4 Jun 2006 23:59:33 +0000 (23:59 +0000)
                        [RT #16075]

CHANGES
bin/named/client.c
bin/named/include/named/client.h
bin/named/query.c

diff --git a/CHANGES b/CHANGES
index 2e18766996bc1e8a6140f20789105a62a1cbb48b..0046e4e564c9a6efbac1ece2acc028e35e9017d1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2036.  [bug]           'rndc recursing' could cause trigger a REQUIRE.
+                       [RT #16075]
+
 2035.  [func]          Make falling back to TCP on UDP refresh failure
                        optional. Default "try-tcp-refresh yes;" for BIND 8
                        compatibility. [RT #16123]
index 336433f6cbe7609db895fbd5afb77b0523f247fe..af518ff51a9a555786a63cba133dcb5ba177dce0 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: client.c,v 1.236 2006/05/29 01:27:58 marka Exp $ */
+/* $Id: client.c,v 1.237 2006/06/04 23:59:33 marka Exp $ */
 
 #include <config.h>
 
@@ -321,8 +321,17 @@ exit_check(ns_client_t *client) {
                }
                /*
                 * I/O cancel is complete.  Burn down all state
-                * related to the current request.
+                * related to the current request.  Ensure that
+                * the client is on the active list and not the
+                * recursing list.
                 */
+               LOCK(&client->manager->lock);
+               if (client->list == &client->manager->recursing) {
+                       ISC_LIST_UNLINK(*client->list, client, link);
+                       ISC_LIST_APPEND(client->manager->active, client, link);
+                       client->list = &client->manager->active;
+               }
+               UNLOCK(&client->manager->lock);
                ns_client_endrequest(client);
 
                client->state = NS_CLIENTSTATE_READING;
@@ -2594,3 +2603,20 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
        }
        UNLOCK(&manager->lock);
 }
+
+void
+ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
+
+       if (client->manager != NULL)
+               LOCK(&client->manager->lock);
+       if (client->query.restarts > 0) {
+               /*
+                * client->query.qname was dynamically allocated.
+                */
+               dns_message_puttempname(client->message,
+                                       &client->query.qname);
+       }
+       client->query.qname = name;
+       if (client->manager != NULL)
+               UNLOCK(&client->manager->lock);
+}
index 44e25668a8fd156d2a34e77a35ae05d739ff0d60..82881eb416851d1c6c165fc8062aef375db6ac56 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: client.h,v 1.77 2005/08/15 01:21:04 marka Exp $ */
+/* $Id: client.h,v 1.78 2006/06/04 23:59:33 marka Exp $ */
 
 #ifndef NAMED_CLIENT_H
 #define NAMED_CLIENT_H 1
@@ -344,6 +344,12 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
  * Dump the outstanding recursive queries to 'f'.
  */
 
+void
+ns_client_qnamereplace(ns_client_t *client, dns_name_t *name);
+/*%
+ * Replace the qname.
+ */
+
 isc_boolean_t
 ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
                  isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
index b274d4377a4680d12896996d5ecfc11acd2d16b7..ddd91508de8a6d4e0d3cb3df41450430d60e4e8d 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: query.c,v 1.287 2006/05/26 02:44:02 marka Exp $ */
+/* $Id: query.c,v 1.288 2006/06/04 23:59:33 marka Exp $ */
 
 /*! \file */
 
@@ -179,18 +179,6 @@ query_next(ns_client_t *client, isc_result_t result) {
        ns_client_next(client, result);
 }
 
-static inline void
-query_maybeputqname(ns_client_t *client) {
-       if (client->query.restarts > 0) {
-               /*
-                * client->query.qname was dynamically allocated.
-                */
-               dns_message_puttempname(client->message,
-                                       &client->query.qname);
-               client->query.qname = NULL;
-       }
-}
-
 static inline void
 query_freefreeversions(ns_client_t *client, isc_boolean_t everything) {
        ns_dbversion_t *dbversion, *dbversion_next;
@@ -271,8 +259,14 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
                }
        }
 
-       query_maybeputqname(client);
-
+       if (client->query.restarts > 0) {
+               /*
+                * client->query.qname was dynamically allocated.
+                */
+               dns_message_puttempname(client->message,
+                                       &client->query.qname);
+       }
+       client->query.qname = NULL;
        client->query.attributes = (NS_QUERYATTR_RECURSIONOK |
                                    NS_QUERYATTR_CACHEOK |
                                    NS_QUERYATTR_SECURE);
@@ -4004,8 +3998,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                        goto cleanup;
                }
                dns_rdata_freestruct(&cname);
-               query_maybeputqname(client);
-               client->query.qname = tname;
+               ns_client_qnamereplace(client, tname);
                want_restart = ISC_TRUE;
                if (!WANTRECURSION(client))
                        options |= DNS_GETDB_NOLOG;
@@ -4122,8 +4115,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                /*
                 * Switch to the new qname and restart.
                 */
-               query_maybeputqname(client);
-               client->query.qname = fname;
+               ns_client_qnamereplace(client, fname);
                fname = NULL;
                want_restart = ISC_TRUE;
                if (!WANTRECURSION(client))