diff options
author | Greg Fitzgerald <gregf@gentoo.org> | 2003-11-18 06:15:02 +0000 |
---|---|---|
committer | Greg Fitzgerald <gregf@gentoo.org> | 2003-11-18 06:15:02 +0000 |
commit | a76e4c75f67c5090037829fa1e5fb372617989dd (patch) | |
tree | 83b0c1083012c634bb533cee451f4db51c9fe4c5 /net-misc/wget | |
parent | Dep fix (diff) | |
download | historical-a76e4c75f67c5090037829fa1e5fb372617989dd.tar.gz historical-a76e4c75f67c5090037829fa1e5fb372617989dd.tar.bz2 historical-a76e4c75f67c5090037829fa1e5fb372617989dd.zip |
patch to fix ip6
Diffstat (limited to 'net-misc/wget')
-rw-r--r-- | net-misc/wget/files/wget-1.9.1+ipvmisc.patch | 795 |
1 files changed, 795 insertions, 0 deletions
diff --git a/net-misc/wget/files/wget-1.9.1+ipvmisc.patch b/net-misc/wget/files/wget-1.9.1+ipvmisc.patch new file mode 100644 index 000000000000..27768bfaa29e --- /dev/null +++ b/net-misc/wget/files/wget-1.9.1+ipvmisc.patch @@ -0,0 +1,795 @@ +Dual-family (IPv4+IPv6) support for wget 1.9 + +Without this patch, IPv6 support completely disables IPv4, since dual-family +support was incomplete. Read MODIFICATIONS.ari for details. + +This patch also adds the configuration option --with-ipv4-default, which +will sort resolved addresses so that those with the AF_INET family will be +attempted first. Remember to run autoconf in the top-level wget source +directory after patching. + +NOTE: I do not currently have an IPv6-enabled system on hand in order to +properly test IPv6 functionality. If wget 1.9 had any problems +communicating over IPv6, it is not likely that this patch will have +corrected them. Until this functionality is committed into wget, please +send any relevant IPv6 problems to me. + + +ari edelkind (10/27/2003) +last modified 10/27/2003 + + +diff -ruN --exclude configure wget-1.9.orig/MODIFICATIONS.ari wget-1.9/MODIFICATIONS.ari +--- wget-1.9.orig/MODIFICATIONS.ari Wed Dec 31 19:00:00 1969 ++++ wget-1.9/MODIFICATIONS.ari Mon Oct 27 04:05:34 2003 +@@ -0,0 +1,40 @@ ++ ++- added an ip_addrset structure to host.h, containing an ip_address type and ++ a family. ++ ++- Changed the address_list structure to use an array of ip_addrset types ++ instead of ip_address types. ++ ++- Changed usage of ip_address type to ip_addrset type in any location where ++ it would be useful to have the family for a particular ip address or ++ connection. Modified all dereferences accordingly, and removed ++ ip_default_family altogether. ++ ++- added a family option to the sockaddr_len() function in host.c, and the ++ bindport() function in connect.c. ++ ++- Added --with-ipv4-default option to configure.in. If this option is set, ++ AF_INET will be used as the default domain, even when ipv6 is enabled. ++ This configure option defines the macro USE_IPV4_DEFAULT. ++ ++- Changed the --disable-ipv6 comment in configure.in to --enable-ipv6. ++ Since ipv6 is currently enabled neither by default nor by configure ++ checks, and --enable-ipv6 must be passed in order to do so, this will make ++ the option more intuitive. When configure is modified to check for ipv6 ++ support by default, this comment should be reverted. Be sure to run ++ autoconf to recreate the configure file. ++ ++- host.c: getaddrinfo functions were conditionally included depending on ++ whether ENABLE_IPV6 was defined, yet in lookup_host(), they are called ++ depending on whether HAVE_GETADDRINFO is defined. Switched the relevant ++ ENABLE_IPV6 conditional define to use HAVE_GETADDRINFO. ++ ++- Added the function address_list_sort_family() to host.c if ++ USE_IPV4_DEFAULT is defined. When the address list is gathered from name ++ resolution, any addresses associated with an AF_INET family will be first ++ in the al->addrsets array. They will therefore be tried before AF_INET6 ++ types. ++ ++- ftp.c, getftp(): Used conaddr() to initially populate passive_addrset with ++ RBUF_FD(&con->rbuf), so that the family of the requested connection may be ++ known to other functions. +diff -ruN --exclude configure wget-1.9.orig/configure.in wget-1.9/configure.in +--- wget-1.9.orig/configure.in Thu Oct 16 10:27:39 2003 ++++ wget-1.9/configure.in Mon Oct 27 00:24:54 2003 +@@ -59,6 +59,10 @@ + [[ --with-ssl[=SSL-ROOT] link with SSL support [default=auto] + --without-ssl disable SSL autodetection]]) + ++AC_ARG_WITH(ipv4-default, ++[ --with-ipv4-default use IPv4 by default when IPv6 is enabled], ++[AC_DEFINE(USE_IPV4_DEFAULT)]) ++ + AC_ARG_ENABLE(opie, + [ --disable-opie disable support for opie or s/key FTP login], + USE_OPIE=$enableval, USE_OPIE=yes) +@@ -455,7 +459,7 @@ + ipv6= + check_for_ipv6=no + AC_ARG_ENABLE(ipv6, +- AC_HELP_STRING([--disable-ipv6],[disable IPv6 support]), ++ AC_HELP_STRING([--enable-ipv6],[enable IPv6 support]), + [case "${enable_ipv6}" in + no) + AC_MSG_NOTICE([Disabling IPv6 at user request]) +diff -ruN --exclude configure wget-1.9.orig/src/config.h.in wget-1.9/src/config.h.in +--- wget-1.9.orig/src/config.h.in Mon Oct 13 10:20:45 2003 ++++ wget-1.9/src/config.h.in Mon Oct 27 00:24:54 2003 +@@ -272,6 +272,9 @@ + /* Define if you want to enable the IPv6 support. */ + #undef ENABLE_IPV6 + ++/* Define if you want to use IPv4 by default when IPv6 is supported. */ ++#undef USE_IPV4_DEFAULT ++ + /* Defined to int or size_t on systems without socklen_t. */ + #undef socklen_t + +diff -ruN --exclude configure wget-1.9.orig/src/connect.c wget-1.9/src/connect.c +--- wget-1.9.orig/src/connect.c Fri Oct 10 21:39:07 2003 ++++ wget-1.9/src/connect.c Mon Oct 27 00:24:54 2003 +@@ -69,7 +69,7 @@ + static int msock = -1; + static struct sockaddr *addr; + +-static ip_address bind_address; ++static ip_addrset bind_address; + static int bind_address_resolved; + + static void +@@ -149,17 +149,17 @@ + + /* Connect to a remote host whose address has been resolved. */ + int +-connect_to_one (ip_address *addr, unsigned short port, int silent) ++connect_to_one (ip_addrset *addrset, unsigned short port, int silent) + { + wget_sockaddr sa; + int sock, save_errno; + + /* Set port and protocol */ +- wget_sockaddr_set_address (&sa, ip_default_family, port, addr); ++ wget_sockaddr_set_address (&sa, addrset->family, port, &addrset->addr); + + if (!silent) + { +- char *pretty_addr = pretty_print_address (addr); ++ char *pretty_addr = pretty_print_address (&addrset->addr); + if (connection_host_name + && 0 != strcmp (connection_host_name, pretty_addr)) + logprintf (LOG_VERBOSE, _("Connecting to %s[%s]:%hu... "), +@@ -170,7 +170,7 @@ + } + + /* Make an internet socket, stream type. */ +- sock = socket (ip_default_family, SOCK_STREAM, 0); ++ sock = socket (addrset->family, SOCK_STREAM, 0); + if (sock < 0) + goto out; + +@@ -196,8 +196,9 @@ + { + /* Bind the client side to the requested address. */ + wget_sockaddr bsa; +- wget_sockaddr_set_address (&bsa, ip_default_family, 0, &bind_address); +- if (bind (sock, &bsa.sa, sockaddr_len ())) ++ wget_sockaddr_set_address (&bsa, bind_address.family, 0, ++ &bind_address.addr); ++ if (bind (sock, &bsa.sa, sockaddr_len (addrset->family))) + { + CLOSE (sock); + sock = -1; +@@ -206,7 +207,7 @@ + } + + /* Connect the socket to the remote host. */ +- if (connect_with_timeout (sock, &sa.sa, sockaddr_len (), ++ if (connect_with_timeout (sock, &sa.sa, sockaddr_len (addrset->family), + opt.connect_timeout) < 0) + { + CLOSE (sock); +@@ -233,20 +234,20 @@ + return sock; + } + ++ + /* Connect to a remote host whose address has been resolved. */ + int + connect_to_many (struct address_list *al, unsigned short port, int silent) + { +- int i, start, end; ++ int i, start, end, sock; ++ ip_addrset addrset; + + address_list_get_bounds (al, &start, &end); + for (i = start; i < end; i++) + { +- ip_address addr; +- int sock; +- address_list_copy_one (al, i, &addr); ++ address_list_copy_one (al, i, &addrset); + +- sock = connect_to_one (&addr, port, silent); ++ sock = connect_to_one (&addrset, port, silent); + if (sock >= 0) + /* Success. */ + return sock; +@@ -298,7 +299,7 @@ + internal variable MPORT is set to the value of the ensuing master + socket. Call acceptport() to block for and accept a connection. */ + uerr_t +-bindport (unsigned short *port, int family) ++bindport (unsigned short *port, int ip_family) + { + int optval = 1; + wget_sockaddr srv; +@@ -306,7 +307,7 @@ + + msock = -1; + +- if ((msock = socket (family, SOCK_STREAM, 0)) < 0) ++ if ((msock = socket (ip_family, SOCK_STREAM, 0)) < 0) + return CONSOCKERR; + + #ifdef SO_REUSEADDR +@@ -316,9 +317,9 @@ + #endif + + resolve_bind_address (); +- wget_sockaddr_set_address (&srv, ip_default_family, htons (*port), +- bind_address_resolved ? &bind_address : NULL); +- if (bind (msock, &srv.sa, sockaddr_len ()) < 0) ++ wget_sockaddr_set_address (&srv, ip_family, htons (*port), ++ bind_address_resolved ? &bind_address.addr : NULL); ++ if (bind (msock, &srv.sa, sockaddr_len (ip_family)) < 0) + { + CLOSE (msock); + msock = -1; +@@ -327,7 +328,7 @@ + DEBUGP (("Master socket fd %d bound.\n", msock)); + if (!*port) + { +- socklen_t sa_len = sockaddr_len (); ++ socklen_t sa_len = sockaddr_len (ip_family); + if (getsockname (msock, &srv.sa, &sa_len) < 0) + { + CLOSE (msock); +@@ -389,7 +390,13 @@ + uerr_t + acceptport (int *sock) + { +- socklen_t addrlen = sockaddr_len (); ++ socklen_t addrlen; ++ ip_addrset addrset; ++ ++ if (!conaddr (msock, &addrset)) ++ return ACCEPTERR; ++ ++ addrlen = sockaddr_len (addrset.family); + + #ifdef HAVE_SELECT + if (select_fd (msock, opt.connect_timeout, 0) <= 0) +@@ -417,22 +424,22 @@ + /* Return the local IP address associated with the connection on FD. */ + + int +-conaddr (int fd, ip_address *ip) ++conaddr (int fd, ip_addrset *ip) + { + wget_sockaddr mysrv; + socklen_t addrlen = sizeof (mysrv); + if (getsockname (fd, &mysrv.sa, &addrlen) < 0) + return 0; + +- switch (mysrv.sa.sa_family) ++ switch (ip->family = mysrv.sa.sa_family) + { + #ifdef ENABLE_IPV6 + case AF_INET6: +- memcpy (ip, &mysrv.sin6.sin6_addr, 16); ++ memcpy (&ip->addr, &mysrv.sin6.sin6_addr, 16); + return 1; + #endif + case AF_INET: +- map_ipv4_to_ip ((ip4_address *)&mysrv.sin.sin_addr, ip); ++ map_ipv4_to_ip ((ip4_address *)&mysrv.sin.sin_addr, &ip->addr); + return 1; + default: + abort (); +diff -ruN --exclude configure wget-1.9.orig/src/connect.h wget-1.9/src/connect.h +--- wget-1.9.orig/src/connect.h Sat Sep 20 19:12:18 2003 ++++ wget-1.9/src/connect.h Mon Oct 27 00:24:54 2003 +@@ -34,7 +34,7 @@ + + /* Function declarations */ + +-int connect_to_one PARAMS ((ip_address *, unsigned short, int)); ++int connect_to_one PARAMS ((ip_addrset *, unsigned short, int)); + int connect_to_many PARAMS ((struct address_list *, unsigned short, int)); + void set_connection_host_name PARAMS ((const char *)); + +@@ -43,7 +43,7 @@ + uerr_t bindport PARAMS ((unsigned short *, int)); + uerr_t acceptport PARAMS ((int *)); + void closeport PARAMS ((int)); +-int conaddr PARAMS ((int, ip_address *)); ++int conaddr PARAMS ((int, ip_addrset *)); + + int iread PARAMS ((int, char *, int)); + int iwrite PARAMS ((int, char *, int)); +diff -ruN --exclude configure wget-1.9.orig/src/ftp-basic.c wget-1.9/src/ftp-basic.c +--- wget-1.9.orig/src/ftp-basic.c Fri Oct 10 21:39:07 2003 ++++ wget-1.9/src/ftp-basic.c Mon Oct 27 00:24:54 2003 +@@ -259,23 +259,24 @@ + uerr_t err; + + char *request, *respline; +- ip_address in_addr; ++ ip_addrset in_addrset; + unsigned short port; + + char ipv6 [8 * (4 * 3 + 3) + 8]; + char *bytes; + ++ /* Get the address of this side of the connection. */ ++ if (!conaddr (RBUF_FD (rbuf), &in_addrset)) ++ /* Huh? This is not BINDERR! */ ++ return BINDERR; ++ + /* Setting port to 0 lets the system choose a free port. */ + port = 0; +- err = bindport (&port, ip_default_family); ++ err = bindport (&port, in_addrset.family); + if (err != BINDOK) /* Bind the port. */ + return err; + +- /* Get the address of this side of the connection. */ +- if (!conaddr (RBUF_FD (rbuf), &in_addr)) +- /* Huh? This is not BINDERR! */ +- return BINDERR; +- inet_ntop (AF_INET6, &in_addr, ipv6, sizeof (ipv6)); ++ inet_ntop (AF_INET6, &in_addrset.addr, ipv6, sizeof (ipv6)); + + /* Construct the argument of EPRT (of the form |2|IPv6.ascii|PORT.ascii|). */ + bytes = alloca (3 + strlen (ipv6) + 1 + numdigit (port) + 1 + 1); +@@ -318,17 +319,27 @@ + char *request, *respline; + char bytes[6 * 4 +1]; + +- ip_address in_addr; ++ ip_addrset in_addrset; + ip4_address in_addr_4; + unsigned char *in_addr4_ptr = (unsigned char *)&in_addr_4; + + int nwritten; + unsigned short port; ++ ++ ++ /* Get the address of this side of the connection and convert it ++ (back) to IPv4. */ ++ if (!conaddr (RBUF_FD (rbuf), &in_addrset)) ++ /* Huh? This is not BINDERR! */ ++ return BINDERR; ++ if (!map_ip_to_ipv4 (&in_addrset.addr, &in_addr_4)) ++ return BINDERR; ++ + #ifdef ENABLE_IPV6 + /* + Only try the Extented Version if we actually use IPv6 + */ +- if (ip_default_family == AF_INET6) ++ if (in_addrset.family == AF_INET6) + { + err = ftp_eprt (rbuf); + if (err == FTPOK) +@@ -338,18 +349,10 @@ + /* Setting port to 0 lets the system choose a free port. */ + port = 0; + +- err = bindport (&port, AF_INET); ++ err = bindport (&port, in_addrset.family); + if (err != BINDOK) + return err; + +- /* Get the address of this side of the connection and convert it +- (back) to IPv4. */ +- if (!conaddr (RBUF_FD (rbuf), &in_addr)) +- /* Huh? This is not BINDERR! */ +- return BINDERR; +- if (!map_ip_to_ipv4 (&in_addr, &in_addr_4)) +- return BINDERR; +- + /* Construct the argument of PORT (of the form a,b,c,d,e,f). Port + is unsigned short so (unsigned) (port & 0xff000) >> 8 is the same + like port >> 8 +@@ -384,7 +387,7 @@ + + #ifdef ENABLE_IPV6 + uerr_t +-ftp_epsv (struct rbuf *rbuf, ip_address *addr, unsigned short *port, ++ftp_epsv (struct rbuf *rbuf, ip_addrset *addrset, unsigned short *port, + char *typ) + { + int err; +@@ -423,13 +426,13 @@ + socklen_t addrlen = sizeof (remote); + struct sockaddr_in *ipv4_sock = (struct sockaddr_in *)&remote; + getpeername (RBUF_FD (rbuf), (struct sockaddr *)&remote, &addrlen); +- switch(remote.sa.sa_family) ++ switch(addrset->family = remote.sa.sa_family) + { + case AF_INET6: +- memcpy (addr, &remote.sin6.sin6_addr, 16); ++ memcpy (&addrset->addr, &remote.sin6.sin6_addr, 16); + break; + case AF_INET: +- map_ipv4_to_ip ((ip4_address *)&ipv4_sock->sin_addr, addr); ++ map_ipv4_to_ip ((ip4_address *)&ipv4_sock->sin_addr, &addrset->addr); + break; + default: + abort(); +@@ -446,7 +449,7 @@ + transfer. Reads the response from server and parses it. Reads the + host and port addresses and returns them. */ + uerr_t +-ftp_pasv (struct rbuf *rbuf, ip_address *addr, unsigned short *port) ++ftp_pasv (struct rbuf *rbuf, ip_addrset *addrset, unsigned short *port) + { + char *request, *respline, *s; + int nwritten, i; +@@ -454,12 +457,12 @@ + unsigned char addr4[4]; + + #ifdef ENABLE_IPV6 +- if (ip_default_family == AF_INET6) ++ if (addrset->family == AF_INET6) + { +- err = ftp_epsv (rbuf, addr, port, "2"); /* try IPv6 with EPSV */ ++ err = ftp_epsv (rbuf, addrset, port, "2"); /* try IPv6 with EPSV */ + if (FTPOK == err) + return FTPOK; +- err = ftp_epsv (rbuf, addr, port, "1"); /* try IPv4 with EPSV */ ++ err = ftp_epsv (rbuf, addrset, port, "1"); /* try IPv4 with EPSV */ + if (FTPOK == err) + return FTPOK; + } +@@ -507,7 +510,7 @@ + } + + /* Eventually make an IPv4 in IPv6 adress if needed */ +- map_ipv4_to_ip ((ip4_address *)addr4, addr); ++ map_ipv4_to_ip ((ip4_address *)addr4, &addrset->addr); + + *port=0; + for (; ISDIGIT (*s); s++) +diff -ruN --exclude configure wget-1.9.orig/src/ftp.c wget-1.9/src/ftp.c +--- wget-1.9.orig/src/ftp.c Tue Oct 14 18:52:12 2003 ++++ wget-1.9/src/ftp.c Mon Oct 27 00:24:54 2003 +@@ -538,11 +538,15 @@ + { + if (opt.ftp_pasv > 0) + { +- ip_address passive_addr; ++ ip_addrset passive_addrset; + unsigned short passive_port; + if (!opt.server_response) + logputs (LOG_VERBOSE, "==> PASV ... "); +- err = ftp_pasv (&con->rbuf, &passive_addr, &passive_port); ++ ++ if (!conaddr (RBUF_FD (&con->rbuf), &passive_addrset)) ++ return HOSTERR; ++ ++ err = ftp_pasv (&con->rbuf, &passive_addrset, &passive_port); + /* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */ + switch (err) + { +@@ -579,14 +583,14 @@ + } /* switch(err) */ + if (err==FTPOK) + { +- dtsock = connect_to_one (&passive_addr, passive_port, 1); ++ dtsock = connect_to_one (&passive_addrset, passive_port, 1); + if (dtsock < 0) + { + int save_errno = errno; + CLOSE (csock); + rbuf_uninitialize (&con->rbuf); + logprintf (LOG_VERBOSE, _("couldn't connect to %s:%hu: %s\n"), +- pretty_print_address (&passive_addr), passive_port, ++ pretty_print_address (&passive_addrset.addr), passive_port, + strerror (save_errno)); + return CONNECT_ERROR (save_errno); + } +diff -ruN --exclude configure wget-1.9.orig/src/ftp.h wget-1.9/src/ftp.h +--- wget-1.9.orig/src/ftp.h Thu Sep 18 09:46:17 2003 ++++ wget-1.9/src/ftp.h Mon Oct 27 00:24:54 2003 +@@ -49,9 +49,9 @@ + uerr_t ftp_response PARAMS ((struct rbuf *, char **)); + uerr_t ftp_login PARAMS ((struct rbuf *, const char *, const char *)); + uerr_t ftp_port PARAMS ((struct rbuf *)); +-uerr_t ftp_pasv PARAMS ((struct rbuf *, ip_address *, unsigned short *)); ++uerr_t ftp_pasv PARAMS ((struct rbuf *, ip_addrset *, unsigned short *)); + #ifdef ENABLE_IPV6 +-uerr_t ftp_epsv PARAMS ((struct rbuf *, ip_address *, unsigned short *, ++uerr_t ftp_epsv PARAMS ((struct rbuf *, ip_addrset *, unsigned short *, + char *)); + #endif + uerr_t ftp_type PARAMS ((struct rbuf *, int)); +diff -ruN --exclude configure wget-1.9.orig/src/host.c wget-1.9/src/host.c +--- wget-1.9.orig/src/host.c Fri Oct 10 22:27:41 2003 ++++ wget-1.9/src/host.c Mon Oct 27 00:24:54 2003 +@@ -81,11 +81,6 @@ + # endif + #endif + +-#ifdef ENABLE_IPV6 +-int ip_default_family = AF_INET6; +-#else +-int ip_default_family = AF_INET; +-#endif + + /* Mapping between known hosts and to lists of their addresses. */ + +@@ -96,7 +91,7 @@ + + struct address_list { + int count; /* number of adrresses */ +- ip_address *addresses; /* pointer to the string of addresses */ ++ ip_addrset *addrsets; /* pointer to the string of address sets */ + + int faulty; /* number of addresses known not to work. */ + int refcount; /* so we know whether to free it or not. */ +@@ -114,10 +109,10 @@ + /* Copy address number INDEX to IP_STORE. */ + + void +-address_list_copy_one (struct address_list *al, int index, ip_address *ip_store) ++address_list_copy_one (struct address_list *al, int index, ip_addrset *ip_store) + { + assert (index >= al->faulty && index < al->count); +- memcpy (ip_store, al->addresses + index, sizeof (ip_address)); ++ memcpy (ip_store, al->addrsets + index, sizeof (ip_addrset)); + } + + /* Check whether two address lists have all their IPs in common. */ +@@ -129,8 +124,8 @@ + return 1; + if (al1->count != al2->count) + return 0; +- return 0 == memcmp (al1->addresses, al2->addresses, +- al1->count * sizeof (ip_address)); ++ return 0 == memcmp (al1->addrsets, al2->addrsets, ++ al1->count * sizeof (ip_addrset)); + } + + /* Mark the INDEXth element of AL as faulty, so that the next time +@@ -153,6 +148,36 @@ + al->faulty = 0; + } + ++#ifdef USE_IPV4_DEFAULT ++static inline void ++address_list_sort_family (struct address_list *al, int family) ++{ ++ int i, j = 0, len; ++ ip_addrset *copysets; ++ ++ len = sizeof(ip_addrset) * al->count; ++ ++ if (!(copysets = malloc (len))) return; ++ ++ for (i = 0; i < al->count; i++) ++ { ++ if (al->addrsets[i].family == family) ++ address_list_copy_one (al, i, ©sets[j++]); ++ } ++ ++ if (j < al->count) { ++ for (i = 0; i < al->count; i++) ++ { ++ if (al->addrsets[i].family != family) ++ address_list_copy_one (al, i, ©sets[j++]); ++ } ++ } ++ ++ memcpy (al->addrsets, copysets, len); ++ free (copysets); ++} ++#endif ++ + #ifdef HAVE_GETADDRINFO + /** + * address_list_from_addrinfo +@@ -180,7 +205,7 @@ + return NULL; + + al = xmalloc (sizeof (struct address_list)); +- al->addresses = xmalloc (cnt * sizeof (ip_address)); ++ al->addrsets = xmalloc (cnt * sizeof (ip_addrset)); + al->count = cnt; + al->faulty = 0; + al->refcount = 1; +@@ -189,13 +214,15 @@ + if (ai->ai_family == AF_INET6) + { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr; +- memcpy (al->addresses + i, &sin6->sin6_addr, 16); ++ memcpy (&al->addrsets[i].addr, &sin6->sin6_addr, 16); ++ al->addrsets[i].family = AF_INET6; + ++i; + } + else if (ai->ai_family == AF_INET) + { + struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr; +- map_ipv4_to_ip ((ip4_address *)&sin->sin_addr, al->addresses + i); ++ map_ipv4_to_ip ((ip4_address *)&sin->sin_addr, &al->addrsets[i].addr); ++ al->addrsets[i].family = AF_INET; + ++i; + } + assert (i == cnt); +@@ -216,11 +243,13 @@ + assert (count > 0); + al->count = count; + al->faulty = 0; +- al->addresses = xmalloc (count * sizeof (ip_address)); ++ al->addrsets = xmalloc (count * sizeof (ip_addrset)); + al->refcount = 1; + +- for (i = 0; i < count; i++) +- map_ipv4_to_ip ((ip4_address *)h_addr_list[i], al->addresses + i); ++ for (i = 0; i < count; i++) { ++ al->addrsets[i].family = AF_INET; ++ map_ipv4_to_ip ((ip4_address *)h_addr_list[i], &al->addrsets[i].addr); ++ } + + return al; + } +@@ -230,14 +259,15 @@ + address. */ + + static struct address_list * +-address_list_from_single (ip_address *addr) ++address_list_from_single (ip_address *addr, int ip_family) + { + struct address_list *al = xmalloc (sizeof (struct address_list)); + al->count = 1; + al->faulty = 0; +- al->addresses = xmalloc (sizeof (ip_address)); ++ al->addrsets = xmalloc (sizeof (ip_addrset)); + al->refcount = 1; +- memcpy (al->addresses, addr, sizeof (ip_address)); ++ memcpy (&al->addrsets->addr, addr, sizeof (ip_address)); ++ al->addrsets->family = ip_family; + + return al; + } +@@ -245,7 +275,7 @@ + static void + address_list_delete (struct address_list *al) + { +- xfree (al->addresses); ++ xfree (al->addrsets); + xfree (al); + } + +@@ -422,12 +452,12 @@ + * socklen_t structure length for socket options + */ + socklen_t +-sockaddr_len () ++sockaddr_len (int ip_family) + { +- if (ip_default_family == AF_INET) ++ if (ip_family == AF_INET) + return sizeof (struct sockaddr_in); + #ifdef ENABLE_IPV6 +- if (ip_default_family == AF_INET6) ++ if (ip_family == AF_INET6) + return sizeof (struct sockaddr_in6); + #endif + abort(); +@@ -474,7 +504,7 @@ + + /* Versions of gethostbyname and getaddrinfo that support timeout. */ + +-#ifndef ENABLE_IPV6 ++#ifndef HAVE_GETADDRINFO + + struct ghbnwt_context { + const char *host_name; +@@ -509,7 +539,7 @@ + return ctx.hptr; + } + +-#else /* ENABLE_IPV6 */ ++#else /* HAVE_GETADDRINFO */ + + struct gaiwt_context { + const char *node; +@@ -548,8 +578,7 @@ + } + return ctx.exit_code; + } +- +-#endif /* ENABLE_IPV6 */ ++#endif /* HAVE_GETADDRINFO */ + + /* Pretty-print ADDR. When compiled without IPv6, this is the same as + inet_ntoa. With IPv6, it either prints an IPv6 address or an IPv4 +@@ -591,7 +620,8 @@ + int i; + debug_logprintf ("Caching %s =>", host); + for (i = 0; i < al->count; i++) +- debug_logprintf (" %s", pretty_print_address (al->addresses + i)); ++ debug_logprintf (" %s", ++ pretty_print_address (&al->addrsets[i].addr)); + debug_logprintf ("\n"); + } + #endif +@@ -609,7 +639,7 @@ + + #ifdef ENABLE_IPV6 + if (inet_pton (AF_INET6, host, &addr) > 0) +- return address_list_from_single (&addr); ++ return address_list_from_single (&addr, AF_INET6); + #endif + + addr_ipv4 = (u_int32_t)inet_addr (host); +@@ -618,7 +648,7 @@ + /* ADDR is defined to be in network byte order, which is what + this returns, so we can just copy it to STORE_IP. */ + map_ipv4_to_ip ((ip4_address *)&addr_ipv4, &addr); +- return address_list_from_single (&addr); ++ return address_list_from_single (&addr, AF_INET6); + } + + if (host_name_addresses_map) +@@ -643,11 +673,14 @@ + int err; + + memset (&hints, 0, sizeof (hints)); +- if (ip_default_family == AF_INET) +- hints.ai_family = AF_INET; +- else +- hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; ++ ++# if !defined (ENABLE_IPV6) ++ hints.ai_family = AF_INET; ++# else ++ hints.ai_family = AF_UNSPEC; ++# endif ++ + err = getaddrinfo_with_timeout (host, NULL, &hints, &ai, opt.dns_timeout); + + if (err != 0 || ai == NULL) +@@ -681,6 +714,10 @@ + } + #endif + ++#ifdef USE_IPV4_DEFAULT ++ address_list_sort_family (al, AF_INET); ++#endif ++ + /* Print the addresses determined by DNS lookup, but no more than + three. */ + if (!silent) +@@ -690,7 +727,7 @@ + for (i = 0; i < printmax; i++) + { + logprintf (LOG_VERBOSE, "%s", +- pretty_print_address (al->addresses + i)); ++ pretty_print_address (&al->addrsets[i].addr)); + if (i < printmax - 1) + logputs (LOG_VERBOSE, ", "); + } +diff -ruN --exclude configure wget-1.9.orig/src/host.h wget-1.9/src/host.h +--- wget-1.9.orig/src/host.h Fri Oct 10 21:39:07 2003 ++++ wget-1.9/src/host.h Mon Oct 27 03:36:52 2003 +@@ -73,13 +73,18 @@ + unsigned char bytes[MAX_IP_ADDRESS_SIZE]; + } ip_address; + ++typedef struct { ++ ip_address addr; ++ int family; ++} ip_addrset; ++ + /* Function declarations */ + struct address_list *lookup_host PARAMS ((const char *, int)); + char *herrmsg PARAMS ((int)); + + void address_list_get_bounds PARAMS ((struct address_list *, int *, int *)); + void address_list_copy_one PARAMS ((struct address_list *, int, +- ip_address *)); ++ ip_addrset *)); + int address_list_match_all PARAMS ((struct address_list *, + struct address_list *)); + void address_list_set_faulty PARAMS ((struct address_list *, int)); +@@ -97,11 +102,9 @@ + void wget_sockaddr_set_port PARAMS((wget_sockaddr *, unsigned short)); + void *wget_sockaddr_get_addr PARAMS((wget_sockaddr *)); + unsigned short wget_sockaddr_get_port PARAMS((const wget_sockaddr *)); +-socklen_t sockaddr_len PARAMS(()); ++socklen_t sockaddr_len PARAMS((int)); + void map_ipv4_to_ip PARAMS((ip4_address *, ip_address *)); + int map_ip_to_ipv4 PARAMS((ip_address *, ip4_address *)); + +-extern int ip_default_family; /* defined in host.c */ +- + + #endif /* HOST_H */ |