Author: vlendec
Date: 2004-12-15 12:05:48 +0000 (Wed, 15 Dec 2004)
New Revision: 4217

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4217

Log:
Fix open_any_socket_out.

This was a missing merge from HEAD or rather a commit to 3_0 from the wrong
source. Fixed slightly over HEAD, HEAD merge will follow.

Deal with connection refused according to the specs.

Volker

Modified:
   branches/SAMBA_3_0/source/lib/util_sock.c


Changeset:
Modified: branches/SAMBA_3_0/source/lib/util_sock.c
===================================================================
--- branches/SAMBA_3_0/source/lib/util_sock.c   2004-12-15 10:12:10 UTC (rev 
4216)
+++ branches/SAMBA_3_0/source/lib/util_sock.c   2004-12-15 12:05:48 UTC (rev 
4217)
@@ -810,7 +810,7 @@
        int *sockets;
        BOOL good_connect;
 
-       fd_set wr_fds;
+       fd_set r_fds, wr_fds;
        struct timeval tv;
        int maxfd;
 
@@ -840,6 +840,9 @@
 
        for (i=0; i<num_addrs; i++) {
 
+               if (sockets[i] == -1)
+                       continue;
+
                if (connect(sockets[i], (struct sockaddr *)&(addrs[i]),
                            sizeof(*addrs)) == 0) {
                        /* Rather unlikely as we are non-blocking, but it
@@ -853,6 +856,10 @@
                        /* These are the error messages that something is
                           progressing. */
                        good_connect = True;
+               } else if (errno != 0) {
+                       /* There was a direct error */
+                       close(sockets[i]);
+                       sockets[i] = -1;
                }
        }
 
@@ -865,9 +872,13 @@
 
        maxfd = 0;
        FD_ZERO(&wr_fds);
+       FD_ZERO(&r_fds);
 
        for (i=0; i<num_addrs; i++) {
+               if (sockets[i] == -1)
+                       continue;
                FD_SET(sockets[i], &wr_fds);
+               FD_SET(sockets[i], &r_fds);
                if (sockets[i]>maxfd)
                        maxfd = sockets[i];
        }
@@ -875,7 +886,7 @@
        tv.tv_sec = 0;
        tv.tv_usec = connect_loop;
 
-       res = sys_select(maxfd+1, NULL, &wr_fds, NULL, &tv);
+       res = sys_select(maxfd+1, &r_fds, &wr_fds, NULL, &tv);
 
        if (res < 0)
                goto done;
@@ -885,21 +896,24 @@
 
        for (i=0; i<num_addrs; i++) {
 
-               int sockerr, sockerr_len;
-               
-               if (!FD_ISSET(sockets[i], &wr_fds))
+               if (sockets[i] == -1)
                        continue;
 
-               sockerr_len = sizeof(sockerr);
+               /* Stevens, Network Programming says that if there's a
+                * successful connect, the socket is only writable. Upon an
+                * error, it's both readable and writable. */
 
-               res = getsockopt(sockets[i], SOL_SOCKET, SO_ERROR, &sockerr,
-                                &sockerr_len);
+               if (FD_ISSET(sockets[i], &r_fds) &&
+                   FD_ISSET(sockets[i], &wr_fds)) {
+                       /* readable and writable, so it's an error */
+                       close(sockets[i]);
+                       sockets[i] = -1;
+                       continue;
+               }
 
-               if (res < 0)
-                       goto done;
-
-               if (sockerr == 0) {
-                       /* Hey, we got a connection */
+               if (!FD_ISSET(sockets[i], &r_fds) &&
+                   FD_ISSET(sockets[i], &wr_fds)) {
+                       /* Only writable, so it's connected */
                        resulting_index = i;
                        goto done;
                }

Reply via email to