summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2004-12-15 12:05:48 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:53:38 -0500
commit786b6c5e284b0f9b01a7554e217e67ae777adf5a (patch)
tree52a54ccc4a2a3d6c13624ccec373891f0e471c1b /source3
parent37e5f14089bf70f78026b34d60917469e26a64ae (diff)
downloadsamba-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')
-rw-r--r--source3/lib/util_sock.c40
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;
}