conn->ip_addr MUST NOT be used on re-used connections

This commit is contained in:
Daniel Stenberg 2005-01-29 13:07:16 +00:00
parent 0859cd2444
commit c4ff5eb0ca
6 changed files with 40 additions and 32 deletions

View File

@ -7,6 +7,9 @@
Changelog Changelog
Daniel (29 January 2005) Daniel (29 January 2005)
- Adjusted the KNOWN_BUGS #17 fix a bit more since the FTP code also did some
bad assumptions.
- multi interface: when a request is denied due to "Maximum redirects - multi interface: when a request is denied due to "Maximum redirects
followed" libcurl leaked the last Location: URL. followed" libcurl leaked the last Location: URL.

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -429,6 +429,25 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
return rc; return rc;
} }
CURLcode Curl_store_ip_addr(struct connectdata *conn)
{
char addrbuf[256];
Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
/* save the string */
Curl_safefree(conn->ip_addr_str);
conn->ip_addr_str = strdup(addrbuf);
if(!conn->ip_addr_str)
return CURLE_OUT_OF_MEMORY; /* FAIL */
#ifdef PF_INET6
if(conn->ip_addr->ai_family == PF_INET6)
conn->bits.ipv6 = TRUE;
#endif
return CURLE_OK;
}
/* Used within the multi interface. Try next IP address, return TRUE if no /* Used within the multi interface. Try next IP address, return TRUE if no
more address exists */ more address exists */
static bool trynextip(struct connectdata *conn, static bool trynextip(struct connectdata *conn,
@ -450,6 +469,8 @@ static bool trynextip(struct connectdata *conn,
/* store the new socket descriptor */ /* store the new socket descriptor */
conn->sock[sockindex] = sockfd; conn->sock[sockindex] = sockfd;
conn->ip_addr = ai; conn->ip_addr = ai;
Curl_store_ip_addr(conn);
return FALSE; return FALSE;
} }
ai = ai->ai_next; ai = ai->ai_next;

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -39,6 +39,8 @@ CURLcode Curl_connecthost(struct connectdata *conn,
int Curl_ourerrno(void); int Curl_ourerrno(void);
CURLcode Curl_store_ip_addr(struct connectdata *conn);
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */ #define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
#endif #endif

View File

@ -1226,12 +1226,10 @@ CURLcode ftp_use_port(struct connectdata *conn)
} }
#ifdef PF_INET6 #ifdef PF_INET6
if(!conn->bits.ftp_use_eprt && if(!conn->bits.ftp_use_eprt && conn->bits.ipv6)
(conn->ip_addr->ai_family == PF_INET6)) {
/* EPRT is disabled but we are connected to a IPv6 host, so we ignore the /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the
request! */ request and enable EPRT again! */
conn->bits.ftp_use_eprt = TRUE; conn->bits.ftp_use_eprt = TRUE;
}
#endif #endif
for (fcmd = EPRT; fcmd != DONE; fcmd++) { for (fcmd = EPRT; fcmd != DONE; fcmd++) {
@ -1563,12 +1561,10 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
char newhost[NEWHOST_BUFSIZE]; char newhost[NEWHOST_BUFSIZE];
#ifdef PF_INET6 #ifdef PF_INET6
if(!conn->bits.ftp_use_epsv && if(!conn->bits.ftp_use_epsv && conn->bits.ipv6)
(conn->ip_addr->ai_family == PF_INET6)) {
/* EPSV is disabled but we are connected to a IPv6 host, so we ignore the /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the
request! */ request and enable EPSV again! */
conn->bits.ftp_use_epsv = TRUE; conn->bits.ftp_use_epsv = TRUE;
}
#endif #endif
for (modeoff = (conn->bits.ftp_use_epsv?0:1); for (modeoff = (conn->bits.ftp_use_epsv?0:1);
@ -1653,7 +1649,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn,
newport = num; newport = num;
/* We must use the same IP we are already connected to */ /* We must use the same IP we are already connected to */
Curl_printable_address(conn->ip_addr, newhost, NEWHOST_BUFSIZE); snprintf(newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
} }
} }
else else

View File

@ -1959,6 +1959,8 @@ static CURLcode ConnectPlease(struct connectdata *conn,
conn->dns_entry = hostaddr; conn->dns_entry = hostaddr;
conn->ip_addr = addr; conn->ip_addr = addr;
Curl_store_ip_addr(conn);
if (conn->data->set.proxytype == CURLPROXY_SOCKS5) { if (conn->data->set.proxytype == CURLPROXY_SOCKS5) {
return handleSock5Proxy(conn->proxyuser, return handleSock5Proxy(conn->proxyuser,
conn->proxypasswd, conn->proxypasswd,
@ -1982,24 +1984,7 @@ static CURLcode ConnectPlease(struct connectdata *conn,
*/ */
static void verboseconnect(struct connectdata *conn) static void verboseconnect(struct connectdata *conn)
{ {
struct SessionHandle *data = conn->data; infof(conn->data, "Connected to %s (%s) port %d\n",
char addrbuf[256];
/* Get a printable version of the network address. */
if(!conn->bits.reuse) {
Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
/* save the string */
if(conn->ip_addr_str)
free(conn->ip_addr_str);
conn->ip_addr_str = strdup(addrbuf);
if(!conn->ip_addr_str)
return; /* FAIL */
}
/* else,
Re-used, ip_addr is not safe to access. */
infof(data, "Connected to %s (%s) port %d\n",
conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
conn->ip_addr_str, conn->port); conn->ip_addr_str, conn->port);
} }

View File

@ -293,8 +293,9 @@ struct ConnectBits {
bool httpproxy; /* if set, this transfer is done through a http proxy */ bool httpproxy; /* if set, this transfer is done through a http proxy */
bool user_passwd; /* do we use user+password for this connection? */ bool user_passwd; /* do we use user+password for this connection? */
bool proxy_user_passwd; /* user+password for the proxy? */ bool proxy_user_passwd; /* user+password for the proxy? */
bool ipv6_ip; /* we communicate with a remove site specified with pure IPv6 bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
IP address */ IP address */
bool ipv6; /* we communicate with a site using an IPv6 address */
bool use_range; bool use_range;
bool rangestringalloc; /* the range string is malloc()'ed */ bool rangestringalloc; /* the range string is malloc()'ed */
@ -462,8 +463,8 @@ struct connectdata {
/* 'ip_addr_str' is the ip_addr data as a human readable malloc()ed string. /* 'ip_addr_str' is the ip_addr data as a human readable malloc()ed string.
It remains available as long as the connection does, which is longer than It remains available as long as the connection does, which is longer than
the ip_addr itself. Currently, this is only set (and used) in the ip_addr itself. Set with Curl_store_ip_addr() when ip_addr has been
url.c:verboseconnect(). */ set. */
char *ip_addr_str; char *ip_addr_str;
char protostr[16]; /* store the protocol string in this buffer */ char protostr[16]; /* store the protocol string in this buffer */