/* Establishing and handling network connections.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+ Foundation, Inc.
This file is part of GNU Wget.
#include <stdio.h>
#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
+#include <unistd.h>
#include <assert.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
+#include <sys/time.h>
#include "utils.h"
#include "host.h"
#include "connect.h"
xfree (str);
}
else
- logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
+ {
+ if (ip->family == AF_INET)
+ logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
+#ifdef ENABLE_IPV6
+ else if (ip->family == AF_INET6)
+ logprintf (LOG_VERBOSE, _("Connecting to [%s]:%d... "), txt_addr, port);
+#endif
+ }
}
/* Store the sockaddr info to SA. */
socket_ip_address (int sock, ip_address *ip, int endpoint)
{
struct sockaddr_storage storage;
- struct sockaddr *sockaddr = (struct sockaddr *)&storage;
+ struct sockaddr *sockaddr = (struct sockaddr *) &storage;
socklen_t addrlen = sizeof (storage);
int ret;
+ memset (sockaddr, 0, addrlen);
if (endpoint == ENDPOINT_LOCAL)
ret = getsockname (sock, sockaddr, &addrlen);
else if (endpoint == ENDPOINT_PEER)
}
}
+/* Get the socket family of connection on FD and store
+ Return family type on success, -1 otherwise.
+
+ If ENDPOINT is ENDPOINT_LOCAL, it returns the sock family of the local
+ (client) side of the socket. Else if ENDPOINT is ENDPOINT_PEER, it
+ returns the sock family of the remote (peer's) side of the socket. */
+
+int
+socket_family (int sock, int endpoint)
+{
+ struct sockaddr_storage storage;
+ struct sockaddr *sockaddr = (struct sockaddr *) &storage;
+ socklen_t addrlen = sizeof (storage);
+ int ret;
+
+ memset (sockaddr, 0, addrlen);
+
+ if (endpoint == ENDPOINT_LOCAL)
+ ret = getsockname (sock, sockaddr, &addrlen);
+ else if (endpoint == ENDPOINT_PEER)
+ ret = getpeername (sock, sockaddr, &addrlen);
+ else
+ abort ();
+
+ if (ret < 0)
+ return -1;
+
+ return sockaddr->sa_family;
+}
+
/* Return true if the error from the connect code can be considered
retryable. Wget normally retries after errors, but the exception
are the "unsupported protocol" type errors (possible on IPv4/IPv6
tmout.tv_usec = 1000000 * (maxtime - (long) maxtime);
do
+ {
result = select (fd + 1, rd, wr, NULL, &tmout);
+#ifdef WINDOWS
+ /* gnulib select() converts blocking sockets to nonblocking in windows.
+ wget uses blocking sockets so we must convert them back to blocking. */
+ set_windows_fd_as_blocking_socket (fd);
+#endif
+ }
while (result < 0 && errno == EINTR);
return result;
{
fd_set check_set;
struct timeval to;
+ int ret = 0;
/* Check if we still have a valid (non-EOF) connection. From Andrew
* Maholski's code in the Unix Socket FAQ. */
to.tv_sec = 0;
to.tv_usec = 1;
- if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
+ ret = select (sock + 1, &check_set, NULL, NULL, &to);
+#ifdef WINDOWS
+/* gnulib select() converts blocking sockets to nonblocking in windows.
+wget uses blocking sockets so we must convert them back to blocking
+*/
+ set_windows_fd_as_blocking_socket ( sock );
+#endif
+
+ if ( !ret )
/* We got a timeout, it means we're still connected. */
return true;
else