]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
re-merged rt18194 after fixing problems
authorEvan Hunt <each@isc.org>
Thu, 3 Jul 2008 00:14:13 +0000 (00:14 +0000)
committerEvan Hunt <each@isc.org>
Thu, 3 Jul 2008 00:14:13 +0000 (00:14 +0000)
lib/dns/dispatch.c
lib/isc/include/isc/socket.h
lib/isc/unix/socket.c
lib/isc/win32/socket.c

index e60188650851a5f3351a4afc20b75003eebdcec1..7d531177e940325906b1276fe51378dff3095359 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dispatch.c,v 1.137.128.7 2008/06/26 22:16:58 jinmei Exp $ */
+/* $Id: dispatch.c,v 1.137.128.8 2008/07/03 00:14:13 each Exp $ */
 
 /*! \file */
 
@@ -803,6 +803,8 @@ destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
  */
 static void
 deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
+       isc_result_t result;
+
        /*
         * The dispatch must be locked.
         */
@@ -815,8 +817,18 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
        if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
                destroy_dispsocket(disp, &dispsock);
        else {
-               isc_socket_close(dispsock->socket);
-               ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
+               result = isc_socket_close(dispsock->socket);
+               if (result == ISC_R_SUCCESS)
+                       ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
+               else {
+                       /*
+                        * If the underlying system does not allow this
+                        * optimization, destroy this temporary structure (and
+                        * create a new one for a new transaction).
+                        */
+                       INSIST(result == ISC_R_NOTIMPLEMENTED);
+                       destroy_dispsocket(disp, &dispsock);
+               }
        }
 }
 
index 348c0732a10f6b3a0f26dc4e6789b1bbc3e33bc4..4cc0a56c356fb971487327e24d1d024c21135ff2 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.h,v 1.72.128.4 2008/06/24 23:46:26 tbox Exp $ */
+/* $Id: socket.h,v 1.72.128.5 2008/07/03 00:14:13 each Exp $ */
 
 #ifndef ISC_SOCKET_H
 #define ISC_SOCKET_H 1
@@ -369,7 +369,8 @@ isc_socket_open(isc_socket_t *sock);
  * avoid overhead of destroying and creating sockets when many short-lived
  * sockets are frequently opened and closed.  When the efficiency is not an
  * issue, it should be safer to detach the unused socket and re-create a new
- * one.
+ * one.  This optimization may not be available for some systems, in which
+ * case this function will return ISC_R_NOTIMPLEMENTED and must not be used.
  *
  * Requires:
  *
@@ -379,15 +380,18 @@ isc_socket_open(isc_socket_t *sock);
  *
  * Returns:
  *     Same as isc_socket_create().
+ * \li ISC_R_NOTIMPLEMENTED
  */
 
-void
+isc_result_t
 isc_socket_close(isc_socket_t *sock);
 /*%<
  * Close a socket file descriptor of the given socket structure.  This function
  * is provided as an alternative to destroying an unused socket when overhead
  * destroying/re-creating sockets can be significant, and is expected to be
- * used with isc_socket_open().
+ * used with isc_socket_open().  This optimization may not be available for some
+ * systems, in which case this function will return ISC_R_NOTIMPLEMENTED and
+ * must not be used.
  *
  * Requires:
  *
@@ -397,6 +401,8 @@ isc_socket_close(isc_socket_t *sock);
  *
  * \li There must be no pending I/O requests.
  *
+ * Returns:
+ * \li #ISC_R_NOTIMPLEMENTED
  */
 
 isc_result_t
index e75ffb7c861a54ce8ad1415502c0e5e1045a31fd..f4cba28ba8cbbfb88e58667fcae2d994ed45d895 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.275.10.9 2008/06/25 22:57:01 jinmei Exp $ */
+/* $Id: socket.c,v 1.275.10.10 2008/07/03 00:14:13 each Exp $ */
 
 /*! \file */
 
@@ -2195,7 +2195,7 @@ isc_socket_detach(isc_socket_t **socketp) {
        *socketp = NULL;
 }
 
-void
+isc_result_t
 isc_socket_close(isc_socket_t *sock) {
        int fd;
 
@@ -2229,6 +2229,8 @@ isc_socket_close(isc_socket_t *sock) {
        isc_sockaddr_any(&sock->peer_address);
 
        closesocket(sock->manager, sock->type, fd);
+
+       return (ISC_R_SUCCESS);
 }
 
 /*
index 9e618be816168bf1a89d58e0a055b1b80df89ef1..113acd2b9f7f1d858550c7f97cf21b6f7286238e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.52.94.4 2008/07/01 02:09:10 each Exp $ */
+/* $Id: socket.c,v 1.52.94.5 2008/07/03 00:14:13 each Exp $ */
 
 /* This code has been rewritten to take advantage of Windows Sockets
  * I/O Completion Ports and Events. I/O Completion Ports is ONLY
@@ -1173,7 +1173,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
 
        memset(msg, 0, sizeof(*msg));
 
-       if (!sock->connected) {
+       if (sock->type == isc_sockettype_udp) {
                msg->msg_name = (void *)&dev->address.type.sa;
                msg->msg_namelen = dev->address.length;
        } else {
@@ -1869,8 +1869,16 @@ free_socket(isc_socket_t **socketp) {
        *socketp = NULL;
 }
 
-static isc_result_t
-internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
+/*
+ * Create a new 'type' socket managed by 'manager'.  Events
+ * will be posted to 'task' and when dispatched 'action' will be
+ * called with 'arg' as the arg value.  The new socket is returned
+ * in 'socketp'.
+ */
+isc_result_t
+isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
+                 isc_socket_t **socketp) {
+       isc_socket_t *sock = NULL;
        isc_result_t result;
 #if defined(USE_CMSG)
        int on = 1;
@@ -1882,9 +1890,17 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
        int socket_errno;
        char strbuf[ISC_STRERRORSIZE];
 
-       switch (sock->type) {
+       REQUIRE(VALID_MANAGER(manager));
+       REQUIRE(socketp != NULL && *socketp == NULL);
+
+       result = allocate_socket(manager, type, &sock);
+       if (result != ISC_R_SUCCESS)
+               return (result);
+
+       sock->pf = pf;
+       switch (type) {
        case isc_sockettype_udp:
-               sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP);
+               sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
                if (sock->fd != INVALID_SOCKET) {
                        result = connection_reset_fix(sock->fd);
                        if (result != ISC_R_SUCCESS) {
@@ -1895,12 +1911,13 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
                }
                break;
        case isc_sockettype_tcp:
-               sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP);
+               sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);
                break;
        }
 
        if (sock->fd == INVALID_SOCKET) {
                socket_errno = WSAGetLastError();
+               free_socket(&sock);
 
                switch (socket_errno) {
                case WSAEMFILE:
@@ -1928,17 +1945,19 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
        result = make_nonblock(sock->fd);
        if (result != ISC_R_SUCCESS) {
                closesocket(sock->fd);
+               free_socket(&sock);
                return (result);
        }
 
+
 #if defined(USE_CMSG) || defined(SO_RCVBUF)
-       if (sock->type == isc_sockettype_udp) {
+       if (type == isc_sockettype_udp) {
 
 #if defined(USE_CMSG)
 #if defined(ISC_PLATFORM_HAVEIPV6)
 #ifdef IPV6_RECVPKTINFO
                /* 2292bis */
-               if ((sock->pf == AF_INET6)
+               if ((pf == AF_INET6)
                    && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
                                   (void *)&on, sizeof(on)) < 0)) {
                        isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
@@ -1953,7 +1972,7 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
                }
 #else
                /* 2292 */
-               if ((sock->pf == AF_INET6)
+               if ((pf == AF_INET6)
                    && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
                                   (void *)&on, sizeof(on)) < 0)) {
                        isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
@@ -1969,7 +1988,7 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
 #endif /* IPV6_RECVPKTINFO */
 #ifdef IPV6_USE_MIN_MTU        /*2292bis, not too common yet*/
                /* use minimum MTU */
-               if (sock->pf == AF_INET6) {
+               if (pf == AF_INET6) {
                        (void)setsockopt(sock->fd, IPPROTO_IPV6,
                                         IPV6_USE_MIN_MTU,
                                         (void *)&on, sizeof(on));
@@ -1992,36 +2011,6 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
        }
 #endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */
 
-       return (ISC_R_SUCCESS);
-}
-
-
-/*
- * Create a new 'type' socket managed by 'manager'.  Events
- * will be posted to 'task' and when dispatched 'action' will be
- * called with 'arg' as the arg value.  The new socket is returned
- * in 'socketp'.
- */
-isc_result_t
-isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
-                 isc_socket_t **socketp) {
-       isc_socket_t *sock = NULL;
-       isc_result_t result;
-
-       REQUIRE(VALID_MANAGER(manager));
-       REQUIRE(socketp != NULL && *socketp == NULL);
-
-       result = allocate_socket(manager, type, &sock);
-       if (result != ISC_R_SUCCESS)
-               return (result);
-
-       sock->pf = pf;
-       result = internal_open(manager, sock);
-       if (result != ISC_R_SUCCESS) {
-               free_socket(&sock);
-               return (result);
-       }
-
        sock->references = 1;
        *socketp = sock;
 
@@ -2043,25 +2032,9 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
 
 isc_result_t
 isc_socket_open(isc_socket_t *sock) {
-       isc_result_t result;
-
        REQUIRE(VALID_SOCKET(sock));
 
-       LOCK(&sock->lock);
-       REQUIRE(sock->references == 1);
-       UNLOCK(&sock->lock);
-
-       /*
-        * We don't need to retain the lock hereafter, since no one else has
-        * this socket.
-        */
-       REQUIRE(sock->fd == -1);
-
-       result = internal_open(sock->manager, sock);
-       if (result != ISC_R_SUCCESS)
-               sock->fd = -1;
-
-       return (result);
+       return (ISC_R_NOTIMPLEMENTED);
 }
 
 /*
@@ -2105,36 +2078,11 @@ isc_socket_detach(isc_socket_t **socketp) {
        *socketp = NULL;
 }
 
-void
+isc_result_t
 isc_socket_close(isc_socket_t *sock) {
        REQUIRE(VALID_SOCKET(sock));
 
-       LOCK(&sock->lock);
-       REQUIRE(sock->references == 1);
-       UNLOCK(&sock->lock);
-       /*
-        * We don't need to retain the lock hereafter, since no one else has
-        * this socket.
-        */
-       REQUIRE(sock->fd >= 0);
-
-       INSIST(!sock->connecting);
-       INSIST(!sock->pending_recv);
-       INSIST(!sock->pending_send);
-       INSIST(!sock->pending_accept);
-       INSIST(ISC_LIST_EMPTY(sock->recv_list));
-       INSIST(ISC_LIST_EMPTY(sock->send_list));
-       INSIST(ISC_LIST_EMPTY(sock->accept_list));
-       INSIST(sock->connect_ev == NULL);
-
-       sock->fd = -1;
-       sock->listener = 0;
-       sock->connected = 0;
-       sock->connecting = 0;
-       sock->bound = 0;
-       isc_sockaddr_any(&sock->address);
-
-       socket_close(sock);
+       return (ISC_R_NOTIMPLEMENTED);
 }
 
 /*