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; }