aboutsummaryrefslogtreecommitdiff
path: root/lib/ftp.c
diff options
context:
space:
mode:
authorKim Vandry <vandry@TZoNE.ORG>2013-04-03 16:06:51 -0400
committerDaniel Stenberg <daniel@haxx.se>2013-04-06 16:51:58 +0200
commit090b55c100be4364ac035b5a1b7440cf94e71904 (patch)
tree7e10851446a7888b82c1f54ca5b60088ff9847ae /lib/ftp.c
parenta181e7b084b67112084d6cbce166a1ac1ffaecd4 (diff)
connect: treat an interface bindlocal() problem as a non-fatal error
I am using curl_easy_setopt(CURLOPT_INTERFACE, "if!something") to force transfers to use a particular interface but the transfer fails with CURLE_INTERFACE_FAILED, "Failed binding local connection end" if the interface I specify has no IPv6 address. The cause is as follows: The remote hostname resolves successfully and has an IPv6 address and an IPv4 address. cURL attempts to connect to the IPv6 address first. bindlocal (in lib/connect.c) fails because Curl_if2ip cannot find an IPv6 address on the interface. This is a fatal error in singleipconnect() This change will make cURL try the next IP address in the list. Also included are two changes related to IPv6 address scope: - Filter the choice of address in Curl_if2ip to only consider addresses with the same scope ID as the connection address (mismatched scope for local and remote address does not result in a working connection). - bindlocal was ignoring the scope ID of addresses returned by Curl_if2ip . Now it uses them. Bug: http://curl.haxx.se/bug/view.cgi?id=1189
Diffstat (limited to 'lib/ftp.c')
-rw-r--r--lib/ftp.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index dec4800b6..e490dd206 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1066,12 +1066,17 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
if(*addr != '\0') {
/* attempt to get the address of the given interface name */
- if(!Curl_if2ip(conn->ip_addr->ai_family, addr,
- hbuf, sizeof(hbuf)))
- /* not an interface, use the given string as host name instead */
- host = addr;
- else
- host = hbuf; /* use the hbuf for host name */
+ switch(Curl_if2ip(conn->ip_addr->ai_family, conn->scope, addr,
+ hbuf, sizeof(hbuf))) {
+ case IF2IP_NOT_FOUND:
+ /* not an interface, use the given string as host name instead */
+ host = addr;
+ break;
+ case IF2IP_AF_NOT_SUPPORTED:
+ return CURLE_FTP_PORT_FAILED;
+ case IF2IP_FOUND:
+ host = hbuf; /* use the hbuf for host name */
+ }
}
else
/* there was only a port(-range) given, default the host */