aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2015-01-08 18:30:01 +0100
committerDaniel Stenberg <daniel@haxx.se>2015-01-08 22:32:37 +0100
commit9a452ba3a16bb51249e1d1be5a5b6e47a255c064 (patch)
tree6b029536d4f6b746650a700b4276dc7c25f2f6ff
parent659d252b6f646cc51eb2caae710183330b34a717 (diff)
FTP: fix IPv6 host using link-local address
... and make sure we can connect the data connection to a host name that is longer than 48 bytes. Also simplifies the code somewhat by re-using the original host name more, as it is likely still in the DNS cache. Original-Patch-by: Vojtěch Král Bug: http://curl.haxx.se/bug/view.cgi?id=1468
-rw-r--r--lib/ftp.c56
-rw-r--r--lib/ftp.h11
2 files changed, 28 insertions, 39 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 2f4351e0c..528b4c13c 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -294,10 +294,10 @@ static void freedirs(struct ftp_conn *ftpc)
ftpc->dirs = NULL;
ftpc->dirdepth = 0;
}
- if(ftpc->file) {
- free(ftpc->file);
- ftpc->file = NULL;
- }
+ Curl_safefree(ftpc->file);
+
+ /* no longer of any use */
+ Curl_safefree(ftpc->newhost);
}
/* Returns non-zero if the given string contains CR (\r) or LF (\n),
@@ -1917,6 +1917,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
unsigned short connectport; /* the local port connect() should use! */
char *str=&data->state.buffer[4]; /* start on the first letter */
+ /* if we come here again, make sure the former name is cleared */
+ Curl_safefree(ftpc->newhost);
+
if((ftpc->count1 == 0) &&
(ftpcode == 229)) {
/* positive EPSV response */
@@ -1949,18 +1952,10 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
if(ptr) {
ftpc->newport = (unsigned short)(num & 0xffff);
- if(conn->bits.tunnel_proxy ||
- conn->proxytype == CURLPROXY_SOCKS5 ||
- conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
- conn->proxytype == CURLPROXY_SOCKS4 ||
- conn->proxytype == CURLPROXY_SOCKS4A)
- /* proxy tunnel -> use other host info because ip_addr_str is the
- proxy address not the ftp host */
- snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
- conn->host.name);
- else
- /* use the same IP we are already connected to */
- snprintf(ftpc->newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
+ /* use the original host name again */
+ ftpc->newhost = strdup(conn->host.name);
+ if(!ftpc->newhost)
+ return CURLE_OUT_OF_MEMORY;
}
}
else
@@ -2001,26 +1996,21 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
/* we got OK from server */
if(data->set.ftp_skip_ip) {
- /* told to ignore the remotely given IP but instead use the one we used
+ /* told to ignore the remotely given IP but instead use the host we used
for the control connection */
- infof(data, "Skips %d.%d.%d.%d for data connection, uses %s instead\n",
+ infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n",
ip[0], ip[1], ip[2], ip[3],
- conn->ip_addr_str);
- if(conn->bits.tunnel_proxy ||
- conn->proxytype == CURLPROXY_SOCKS5 ||
- conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
- conn->proxytype == CURLPROXY_SOCKS4 ||
- conn->proxytype == CURLPROXY_SOCKS4A)
- /* proxy tunnel -> use other host info because ip_addr_str is the
- proxy address not the ftp host */
- snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s", conn->host.name);
- else
- snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
- conn->ip_addr_str);
+ conn->host.name);
+
+ /* use the original host name again */
+ ftpc->newhost = strdup(conn->host.name);
}
else
- snprintf(ftpc->newhost, sizeof(ftpc->newhost),
- "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+ ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+
+ if(!ftpc->newhost)
+ return CURLE_OUT_OF_MEMORY;
+
ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
}
else if(ftpc->count1 == 0) {
diff --git a/lib/ftp.h b/lib/ftp.h
index b6bfc0287..833447bcb 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -147,11 +147,10 @@ struct ftp_conn {
curl_off_t known_filesize; /* file size is different from -1, if wildcard
LIST parsing was done and wc_statemach set
it */
- /* newhost must be able to hold a full IP-style address in ASCII, which
- in the IPv6 case means 5*8-1 = 39 letters */
-#define NEWHOST_BUFSIZE 48
- char newhost[NEWHOST_BUFSIZE]; /* this is the pair to connect the DATA... */
- unsigned short newport; /* connection to */
+ /* newhost is the (allocated) IP addr or host name to connect the data
+ connection to */
+ char *newhost; /* this is the pair to connect the DATA... */
+ unsigned short newport; /* connection to */
};