]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
pullup:
authorBrian Wellington <source@isc.org>
Wed, 26 Jul 2000 23:51:35 +0000 (23:51 +0000)
committerBrian Wellington <source@isc.org>
Wed, 26 Jul 2000 23:51:35 +0000 (23:51 +0000)
 352.   [bug]           Race condition in dns_client_t startup could cause
                        an assertion failure.

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

diff --git a/CHANGES b/CHANGES
index f09542a87ee1a50016b142a731b5c09c69d84bac..891d3e3f2b12a4455d5b01e1d484f381ec7c8e65 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,7 @@
 
+ 352.  [bug]           Race condition in dns_client_t startup could cause
+                       an assertion failure.
+
  351.  [bug]           Constructing a response with rcode SERVFAIL to a TSIG
                        signed query could crash the server.
 
index a4eeb13dc2b13cd98157590a5593a5be99b5a48b..003db2023e3f9fb11a46e2218a5f5a94402bdb07 100644 (file)
@@ -15,7 +15,7 @@
  * SOFTWARE.
  */
 
-/* $Id: client.c,v 1.98.2.2 2000/07/17 18:56:03 gson Exp $ */
+/* $Id: client.c,v 1.98.2.3 2000/07/26 23:51:31 bwelling Exp $ */
 
 #include <config.h>
 
@@ -163,6 +163,8 @@ static void clientmgr_destroy(ns_clientmgr_t *manager);
 static isc_boolean_t exit_check(ns_client_t *client);
 static void ns_client_endrequest(ns_client_t *client);
 static void ns_client_checkactive(ns_client_t *client);
+static void client_start(isc_task_t *task, isc_event_t *event);
+static void client_request(isc_task_t *task, isc_event_t *event);
 
 /*
  * Enter the inactive state.
@@ -431,6 +433,45 @@ exit_check(ns_client_t *client) {
        return (ISC_TRUE);
 }
 
+/*
+ * The client's task has received the client's control event
+ * as part of the startup process.
+ */
+static void
+client_start(isc_task_t *task, isc_event_t *event) {
+       ns_client_t *client = (ns_client_t *) event->ev_arg;
+       isc_result_t result;
+
+       INSIST(task == client->task);
+       
+       UNUSED(task);
+
+       if (TCP_CLIENT(client)) {
+               client_accept(client);
+       } else {
+               result = dns_dispatch_addrequest(client->dispatch,
+                                                client->task,
+                                                client_request,
+                                                client,
+                                                &client->dispentry);
+               
+               if (result != ISC_R_SUCCESS) {
+                       ns_client_log(client,
+                                     DNS_LOGCATEGORY_SECURITY,
+                                     NS_LOGMODULE_CLIENT,
+                                     ISC_LOG_DEBUG(3),
+                                     "dns_dispatch_addrequest() "
+                                     "failed: %s",
+                                     isc_result_totext(result));
+                       /*
+                        * Not much we can do here but log the failure; 
+                        * the client will effectively go idle.
+                        */
+               }
+       }
+}
+
+
 /*
  * The client's task has received a shutdown event.
  */
@@ -559,14 +600,14 @@ client_senddone(isc_task_t *task, isc_event_t *event) {
        ns_client_t *client;
        isc_socketevent_t *sevent = (isc_socketevent_t *) event;
 
-       UNUSED(task);
-
        REQUIRE(sevent != NULL);
        REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE);
        client = sevent->ev_arg;
        REQUIRE(NS_CLIENT_VALID(client));
        REQUIRE(task == client->task);
 
+       UNUSED(task);
+
        CTRACE("senddone");
 
        if (sevent->result != ISC_R_SUCCESS)
@@ -1195,6 +1236,9 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
        client->recursionquota = NULL;
        client->interface = NULL;
        client->peeraddr_valid = ISC_FALSE;
+       ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
+                      NS_EVENT_CLIENTCONTROL, client_start, client, client,
+                      NULL, NULL);
        ISC_LINK_INIT(client, link);
        client->list = NULL;
 
@@ -1272,7 +1316,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
        UNUSED(task);
 
        INSIST(client->state == NS_CLIENTSTATE_READY);
-       
+
        INSIST(client->naccepts == 1);
        client->naccepts--;
 
@@ -1529,6 +1573,7 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
        LOCK(&manager->lock);
 
        for (i = 0; i < n; i++) {
+               isc_event_t *ev;
                /*
                 * Allocate a client.  First try to get a recycled one;
                 * if that fails, make a new one.
@@ -1553,30 +1598,16 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
                        client->attributes |= NS_CLIENTATTR_TCP;
                        isc_socket_attach(ifp->tcpsocket,
                                          &client->tcplistener);
-                       client_accept(client);
                } else {
                        dns_dispatch_attach(ifp->udpdispatch,
                                            &client->dispatch);
-                       result = dns_dispatch_addrequest(client->dispatch,
-                                                        client->task,
-                                                        client_request,
-                                                        client,
-                                                        &client->dispentry);
-                       if (result != ISC_R_SUCCESS) {
-                               ns_client_log(client,
-                                             DNS_LOGCATEGORY_SECURITY,
-                                             NS_LOGMODULE_CLIENT,
-                                             ISC_LOG_DEBUG(3),
-                                             "dns_dispatch_addrequest() "
-                                             "failed: %s",
-                                             isc_result_totext(result));
-                               isc_task_shutdown(client->task);
-                               break;
-                       }
                }
                client->manager = manager;
                ISC_LIST_APPEND(manager->active, client, link);
                client->list = &manager->active;
+
+               ev = &client->ctlevent;
+               isc_task_send(client->task, &ev);
        }
        if (i != 0) {
                /*
index 922ce2ad3cbac184918e99d498ad5580e9cfe61d..37ef28d68ea78826c1909b246140b1870ef6ec1a 100644 (file)
@@ -15,7 +15,7 @@
  * SOFTWARE.
  */
 
-/* $Id: client.h,v 1.37 2000/06/22 21:49:38 tale Exp $ */
+/* $Id: client.h,v 1.37.2.1 2000/07/26 23:51:33 bwelling Exp $ */
 
 #ifndef NAMED_CLIENT_H
 #define NAMED_CLIENT_H 1
@@ -122,6 +122,7 @@ struct ns_client {
        isc_sockaddr_t          peeraddr;
        isc_boolean_t           peeraddr_valid;
        struct in6_pktinfo      pktinfo;
+       isc_event_t             ctlevent;
        ISC_LINK(ns_client_t)   link;
        /*
         * The list 'link' is part of, or NULL if not on any list.
index 427c1d5f2d196ce3dd99f5dcb79ade8c95cac2ff..e7ff95fd403af1df6a14cff45ce3d03346b56a6a 100644 (file)
@@ -15,7 +15,7 @@
  * SOFTWARE.
  */
 
-/* $Id: server.h,v 1.32 2000/06/22 21:49:51 tale Exp $ */
+/* $Id: server.h,v 1.32.2.1 2000/07/26 23:51:35 bwelling Exp $ */
 
 #ifndef NAMED_SERVER_H
 #define NAMED_SERVER_H 1
@@ -30,6 +30,7 @@
 
 #define NS_EVENTCLASS          ISC_EVENTCLASS(0x4E43)
 #define NS_EVENT_RELOAD                (NS_EVENTCLASS + 0)
+#define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1)
 
 /*
  * Name server state.  Better here than in lots of separate global variables.