diff options
author | Volker Lendecke <vlendec@samba.org> | 2004-12-15 12:05:48 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:53:38 -0500 |
commit | 786b6c5e284b0f9b01a7554e217e67ae777adf5a (patch) | |
tree | 52a54ccc4a2a3d6c13624ccec373891f0e471c1b /source3/lib | |
parent | 37e5f14089bf70f78026b34d60917469e26a64ae (diff) | |
download | samba-786b6c5e284b0f9b01a7554e217e67ae777adf5a.tar.gz samba-786b6c5e284b0f9b01a7554e217e67ae777adf5a.tar.bz2 samba-786b6c5e284b0f9b01a7554e217e67ae777adf5a.zip |
r4217: 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
(This used to be commit 7230cb87eba2c296217bb0255893c55ae5d695d3)
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/util_sock.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c09e4579c4..58bc5ed6fe 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -810,7 +810,7 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, int *sockets; BOOL good_connect; - fd_set wr_fds; + fd_set r_fds, wr_fds; struct timeval tv; int maxfd; @@ -840,6 +840,9 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, 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 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, /* 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 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, 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 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, 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 @@ BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs, 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 (res < 0) - goto done; + 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 (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; } |