]> 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:40 +0000 (00:14 +0000)
committerEvan Hunt <each@isc.org>
Thu, 3 Jul 2008 00:14:40 +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 f2f6911c253b2a241dc45361f6b6665f5753bbb5..6ffe1d0fcdaeccec2e4757fc0451a557a86015d8 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dispatch.c,v 1.116.18.24 2008/06/26 22:18:18 jinmei Exp $ */
+/* $Id: dispatch.c,v 1.116.18.25 2008/07/03 00:14:39 each Exp $ */
 
 /*! \file */
 
@@ -801,6 +801,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.
         */
@@ -813,8 +815,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 682f5d227583638dd57abfeb1c2786a22c177ddb..4a7d542eb2958d5274671dc3469cc1cb7fb7d3df 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.h,v 1.57.18.8 2008/06/24 23:45:55 tbox Exp $ */
+/* $Id: socket.h,v 1.57.18.9 2008/07/03 00:14:39 each Exp $ */
 
 #ifndef ISC_SOCKET_H
 #define ISC_SOCKET_H 1
@@ -320,7 +320,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:
  *
@@ -330,15 +331,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:
  *
@@ -348,6 +352,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 ebdc99171ff5e9fb437cc905615c2b5c1fd3b079..7dfa1a68c6a3c65f893f38a3901c337bbd102f75 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.237.18.37 2008/06/25 22:57:37 jinmei Exp $ */
+/* $Id: socket.c,v 1.237.18.38 2008/07/03 00:14:40 each Exp $ */
 
 /*! \file */
 
@@ -2113,7 +2113,7 @@ isc_socket_detach(isc_socket_t **socketp) {
        *socketp = NULL;
 }
 
-void
+isc_result_t
 isc_socket_close(isc_socket_t *sock) {
        int fd;
 
@@ -2147,6 +2147,8 @@ isc_socket_close(isc_socket_t *sock) {
        isc_sockaddr_any(&sock->address);
 
        closesocket(sock->manager, sock->type, fd);
+
+       return (ISC_R_SUCCESS);
 }
 
 /*
index be178d9876971be6b73330805bbaea52bb3fc728..bb58ad16f75c8857dd2f5d5f70cebbab12da41c3 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.30.18.23 2008/07/01 02:10:06 each Exp $ */
+/* $Id: socket.c,v 1.30.18.24 2008/07/03 00:14:40 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
@@ -1171,7 +1171,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 {
@@ -1867,8 +1867,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;
@@ -1880,9 +1888,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) {
@@ -1893,12 +1909,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:
@@ -1926,17 +1943,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));
@@ -1951,7 +1970,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));
@@ -1967,7 +1986,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));
@@ -1990,36 +2009,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;
 
@@ -2041,25 +2030,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);
 }
 
 /*
@@ -2103,36 +2076,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);
 }
 
 /*