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