mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Jun-ichiro itojun Hagino's IPv6 adjustments
This commit is contained in:
parent
1ae5dab8fb
commit
f6e2bfd464
3
CHANGES
3
CHANGES
@ -8,6 +8,9 @@
|
|||||||
|
|
||||||
|
|
||||||
Daniel (5 February 2001)
|
Daniel (5 February 2001)
|
||||||
|
- Jun-ichiro itojun Hagino brought a big patch that brings IPv6-awareness to
|
||||||
|
a bunch of different areas within libcurl.
|
||||||
|
|
||||||
- Robert Weaver told me about the problems the MS VC++ 6.0 compiler has with
|
- Robert Weaver told me about the problems the MS VC++ 6.0 compiler has with
|
||||||
the 'static' keyword on a number of libcurl functions. I might need to add a
|
the 'static' keyword on a number of libcurl functions. I might need to add a
|
||||||
patch that redefines static when libcurl is compiled with that compiler.
|
patch that redefines static when libcurl is compiled with that compiler.
|
||||||
|
15
configure.in
15
configure.in
@ -53,15 +53,9 @@ dnl
|
|||||||
AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[
|
AC_DEFUN(CURL_CHECK_WORKING_GETADDRINFO,[
|
||||||
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
|
||||||
AC_TRY_RUN( [
|
AC_TRY_RUN( [
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
struct addrinfo hints, *ai;
|
struct addrinfo hints, *ai;
|
||||||
@ -434,6 +428,10 @@ AC_MSG_CHECKING([if Kerberos4 support is requested])
|
|||||||
|
|
||||||
if test "$want_krb4" = yes
|
if test "$want_krb4" = yes
|
||||||
then
|
then
|
||||||
|
if test "$ipv6" = "yes"; then
|
||||||
|
echo krb4 is not compatible with IPv6
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
|
||||||
dnl Check for & handle argument to --with-krb4
|
dnl Check for & handle argument to --with-krb4
|
||||||
@ -691,7 +689,8 @@ AC_CHECK_FUNCS( socket \
|
|||||||
setvbuf \
|
setvbuf \
|
||||||
sigaction \
|
sigaction \
|
||||||
signal \
|
signal \
|
||||||
getpass_r
|
getpass_r \
|
||||||
|
strlcat
|
||||||
)
|
)
|
||||||
|
|
||||||
dnl removed 'getpass' check on October 26, 2000
|
dnl removed 'getpass' check on October 26, 2000
|
||||||
|
@ -788,6 +788,7 @@ If you do find bugs, mail them to curl-bug@haxx.se.
|
|||||||
- Loic Dachary <loic@senga.org>
|
- Loic Dachary <loic@senga.org>
|
||||||
- Robert Weaver <robert.weaver@sabre.com>
|
- Robert Weaver <robert.weaver@sabre.com>
|
||||||
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
- Ingo Ralf Blum <ingoralfblum@ingoralfblum.com>
|
||||||
|
- Jun-ichiro itojun Hagino <itojun@iijlab.net>
|
||||||
|
|
||||||
.SH WWW
|
.SH WWW
|
||||||
http://curl.haxx.se
|
http://curl.haxx.se
|
||||||
|
259
lib/ftp.c
259
lib/ftp.c
@ -564,6 +564,9 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
#if defined (HAVE_INET_NTOA_R)
|
#if defined (HAVE_INET_NTOA_R)
|
||||||
char ntoa_buf[64];
|
char ntoa_buf[64];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *ai;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct curl_slist *qitem; /* QUOTE item */
|
struct curl_slist *qitem; /* QUOTE item */
|
||||||
/* the ftp struct is already inited in ftp_connect() */
|
/* the ftp struct is already inited in ftp_connect() */
|
||||||
@ -702,6 +705,174 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
|
|
||||||
/* We have chosen to use the PORT command */
|
/* We have chosen to use the PORT command */
|
||||||
if(data->bits.ftp_use_port) {
|
if(data->bits.ftp_use_port) {
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo hints, *res, *ai;
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
int sslen;
|
||||||
|
char hbuf[NI_MAXHOST];
|
||||||
|
char *localaddr;
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
|
||||||
|
#else
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||||
|
#endif
|
||||||
|
unsigned char *ap;
|
||||||
|
unsigned char *pp;
|
||||||
|
int alen, plen;
|
||||||
|
char portmsgbuf[4096], tmp[4096];
|
||||||
|
char *p;
|
||||||
|
char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
|
||||||
|
char **modep;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we should use Curl_if2ip? given pickiness of recent ftpd,
|
||||||
|
* I believe we should use the same address as the control connection.
|
||||||
|
*/
|
||||||
|
sslen = sizeof(ss);
|
||||||
|
if (getsockname(data->firstsocket, (struct sockaddr *)&ss, &sslen) < 0)
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
|
||||||
|
if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,
|
||||||
|
niflags))
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = ss.ss_family;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
if (getaddrinfo(hbuf, "0", &hints, &res))
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
|
||||||
|
portsock = -1;
|
||||||
|
for (ai = res; ai; ai = ai->ai_next) {
|
||||||
|
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
|
if (portsock < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
close(portsock);
|
||||||
|
portsock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(portsock, 1) < 0) {
|
||||||
|
close(portsock);
|
||||||
|
portsock = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (portsock < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
sslen = sizeof(ss);
|
||||||
|
if (getsockname(portsock, (struct sockaddr *)&ss, &sslen) < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (modep = mode; modep && *modep; modep++) {
|
||||||
|
int lprtaf, eprtaf;
|
||||||
|
|
||||||
|
switch (ss.ss_family) {
|
||||||
|
case AF_INET:
|
||||||
|
ap = (char *)&((struct sockaddr_in *)&ss)->sin_addr;
|
||||||
|
alen = sizeof(((struct sockaddr_in *)&ss)->sin_addr);
|
||||||
|
pp = (char *)&((struct sockaddr_in *)&ss)->sin_port;
|
||||||
|
plen = sizeof(((struct sockaddr_in *)&ss)->sin_port);
|
||||||
|
lprtaf = 4;
|
||||||
|
eprtaf = 1;
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
ap = (char *)&((struct sockaddr_in6 *)&ss)->sin6_addr;
|
||||||
|
alen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_addr);
|
||||||
|
pp = (char *)&((struct sockaddr_in6 *)&ss)->sin6_port;
|
||||||
|
plen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_port);
|
||||||
|
lprtaf = 6;
|
||||||
|
eprtaf = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ap = pp = NULL;
|
||||||
|
lprtaf = eprtaf = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(*modep, "EPRT") == 0) {
|
||||||
|
if (eprtaf < 0)
|
||||||
|
continue;
|
||||||
|
if (getnameinfo((struct sockaddr *)&ss, sslen,
|
||||||
|
portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags))
|
||||||
|
continue;
|
||||||
|
/* do not transmit IPv6 scope identifier to the wire */
|
||||||
|
if (ss.ss_family == AF_INET6) {
|
||||||
|
char *q = strchr(portmsgbuf, '%');
|
||||||
|
if (q)
|
||||||
|
*q = '\0';
|
||||||
|
}
|
||||||
|
ftpsendf(data->firstsocket, conn, "%s |%d|%s|%s|", *modep, eprtaf,
|
||||||
|
portmsgbuf, tmp);
|
||||||
|
} else if (strcmp(*modep, "LPRT") == 0 || strcmp(*modep, "PORT") == 0) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(*modep, "PORT") == 0 && ss.ss_family != AF_INET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
portmsgbuf[0] = '\0';
|
||||||
|
if (strcmp(*modep, "LPRT") == 0) {
|
||||||
|
snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < alen; i++) {
|
||||||
|
if (portmsgbuf[0])
|
||||||
|
snprintf(tmp, sizeof(tmp), ",%u", ap[i]);
|
||||||
|
else
|
||||||
|
snprintf(tmp, sizeof(tmp), "%u", ap[i]);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strcmp(*modep, "LPRT") == 0) {
|
||||||
|
snprintf(tmp, sizeof(tmp), ",%d", plen);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf))
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
for (i = 0; i < plen; i++) {
|
||||||
|
snprintf(tmp, sizeof(tmp), ",%u", pp[i]);
|
||||||
|
if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf)) {
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ftpsendf(data->firstsocket, conn, "%s %s", *modep, portmsgbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
|
||||||
|
if (nread < 0)
|
||||||
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
|
|
||||||
|
if (ftpcode != 200) {
|
||||||
|
failf(data, "Server does not grok %s", *modep);
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
again:;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*modep) {
|
||||||
|
close(portsock);
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return CURLE_FTP_PORT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
struct hostent *h=NULL;
|
struct hostent *h=NULL;
|
||||||
char *hostdataptr=NULL;
|
char *hostdataptr=NULL;
|
||||||
@ -809,26 +980,43 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
failf(data, "Server does not grok PORT, try without it!");
|
failf(data, "Server does not grok PORT, try without it!");
|
||||||
return CURLE_FTP_PORT_FAILED;
|
return CURLE_FTP_PORT_FAILED;
|
||||||
}
|
}
|
||||||
|
#endif /* ENABLE_IPV6 */
|
||||||
}
|
}
|
||||||
else { /* we use the PASV command */
|
else { /* we use the PASV command */
|
||||||
|
#if 0
|
||||||
|
char *mode[] = { "EPSV", "LPSV", "PASV", NULL };
|
||||||
|
int results[] = { 229, 228, 227, 0 };
|
||||||
|
#else
|
||||||
|
char *mode[] = { "PASV", NULL };
|
||||||
|
int results[] = { 227, 0 };
|
||||||
|
#endif
|
||||||
|
int modeoff;
|
||||||
|
|
||||||
ftpsendf(data->firstsocket, conn, "PASV");
|
for (modeoff = 0; mode[modeoff]; modeoff++) {
|
||||||
|
ftpsendf(data->firstsocket, conn, mode[modeoff]);
|
||||||
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
|
nread = Curl_GetFTPResponse(data->firstsocket, buf, conn, &ftpcode);
|
||||||
if(nread < 0)
|
if(nread < 0)
|
||||||
return CURLE_OPERATION_TIMEOUTED;
|
return CURLE_OPERATION_TIMEOUTED;
|
||||||
|
|
||||||
if(ftpcode != 227) {
|
if (ftpcode == results[modeoff])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mode[modeoff]) {
|
||||||
failf(data, "Odd return code after PASV");
|
failf(data, "Odd return code after PASV");
|
||||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||||
}
|
}
|
||||||
else {
|
else if (strcmp(mode[modeoff], "PASV") == 0) {
|
||||||
int ip[4];
|
int ip[4];
|
||||||
int port[2];
|
int port[2];
|
||||||
unsigned short newport; /* remote port, not necessary the local one */
|
unsigned short newport; /* remote port, not necessary the local one */
|
||||||
unsigned short connectport; /* the local port connect() should use! */
|
unsigned short connectport; /* the local port connect() should use! */
|
||||||
char newhost[32];
|
char newhost[32];
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *res;
|
||||||
|
#else
|
||||||
struct hostent *he;
|
struct hostent *he;
|
||||||
|
#endif
|
||||||
char *str=buf,*ip_addr;
|
char *str=buf,*ip_addr;
|
||||||
char *hostdataptr=NULL;
|
char *hostdataptr=NULL;
|
||||||
|
|
||||||
@ -863,20 +1051,78 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
* proxy again here. We already have the name info for it since the
|
* proxy again here. We already have the name info for it since the
|
||||||
* previous lookup.
|
* previous lookup.
|
||||||
*/
|
*/
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
res = conn->res;
|
||||||
|
#else
|
||||||
he = conn->hp;
|
he = conn->hp;
|
||||||
|
#endif
|
||||||
connectport =
|
connectport =
|
||||||
(unsigned short)data->port; /* we connect to the proxy's port */
|
(unsigned short)data->port; /* we connect to the proxy's port */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* normal, direct, ftp connection */
|
/* normal, direct, ftp connection */
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
res = Curl_getaddrinfo(data, newhost, newport);
|
||||||
|
if(!res)
|
||||||
|
#else
|
||||||
he = Curl_gethost(data, newhost, &hostdataptr);
|
he = Curl_gethost(data, newhost, &hostdataptr);
|
||||||
if(!he) {
|
if(!he)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
failf(data, "Can't resolve new host %s", newhost);
|
failf(data, "Can't resolve new host %s", newhost);
|
||||||
return CURLE_FTP_CANT_GET_HOST;
|
return CURLE_FTP_CANT_GET_HOST;
|
||||||
}
|
}
|
||||||
connectport = newport; /* we connect to the remote port */
|
connectport = newport; /* we connect to the remote port */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
data->secondarysocket = -1;
|
||||||
|
for (ai = res; ai; ai = ai->ai_next) {
|
||||||
|
/* XXX for now, we can do IPv4 only */
|
||||||
|
if (ai->ai_family != AF_INET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
data->secondarysocket = socket(ai->ai_family, ai->ai_socktype,
|
||||||
|
ai->ai_protocol);
|
||||||
|
if (data->secondarysocket < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(data->bits.verbose) {
|
||||||
|
char hbuf[NI_MAXHOST];
|
||||||
|
char nbuf[NI_MAXHOST];
|
||||||
|
char sbuf[NI_MAXSERV];
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
|
||||||
|
#else
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
|
||||||
|
#endif
|
||||||
|
if (getnameinfo(res->ai_addr, res->ai_addrlen, nbuf, sizeof(nbuf),
|
||||||
|
sbuf, sizeof(sbuf), niflags)) {
|
||||||
|
snprintf(nbuf, sizeof(nbuf), "?");
|
||||||
|
snprintf(sbuf, sizeof(sbuf), "?");
|
||||||
|
}
|
||||||
|
if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
|
||||||
|
NULL, 0, 0)) {
|
||||||
|
infof(data, "Connecting to %s port %s\n", nbuf, sbuf);
|
||||||
|
} else {
|
||||||
|
infof(data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(data->secondarysocket, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
close(data->secondarysocket);
|
||||||
|
data->secondarysocket = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->secondarysocket < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
return CURLE_FTP_CANT_RECONNECT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
|
data->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
|
||||||
@ -971,6 +1217,7 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
return CURLE_FTP_CANT_RECONNECT;
|
return CURLE_FTP_CANT_RECONNECT;
|
||||||
}
|
}
|
||||||
|
#endif /*ENABLE_IPV6*/
|
||||||
|
|
||||||
if (data->bits.tunnel_thru_httpproxy) {
|
if (data->bits.tunnel_thru_httpproxy) {
|
||||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||||
@ -979,6 +1226,8 @@ CURLcode _ftp(struct connectdata *conn)
|
|||||||
if(CURLE_OK != result)
|
if(CURLE_OK != result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return CURLE_FTP_CANT_RECONNECT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* we have the (new) data connection ready */
|
/* we have the (new) data connection ready */
|
||||||
|
23
lib/hostip.c
23
lib/hostip.c
@ -83,6 +83,29 @@ static char *MakeIP(unsigned long num,char *addr, int addr_len)
|
|||||||
return (addr);
|
return (addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
|
||||||
|
char *hostname,
|
||||||
|
int port)
|
||||||
|
{
|
||||||
|
struct addrinfo hints, *res;
|
||||||
|
int error;
|
||||||
|
char sbuf[NI_MAXSERV];
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = PF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||||
|
error = getaddrinfo(hostname, sbuf, &hints, &res);
|
||||||
|
if (error) {
|
||||||
|
infof(data, "getaddrinfo(3) failed for %s\n", hostname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The original code to this function was once stolen from the Dancer source
|
/* The original code to this function was once stolen from the Dancer source
|
||||||
code, written by Bjorn Reese, it has since been patched and modified
|
code, written by Bjorn Reese, it has since been patched and modified
|
||||||
considerably. */
|
considerably. */
|
||||||
|
@ -23,6 +23,11 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct addrinfo;
|
||||||
|
struct addrinfo *Curl_getaddrinfo(struct UrlData *data,
|
||||||
|
char *hostname,
|
||||||
|
int port);
|
||||||
|
|
||||||
struct hostent *Curl_gethost(struct UrlData *data,
|
struct hostent *Curl_gethost(struct UrlData *data,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
char **bufp);
|
char **bufp);
|
||||||
|
71
lib/url.c
71
lib/url.c
@ -562,8 +562,13 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
|
|||||||
|
|
||||||
struct UrlData *data = conn->data;
|
struct UrlData *data = conn->data;
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
if(conn->res) /* host name info */
|
||||||
|
freeaddrinfo(conn->res);
|
||||||
|
#else
|
||||||
if(conn->hostent_buf) /* host name info */
|
if(conn->hostent_buf) /* host name info */
|
||||||
free(conn->hostent_buf);
|
free(conn->hostent_buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(conn->path) /* the URL path part */
|
if(conn->path) /* the URL path part */
|
||||||
free(conn->path);
|
free(conn->path);
|
||||||
@ -589,6 +594,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
#endif
|
#endif
|
||||||
int urllen;
|
int urllen;
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *ai;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Check input data
|
* Check input data
|
||||||
@ -1189,13 +1197,23 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
data->port = data->remote_port; /* it is the same port */
|
data->port = data->remote_port; /* it is the same port */
|
||||||
|
|
||||||
/* Connect to target host right on */
|
/* Connect to target host right on */
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
conn->res = Curl_getaddrinfo(data, conn->name, data->port);
|
||||||
|
if(!conn->res)
|
||||||
|
#else
|
||||||
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
|
conn->hp = Curl_gethost(data, conn->name, &conn->hostent_buf);
|
||||||
if(!conn->hp) {
|
if(!conn->hp)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
failf(data, "Couldn't resolve host '%s'", conn->name);
|
failf(data, "Couldn't resolve host '%s'", conn->name);
|
||||||
return CURLE_COULDNT_RESOLVE_HOST;
|
return CURLE_COULDNT_RESOLVE_HOST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
failf(data, "proxy yet to be supported");
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
#else
|
||||||
char *prox_portno;
|
char *prox_portno;
|
||||||
char *endofprot;
|
char *endofprot;
|
||||||
|
|
||||||
@ -1244,9 +1262,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(proxydup); /* free the duplicate pointer and not the modified */
|
free(proxydup); /* free the duplicate pointer and not the modified */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
|
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
|
||||||
|
|
||||||
|
#ifndef ENABLE_IPV6
|
||||||
data->firstsocket = socket(AF_INET, SOCK_STREAM, 0);
|
data->firstsocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
|
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
|
||||||
@ -1254,6 +1274,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
conn->hp->h_addr, conn->hp->h_length);
|
conn->hp->h_addr, conn->hp->h_length);
|
||||||
conn->serv_addr.sin_family = conn->hp->h_addrtype;
|
conn->serv_addr.sin_family = conn->hp->h_addrtype;
|
||||||
conn->serv_addr.sin_port = htons(data->port);
|
conn->serv_addr.sin_port = htons(data->port);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(WIN32)||defined(__CYGWIN32__)
|
#if !defined(WIN32)||defined(__CYGWIN32__)
|
||||||
/* We don't generally like checking for OS-versions, we should make this
|
/* We don't generally like checking for OS-versions, we should make this
|
||||||
@ -1266,6 +1287,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
#define INADDR_NONE (unsigned long) ~0
|
#define INADDR_NONE (unsigned long) ~0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENABLE_IPV6
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Select device to bind socket to
|
* Select device to bind socket to
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
@ -1374,10 +1396,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
} /* end of device selection support */
|
} /* end of device selection support */
|
||||||
#endif /* end of HAVE_INET_NTOA */
|
#endif /* end of HAVE_INET_NTOA */
|
||||||
#endif /* end of not WIN32 */
|
#endif /* end of not WIN32 */
|
||||||
|
#endif /*ENABLE_IPV6*/
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Connect to server/proxy
|
* Connect to server/proxy
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
data->firstsocket = -1;
|
||||||
|
for (ai = conn->res; ai; ai = ai->ai_next) {
|
||||||
|
data->firstsocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||||
|
if (data->firstsocket < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (connect(data->firstsocket, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||||
|
close(data->firstsocket);
|
||||||
|
data->firstsocket = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (data->firstsocket < 0) {
|
||||||
|
failf(data, strerror(errno));
|
||||||
|
return CURLE_COULDNT_CONNECT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (connect(data->firstsocket,
|
if (connect(data->firstsocket,
|
||||||
(struct sockaddr *) &(conn->serv_addr),
|
(struct sockaddr *) &(conn->serv_addr),
|
||||||
sizeof(conn->serv_addr)
|
sizeof(conn->serv_addr)
|
||||||
@ -1426,6 +1469,7 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
}
|
}
|
||||||
return CURLE_COULDNT_CONNECT;
|
return CURLE_COULDNT_CONNECT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Proxy authentication
|
* Proxy authentication
|
||||||
@ -1473,11 +1517,31 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
conn->bytecount = 0;
|
conn->bytecount = 0;
|
||||||
|
|
||||||
/* Figure out the ip-number and display the first host name it shows: */
|
/* Figure out the ip-number and display the first host name it shows: */
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
{
|
||||||
|
char hbuf[NI_MAXHOST];
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
|
||||||
|
#else
|
||||||
|
const int niflags = NI_NUMERICHOST;
|
||||||
|
#endif
|
||||||
|
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0,
|
||||||
|
niflags)) {
|
||||||
|
snprintf(hbuf, sizeof(hbuf), "?");
|
||||||
|
}
|
||||||
|
if (ai->ai_canonname) {
|
||||||
|
infof(data, "Connected to %s (%s)\n", ai->ai_canonname, hbuf);
|
||||||
|
} else {
|
||||||
|
infof(data, "Connected to %s\n", hbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
(void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));
|
(void) memcpy(&in.s_addr, *conn->hp->h_addr_list, sizeof (in.s_addr));
|
||||||
infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in));
|
infof(data, "Connected to %s (%s)\n", conn->hp->h_name, inet_ntoa(in));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __EMX__
|
#ifdef __EMX__
|
||||||
/* 20000330 mgs
|
/* 20000330 mgs
|
||||||
@ -1509,8 +1573,13 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
if(conn) {
|
if(conn) {
|
||||||
if(conn->path)
|
if(conn->path)
|
||||||
free(conn->path);
|
free(conn->path);
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
if(conn->res)
|
||||||
|
freeaddrinfo(conn->res);
|
||||||
|
#else
|
||||||
if(conn->hostent_buf)
|
if(conn->hostent_buf)
|
||||||
free(conn->hostent_buf);
|
free(conn->hostent_buf);
|
||||||
|
#endif
|
||||||
free(conn);
|
free(conn);
|
||||||
*in_connect=NULL;
|
*in_connect=NULL;
|
||||||
}
|
}
|
||||||
|
@ -159,9 +159,13 @@ struct connectdata {
|
|||||||
#define PROT_LDAP (1<<7)
|
#define PROT_LDAP (1<<7)
|
||||||
#define PROT_FILE (1<<8)
|
#define PROT_FILE (1<<8)
|
||||||
|
|
||||||
|
#ifdef ENABLE_IPV6
|
||||||
|
struct addrinfo *res;
|
||||||
|
#else
|
||||||
char *hostent_buf; /* pointer to allocated memory for name info */
|
char *hostent_buf; /* pointer to allocated memory for name info */
|
||||||
struct hostent *hp;
|
struct hostent *hp;
|
||||||
struct sockaddr_in serv_addr;
|
struct sockaddr_in serv_addr;
|
||||||
|
#endif
|
||||||
char proto[64]; /* store the protocol string in this buffer */
|
char proto[64]; /* store the protocol string in this buffer */
|
||||||
char gname[257]; /* store the hostname in this buffer */
|
char gname[257]; /* store the hostname in this buffer */
|
||||||
char *name; /* host name pointer to fool around with */
|
char *name; /* host name pointer to fool around with */
|
||||||
|
Loading…
Reference in New Issue
Block a user