]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2412. [bug] win32: address a resourse leak. [RT #18374]
authorMark Andrews <marka@isc.org>
Fri, 8 Aug 2008 06:00:42 +0000 (06:00 +0000)
committerMark Andrews <marka@isc.org>
Fri, 8 Aug 2008 06:00:42 +0000 (06:00 +0000)
CHANGES
lib/isc/include/isc/msgs.h
lib/isc/win32/errno2result.c
lib/isc/win32/net.c
lib/isc/win32/socket.c

diff --git a/CHANGES b/CHANGES
index 6c2de35748eb9b3490d0e75fe9630e690a0aab37..704d3b09c02509fbc46d6a0b84023c20d4d03ca5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+2412.  [bug]           win32: address a resourse leak. [RT #18374]
+
 2411.  [bug]           Allow using a larger number of sockets than FD_SETSIZE
                        for select().  To enable this, set ISC_SOCKET_MAXSOCKETS
                        at compilation time.  [RT #18433]
index 967005bf35317fb231ada9a8d02ae9d2aef5c333..2b0fa9a84e1d2d6254739b688b1dce761ffde94a 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: msgs.h,v 1.5.2.2.8.3 2004/03/06 08:14:44 marka Exp $ */
+/* $Id: msgs.h,v 1.5.2.2.8.4 2008/08/08 06:00:42 marka Exp $ */
 
 #ifndef ISC_MSGS_H
 #define ISC_MSGS_H 1
 #define ISC_MSG_ACCEPTRETURNED 1418 /* accept() returned %d/%s */
 #define ISC_MSG_TOOMANYFDS     1419 /* %s: too many open file descriptors */
 #define ISC_MSG_ZEROPORT       1420 /* dropping source port zero packet */
-#define ISC_MSG_FILTER        1420 /* setsockopt(SO_ACCEPTFILTER): %s */
+#define ISC_MSG_FILTER        1421 /* setsockopt(SO_ACCEPTFILTER): %s */
+
+#define ISC_MSG_TOOMANYHANDLES 1422 /*%< %s: too many open WSA event handles: %s */
 
 #define ISC_MSG_AWAKE         1502 /* "awake" */
 #define ISC_MSG_WORKING               1503 /* "working" */
index 3fb88f7171dd251b19c785ffa3b53eb5425f2980..5b15858279c22a0c2424e25b322a9c29b07d8dfd 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: errno2result.c,v 1.4.2.5.2.9 2007/08/28 07:19:17 tbox Exp $ */
+/* $Id: errno2result.c,v 1.4.2.5.2.10 2008/08/08 06:00:42 marka Exp $ */
 
 #include <config.h>
 
@@ -61,14 +61,24 @@ isc__errno2resultx(int posixerrno, const char *file, int line) {
        case EMFILE:
        case WSAEMFILE:
                return (ISC_R_TOOMANYOPENFILES);
-       case ERROR_OPERATION_ABORTED:
-               return (ISC_R_CONNECTIONRESET);
-       case ERROR_PORT_UNREACHABLE:
-               return (ISC_R_HOSTUNREACH);
+       case ERROR_CANCELLED:
+               return (ISC_R_CANCELED);
+       case ERROR_CONNECTION_REFUSED:
+               return (ISC_R_CONNREFUSED);
+       case ERROR_CONNECTION_INVALID:
+               return (ISC_R_NOTCONNECTED);
        case ERROR_HOST_UNREACHABLE:
                return (ISC_R_HOSTUNREACH);
        case ERROR_NETWORK_UNREACHABLE:
                return (ISC_R_NETUNREACH);
+       case ERROR_NO_NETWORK:
+               return (ISC_R_NETUNREACH);
+       case ERROR_OPERATION_ABORTED:
+               return (ISC_R_CONNECTIONRESET);
+       case ERROR_PORT_UNREACHABLE:
+               return (ISC_R_HOSTUNREACH);
+       case ERROR_REQUEST_ABORTED:
+               return (ISC_R_CONNECTIONRESET);
        case WSAEADDRNOTAVAIL:
                return (ISC_R_ADDRNOTAVAIL);
        case WSAEHOSTUNREACH:
index 300ec51060a2a767d784f1c6d517c8ae8e556be8..f05736e732f927526d5659b1f36508350e754720 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: net.c,v 1.3.2.2.4.13 2008/07/01 05:40:13 jinmei Exp $ */
+/* $Id: net.c,v 1.3.2.2.4.14 2008/08/08 06:00:42 marka Exp $ */
 
 #include <config.h>
 
@@ -237,7 +237,8 @@ try_ipv6pktinfo(void) {
        optname = IPV6_PKTINFO;
 #endif
        on = 1;
-       if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) {
+       if (setsockopt(s, IPPROTO_IPV6, optname, (const char *) &on,
+                      sizeof(on)) < 0) {
                ipv6pktinfo_result = ISC_R_NOTFOUND;
                goto close;
        }
index c6794dd1f4728460e0094b72749849cfd8022bea..fdd37e7dad53bcaad2cfb329d0ac156080aae46e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.5.2.13.2.34 2008/08/01 02:12:46 jinmei Exp $ */
+/* $Id: socket.c,v 1.5.2.13.2.35 2008/08/08 06:00:42 marka Exp $ */
 
 /* This code has been rewritten to take advantage of Windows Sockets
  * I/O Completion Ports and Events. I/O Completion Ports is ONLY
 #define PENDING_ERROR(e) ((e) == WSA_IO_PENDING || (e) == 0)
 
 #define DOIO_SUCCESS     0       /* i/o ok, event sent */
-#define DOIO_SOFT           1       /* i/o ok, soft error, no event sent */
-#define DOIO_HARD           2       /* i/o error, event sent */
-#define DOIO_EOF             3       /* EOF, no event sent */
+#define DOIO_SOFT        1       /* i/o ok, soft error, no event sent */
+#define DOIO_HARD        2       /* i/o error, event sent */
+#define DOIO_EOF         3       /* EOF, no event sent */
 #define DOIO_PENDING     4       /* status when i/o is in process */
 
 #define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x)
@@ -533,10 +533,13 @@ iocompletionport_update(isc_socket_t *sock) {
        }
 }
 
-void
+isc_result_t
 socket_event_minit(sock_event_list *evlist) {
        BOOL bReset;
        int i;
+       int stat;
+       WSAEVENT hEvent;
+       char strbuf[ISC_STRERRORSIZE];
 
        REQUIRE(evlist != NULL);
        /* Initialize the Event List */
@@ -547,9 +550,28 @@ socket_event_minit(sock_event_list *evlist) {
                evlist->aEventList[i] = (WSAEVENT) 0;
        }
 
-       evlist->aEventList[0] = WSACreateEvent();
+       /*
+        * The event list needs its own event handle so that when we
+        * want to change the list the event loop can be notified.
+        */
+       hEvent = WSACreateEvent();
+       if (hEvent == WSA_INVALID_EVENT) {
+               stat = WSAGetLastError();
+               isc__strerror(stat, strbuf, sizeof(strbuf));
+               isc_log_iwrite(isc_lctx,
+                               ISC_LOGCATEGORY_GENERAL,
+                               ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+                               isc_msgcat, ISC_MSGSET_SOCKET,
+                               ISC_MSG_TOOMANYHANDLES,
+                               "%s: too many open WSA event handles: %s",
+                               "WSACreateEvent", strbuf);
+               return (ISC_R_UNEXPECTED);
+       }
+
+       evlist->aEventList[0] = hEvent;
        (evlist->max_event)++;
        bReset = WSAResetEvent(evlist->aEventList[0]);
+       return (ISC_R_SUCCESS);
 }
 /*
  * Event Thread Initialization
@@ -562,7 +584,10 @@ event_thread_create(events_thread_t **evthreadp, isc_socketmgr_t *manager) {
        REQUIRE(evthreadp != NULL && *evthreadp == NULL);
 
        evthread = isc_mem_get(manager->mctx, sizeof(*evthread));
-       socket_event_minit(&evthread->sockev_list);
+       if (socket_event_minit(&evthread->sockev_list) != ISC_R_SUCCESS) {
+               isc_mem_put(manager->mctx, evthread, sizeof(*evthread));
+               return (ISC_R_UNEXPECTED);
+       }
        ISC_LINK_INIT(evthread, link);
        evthread->manager = manager;
 
@@ -638,21 +663,25 @@ socket_eventlist_add(event_change_t *evchange, sock_event_list *evlist,
                locate_available_thread(manager);
                return (ISC_FALSE);
        }
-
+       /*
+        * Lock the socket before updating
+        */
+       LOCK(&sock->lock);
        evlist->aSockList[max_event] = sock;
        evlist->aEventList[max_event] = sock->hEvent;
        evlist->max_event++;
        evlist->total_events++;
        sock->hAlert = evlist->aEventList[0];
        sock->evthread_id = GetCurrentThreadId();
+       UNLOCK(&sock->lock);
        return (ISC_TRUE);
 }
 
 /*
- * Note that the eventLock is locked before calling this function.
+ * Delete the event from the list
  */
 isc_boolean_t
-socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist,
+eventlist_event_delete(isc_socket_t *sock, sock_event_list *evlist,
                        isc_socketmgr_t *manager)
 {
        int i;
@@ -660,14 +689,11 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist,
        int iEvent = -1;
        isc_boolean_t dofree = ISC_FALSE;
 
-       REQUIRE(evchange != NULL);
-       /*  Make sure this is the right thread from which to delete the event */
-       if (evchange->evthread_id != GetCurrentThreadId())
-               return (ISC_FALSE);
-
+       REQUIRE(sock != NULL);
        REQUIRE(evlist != NULL);
-       REQUIRE(evchange->hEvent != NULL);
-       hEvent = evchange->hEvent;
+       REQUIRE(manager != NULL);
+       REQUIRE(sock->hEvent != NULL);
+       hEvent = sock->hEvent;
 
        /* Find the Event */
        for (i = 1; i < evlist->max_event; i++) {
@@ -677,7 +703,10 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist,
                }
        }
 
-       /* Actual event start at 1 */
+       /*
+        * Actual event start at 1
+        * event at 0 is the thread wakeup
+        */
        if (iEvent < 1)
                return (ISC_FALSE);
 
@@ -692,21 +721,25 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist,
        /* Cleanup */
        WSACloseEvent(hEvent);
 
-       LOCK(&evchange->sock->lock);
-       if (evchange->sock->pending_close) {
-               evchange->sock->pending_close = 0;
-               closesocket(evchange->fd);
+       LOCK(&sock->lock);
+       sock->hEvent = NULL;
+       sock->hAlert = NULL;
+       sock->wait_type = 0;
+
+       if (sock->pending_close) {
+               sock->pending_close = 0;
+               closesocket(sock->fd);
        }
-       if (evchange->sock->pending_recv == 0 &&
-           evchange->sock->pending_send == 0 &&
-           evchange->sock->pending_free) {
-               evchange->sock->pending_free = 0;
-               ISC_LIST_UNLINK(manager->socklist, evchange->sock, link);
+       if (sock->pending_recv == 0 &&
+           sock->pending_send == 0 &&
+           sock->pending_free) {
+               sock->pending_free = 0;
+               ISC_LIST_UNLINK(manager->socklist, sock, link);
                dofree = ISC_TRUE;
        }
-       UNLOCK(&evchange->sock->lock);
+       UNLOCK(&sock->lock);
        if (dofree)
-               free_socket(&evchange->sock);
+               free_socket(&sock);
 
        if (ISC_LIST_EMPTY(manager->socklist))
                SIGNAL(&manager->shutdown_ok);
@@ -717,6 +750,21 @@ socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist,
        return (ISC_TRUE);
 }
 
+/*
+ * Note that the eventLock is locked before calling this function.
+ */
+isc_boolean_t
+socket_eventlist_delete(event_change_t *evchange, sock_event_list *evlist,
+                       isc_socketmgr_t *manager)
+{
+
+       REQUIRE(evchange != NULL);
+       /*  Make sure this is the right thread from which to delete the event */
+       if (evchange->evthread_id != GetCurrentThreadId())
+               return (ISC_FALSE);
+
+       return (eventlist_event_delete(evchange->sock, evlist, manager));
+}
 /*
  * Get the event changes off of the list and apply the
  * requested changes. The manager lock is taken out at
@@ -843,10 +891,13 @@ socket_event_add(isc_socket_t *sock, long type) {
        if (hEvent == WSA_INVALID_EVENT) {
                stat = WSAGetLastError();
                isc__strerror(stat, strbuf, sizeof(strbuf));
-               msg = isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
-                                    ISC_MSG_FAILED, "failed"),
-               UNEXPECTED_ERROR(__FILE__, __LINE__, "WSACreateEvent: %s: %s",
-                                msg, strbuf);
+               isc_log_iwrite(isc_lctx,
+                               ISC_LOGCATEGORY_GENERAL,
+                               ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+                               isc_msgcat, ISC_MSGSET_SOCKET,
+                               ISC_MSG_TOOMANYHANDLES,
+                               "%s: too many open WSA event handles: %s",
+                               "WSACreateEvent", strbuf);
                return (ISC_R_UNEXPECTED);
        }
        if (WSAEventSelect(sock->fd, hEvent, type) != 0) {
@@ -866,7 +917,11 @@ socket_event_add(isc_socket_t *sock, long type) {
 }
 
 /*
- * Note that the socket is not locked before calling this function
+ * Note that the socket is locked before calling this function
+ * Note also that we cannot close the socket here or event handle being
+ * used since the event is being waited upon and any change to either
+ * will signal the change. The notify_eventlist will take care of
+ * these details.
  */
 void
 socket_event_delete(isc_socket_t *sock) {
@@ -877,8 +932,6 @@ socket_event_delete(isc_socket_t *sock) {
        sock->wait_type = 0;
        sock->pending_close = 1;
        notify_eventlist(sock, sock->manager, EVENT_DELETE);
-       sock->hEvent = NULL;
-       sock->hAlert = NULL;
        sock->evthread_id = 0;
 }
 
@@ -888,6 +941,7 @@ socket_event_delete(isc_socket_t *sock) {
  * with an event, otherwise the WSAWaitForMultipleEvents
  * may fail due to the fact that the the Wait should not
  * be running while closing an event or a socket.
+ * The socket is locked before calling this function
  */
 void
 socket_close(isc_socket_t *sock) {
@@ -951,7 +1005,7 @@ internal_sendmsg(isc_socket_t *sock, IoCompletionInfo *lpo,
        int total_sent;
 
        *Error = 0;
-       Result = WSASendTo((SOCKET) sock->fd, messagehdr->msg_iov,
+       Result = WSASendTo(sock->fd, messagehdr->msg_iov,
                           messagehdr->msg_iovlen, &BytesSent,
                           Flags, messagehdr->msg_name,
                           messagehdr->msg_namelen, (LPOVERLAPPED) lpo,
@@ -1397,6 +1451,7 @@ completeio_recv(isc_socket_t *sock, isc_socketevent_t *dev,
                SOFT_OR_HARD(WSAEDISCON, ISC_R_CONNECTIONRESET);
                SOFT_OR_HARD(WSAENETDOWN, ISC_R_NETDOWN);
                ALWAYS_HARD(ERROR_OPERATION_ABORTED, ISC_R_CONNECTIONRESET);
+               ALWAYS_HARD(ERROR_REQUEST_ABORTED, ISC_R_CONNECTIONRESET);
                ALWAYS_HARD(ERROR_NETNAME_DELETED, ISC_R_CONNECTIONRESET);
                ALWAYS_HARD(ERROR_PORT_UNREACHABLE, ISC_R_HOSTUNREACH);
                ALWAYS_HARD(ERROR_HOST_UNREACHABLE, ISC_R_HOSTUNREACH);
@@ -1600,6 +1655,7 @@ completeio_send(isc_socket_t *sock, isc_socketevent_t *dev,
                ALWAYS_HARD(ERROR_PORT_UNREACHABLE, ISC_R_HOSTUNREACH);
                ALWAYS_HARD(ERROR_HOST_UNREACHABLE, ISC_R_HOSTUNREACH);
                ALWAYS_HARD(ERROR_NETWORK_UNREACHABLE, ISC_R_NETUNREACH);
+               ALWAYS_HARD(ERROR_REQUEST_ABORTED, ISC_R_CONNECTIONRESET);
                ALWAYS_HARD(WSAEADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);
                ALWAYS_HARD(WSAEHOSTUNREACH, ISC_R_HOSTUNREACH);
                ALWAYS_HARD(WSAEHOSTDOWN, ISC_R_HOSTUNREACH);
@@ -1791,6 +1847,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
        sock->hAlert = NULL;
        sock->evthread_id = 0;
        sock->wait_type = 0;
+       memset(sock->name, 0, sizeof(sock->name));
 
        /*
         * initialize the lock
@@ -2014,10 +2071,7 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
        REQUIRE(VALID_SOCKET(sock));
        REQUIRE(socketp != NULL && *socketp == NULL);
 
-       LOCK(&sock->lock);
-       sock->references++;
-       UNLOCK(&sock->lock);
-
+       InterlockedIncrement(&sock->references);
        *socketp = sock;
 }
 
@@ -2118,6 +2172,8 @@ send_senddone_event(isc_socket_t *sock, isc_socketevent_t **dev) {
  * readable event, and the first item on the accept_list should be
  * the done event we want to send.  If the list is empty, this is a no-op,
  * so just unlock and return.
+ *
+ * Note the the socket is locked before entering here
  */
 static void
 internal_accept(isc_socket_t *sock, int accept_errno) {
@@ -2131,7 +2187,6 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
 
        INSIST(VALID_SOCKET(sock));
 
-       LOCK(&sock->lock);
        socket_log(sock, NULL, TRACE,
                   isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTLOCK,
                   "internal_accept called, locked socket");
@@ -2166,7 +2221,6 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
                                         strbuf);
                        break;
                }
-               UNLOCK(&sock->lock);
                return;
        }
 
@@ -2183,7 +2237,34 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
                 */
                addrlen = sizeof(from.type);
                fd = accept(sock->fd, &from.type.sa, &addrlen);
-               if (fd != INVALID_SOCKET) {
+               if (fd == INVALID_SOCKET) {
+                       accept_errno = WSAGetLastError();
+                       if (accept_errno == WSAEMFILE) {
+                               isc_log_iwrite(isc_lctx,
+                                       ISC_LOGCATEGORY_GENERAL,
+                                       ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+                                       isc_msgcat, ISC_MSGSET_SOCKET,
+                                       ISC_MSG_TOOMANYFDS,
+                                       "%s: too many open file descriptors",
+                                       "accept");
+                               goto soft_error;
+                       } else if (SOFT_ERROR(accept_errno) ||
+                                  accept_errno == WSAECONNRESET) {
+                               goto soft_error;
+                       } else {
+                               isc__strerror(accept_errno, strbuf, 
+                                             sizeof(strbuf));
+                               UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                        "internal_accept: accept() %s: %s",
+                                        isc_msgcat_get(isc_msgcat,
+                                                       ISC_MSGSET_GENERAL,
+                                                       ISC_MSG_FAILED,
+                                                       "failed"),
+                                        strbuf);
+                               fd = INVALID_SOCKET;
+                               result = ISC_R_UNEXPECTED;
+                       }
+               } else {
                        char addrbuf[ISC_SOCKADDR_FORMATSIZE];
                        isc_sockaddr_format(&from, addrbuf, sizeof(addrbuf));
                        UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -2192,7 +2273,6 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
                                         addrbuf);
                        (void)closesocket(fd);
                }
-               UNLOCK(&sock->lock);
                return;
        }
 
@@ -2265,7 +2345,7 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
        ISC_LIST_UNLINK(sock->accept_list, dev, ev_link);
 
        /*
-        * Stop listing for connects.
+        * Stop listening for connects.
         */
        if (ISC_LIST_EMPTY(sock->accept_list) &&
            WSAEventSelect(sock->fd, sock->hEvent, FD_CLOSE) != 0) {
@@ -2279,7 +2359,6 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
                                 msg, strbuf);
        }
 
-       UNLOCK(&sock->lock);
 
        if (fd != INVALID_SOCKET) {
                isc_result_t tresult;
@@ -2301,6 +2380,7 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
                dev->newsocket->fd = fd;
                dev->newsocket->bound = 1;
                dev->newsocket->connected = 1;
+               strncpy(sock->name, "acceptconnect", sizeof(sock->name) - 1);
 
                /*
                 * The accept socket inherits the listen socket's
@@ -2346,12 +2426,12 @@ internal_accept(isc_socket_t *sock, int accept_errno) {
        return;
 
  soft_error:
-       UNLOCK(&sock->lock);
        return;
 }
 
 /*
  * Called when a socket with a pending connect() finishes.
+ * Note that the socket is locked before entering.
  */
 static void
 internal_connect(isc_socket_t *sock, int connect_errno) {
@@ -2361,15 +2441,12 @@ internal_connect(isc_socket_t *sock, int connect_errno) {
 
        INSIST(VALID_SOCKET(sock));
 
-       LOCK(&sock->lock);
-
        /*
         * Has this event been canceled?
         */
        dev = sock->connect_ev;
        if (dev == NULL) {
                INSIST(!sock->connecting);
-               UNLOCK(&sock->lock);
                return;
        }
 
@@ -2388,7 +2465,6 @@ internal_connect(isc_socket_t *sock, int connect_errno) {
                    connect_errno == WSAEINPROGRESS)
                {
                        sock->connecting = 1;
-                       UNLOCK(&sock->lock);
                        return;
                }
 
@@ -2421,12 +2497,11 @@ internal_connect(isc_socket_t *sock, int connect_errno) {
                dev->result = ISC_R_SUCCESS;
                sock->connected = 1;
                sock->bound = 1;
+               strncpy(sock->name, "connected", sizeof(sock->name) - 1);
        }
 
        sock->connect_ev = NULL;
 
-       UNLOCK(&sock->lock);
-
        task = dev->ev_sender;
        dev->ev_sender = sock;
        isc_task_sendanddetach(&task, (isc_event_t **)&dev);
@@ -2449,6 +2524,12 @@ internal_recv(isc_socket_t *sock, isc_socketevent_t *dev,
 
        INSIST(sock->pending_recv > 0);
        sock->pending_recv--;
+
+       if (sock->references == 0) {
+               UNLOCK(&sock->lock);
+               destroy_socket(&sock);
+               return;
+       }
        /* If the event is no longer in the list we can just return */
        ldev = ISC_LIST_HEAD(sock->recv_list);
        while (ldev != NULL && ldev != dev) {
@@ -2526,7 +2607,6 @@ internal_send(isc_socket_t *sock, isc_socketevent_t *dev,
                break;
        }
 
-
  done:
        UNLOCK(&sock->lock);
 }
@@ -2766,13 +2846,16 @@ event_wait(void *uap) {
                }
 
                if (wsock->references > 0 && wsock->pending_close == 0) {
+                       LOCK(&wsock->lock);
                        if (wsock->listener == 1 &&
                            wsock->pending_accept == 0) {
                                wsock->pending_accept = 1;
                                internal_accept(wsock, event_errno);
-                       }
-                       else {
+                               UNLOCK(&wsock->lock);
+                       else {
                                internal_connect(wsock, event_errno);
+                               UNLOCK(&wsock->lock);
+                               eventlist_event_delete(wsock, evlist, manager);
                        }
                }
        }
@@ -3574,6 +3657,7 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
        if (cc == 0) {
                sock->connected = 1;
                sock->bound = 1;
+               strncpy(sock->name, "connect", sizeof(sock->name) - 1);
                dev->result = ISC_R_SUCCESS;
                isc_task_send(task, (isc_event_t **)&dev);
 
@@ -3827,7 +3911,6 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
        int onoff = yes ? 1 : 0;
 #else
        UNUSED(yes);
-       UNUSED(sock);
 #endif
 
        REQUIRE(VALID_SOCKET(sock));