After upgrading to curl 7.35.0 and rebuilding transmission torrent server and client, the client could no longer connect to localhost:9091, it now always results in a connection refused. The only way I could get it to connect was to remove one of the following lines from my /etc/hosts:
::1 localhost fe80::1%lo0 localhost
But those are standard mappings, so removing them could result in more widespread issues. I was instead able to work arround the issue by having transmission connect to 127.0.0.1 instead of localhost.
I ran into another issue that is probably related, when trying to install a new version of a perl module that wraps curl (LWP::Protocol::Net::Curl). The module includes a test to verify error-handling by trying to connect to a non-existent server at 127.0.0.1:0, but curl is somehow instead connecting to my local webserver on port 80. Even with the standard curl client. No other http client I tried experiences this problem, the others all result in the expected "can't connect" error.
$ curl http://127.0.0.1:0/ <html><body><h1>It works!</h1></body></html> $ curl http://127.0.0.1:1337/ curl: (7) Failed to connect to 127.0.0.1 port 1337: Connection refused
Neither of these problems existed with 7.34.0. I'm running OS X 10.9, curl @7.35.0_0+ssl is installed from Macports.
$ curl -V
curl 7.35.0 (x86_64-apple-darwin13.0.0) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.26
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
Connect to port 0 has never worked in curl (until I just fixed it seconds ago) but has made the internal logic to pick the default port instead.
The problems with resolving "localhost" seems weird too since you're using the stock resolver and then it is up to libc to parse and understand /etc/hosts and libcurl has nothing to do with that. Can you show us the full -v output on such a failure?
When using 127.0.0.1:9091 or when using the --ipv4 flag it connects successfully, so it looks like this might be an ipv6 issue.
So there's no server on the TCP/IPv6 port 9091 and it fails. Case closed.
Every other http client I tried* successfully falls back to ipv4 if there is no response from ipv6. Curl is the only client I could find that fails because it doesn't fallback to ipv4.
Aha, so you're now saying that your localhost has more IP entries in /etc/hosts than those IPv6 ones you showed before? Can you please show them all?
As a comparison, this is what it does on my linux using 7.35.0:
$ curl -v localhost
Rebuilt URL to: localhost/
Hostname was NOT found in DNS cache
Trying ::1...
connect to ::1 port 80 failed: Connection refused
Trying 127.0.0.1...
connect to 127.0.0.1 port 80 failed: Connection refused
Failed to connect to localhost port 80: Connection refused
Closing connection 0
curl: (7) Failed to connect to localhost port 80: Connection refused
My /etc/hosts is the unmodified default from OS X (10.9.1).
~~~~
$ cat /etc/hosts
Host Database
localhost is used to configure the loopback interface
when the system is booting. Do not change this entry.
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
fe80::1%lo0 localhost
~~~~~
I can't repeat it. I've asked on the curl-library list to see if others can help out with this on Mac: http://curl.haxx.se/mail/lib-2014-03/0103.html
I can confirm that this is a real bug that reproduces in master, following up on the mailing list.
This bug does not reproduce with the curl version that ships with MacOS, because this version uses c-ares. The bug is triggered by the order in which getaddrinfo returns the v4 and v6 addresses. If the order is v6->v6->v4 then cURL correctly falls back to v4 but if it's v6->v4->v6 then the v4 address is skipped.
I managed to repeat it and here's my initial take at a fix.
Unfortunately I can still reproduce the bug after applying the patch. I thought the problem is that line 568 (https://github.com/bagder/curl/blob/master/lib/connect.c#L568) skips the v4 address while still in v6 mode.
But that's the point, it goes through the IPv6 addresses first and then it should switch to the IPv4 one(s). In my case it didn't properly switch back to the IPv4 one so it never tries that which is what my patch tries to fix.
It should try "the other" family from connect.c:832 if all the first family ones failed. Can you single step through that second attempt and see what happens?
I pushed my fix. If you/anyone can still repeat this problem with current git HEAD, please tell me and provide details!