]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Windows sockets won't connect unless the socket is bound. v9.4.2-P2-W2
authorMark Andrews <marka@isc.org>
Thu, 11 Sep 2008 04:20:19 +0000 (04:20 +0000)
committerMark Andrews <marka@isc.org>
Thu, 11 Sep 2008 04:20:19 +0000 (04:20 +0000)
lib/isc/win32/socket.c

index 682bd35b5a2cb3cac787b1dd43b2c4a93553c853..f09ee01c8c13039ca2dc450de14d7146a9328742 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: socket.c,v 1.30.18.20.12.5.6.3 2008/09/10 21:37:15 explorer Exp $ */
+/* $Id: socket.c,v 1.30.18.20.12.5.6.4 2008/09/11 04:20:19 marka Exp $ */
 
 /* This code uses functions which are only available on Server 2003 and
  * higher, and Windows XP and higher.
@@ -2103,7 +2103,6 @@ internal_connect(isc_socket_t *sock, IoCompletionInfo *lpo, int connect_errno) {
                INSIST(setsockopt(sock->fd, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == 0);
                cdev->result = ISC_R_SUCCESS;
                sock->connected = 1;
-               sock->bound = 1;
                socket_log(__LINE__, sock, &sock->address, IOEVENT,
                           isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN,
                           "internal_connect: success");
@@ -3230,10 +3229,12 @@ isc_result_t
 isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
                   isc_task_t *task, isc_taskaction_t action, const void *arg)
 {
+       char strbuf[ISC_STRERRORSIZE];
        isc_socket_connev_t *cdev;
        isc_task_t *ntask = NULL;
        isc_socketmgr_t *manager;
        IoCompletionInfo *lpo;
+       int bind_errno;
 
        REQUIRE(VALID_SOCKET(sock));
        REQUIRE(addr != NULL);
@@ -3258,6 +3259,36 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
                return (ISC_R_CONNREFUSED);
        }
 
+       /*
+        * Windows sockets won't connect unless the socket is bound.
+        */
+       if (!sock->bound) {
+               isc_sockaddr_t any;
+
+               isc_sockaddr_anyofpf(&any, isc_sockaddr_pf(addr));
+               if (bind(sock->fd, &any.type.sa, any.length) < 0) {
+                       bind_errno = WSAGetLastError();
+                       UNLOCK(&sock->lock);
+                       switch (bind_errno) {
+                       case WSAEACCES:
+                               return (ISC_R_NOPERM);
+                       case WSAEADDRNOTAVAIL:
+                               return (ISC_R_ADDRNOTAVAIL);
+                       case WSAEADDRINUSE:
+                               return (ISC_R_ADDRINUSE);
+                       case WSAEINVAL:
+                               return (ISC_R_BOUND);
+                       default:
+                               isc__strerror(bind_errno, strbuf,
+                                             sizeof(strbuf));
+                               UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                                "bind: %s", strbuf);
+                               return (ISC_R_UNEXPECTED);
+                       }
+               }
+               sock->bound = 1;
+       }
+
        REQUIRE(!sock->pending_connect);
 
        cdev = (isc_socket_connev_t *)isc_event_allocate(manager->mctx, sock,