1
0
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:
Daniel Stenberg 2001-02-05 23:04:44 +00:00
parent 1ae5dab8fb
commit f6e2bfd464
8 changed files with 369 additions and 16 deletions

View File

@ -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.

View File

@ -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

View File

@ -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
View File

@ -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 */

View File

@ -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. */

View File

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

View File

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

View File

@ -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 */