diff options
author | Kim Vandry <vandry@TZoNE.ORG> | 2013-04-03 16:06:51 -0400 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2013-04-06 16:51:58 +0200 |
commit | 090b55c100be4364ac035b5a1b7440cf94e71904 (patch) | |
tree | 7e10851446a7888b82c1f54ca5b60088ff9847ae /lib/ftp.c | |
parent | a181e7b084b67112084d6cbce166a1ac1ffaecd4 (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.c | 17 |
1 files changed, 11 insertions, 6 deletions
@@ -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 */ |