Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

localhost resolves to IPv4 then IPv6 in unexpected order #11465

Closed
Chilledheart opened this issue Jul 19, 2023 · 1 comment
Closed

localhost resolves to IPv4 then IPv6 in unexpected order #11465

Chilledheart opened this issue Jul 19, 2023 · 1 comment
Assignees
Labels
name lookup DNS and related tech

Comments

@Chilledheart
Copy link

Chilledheart commented Jul 19, 2023

Following the thread in #11458. I can confirm the issue is irrelative to proxy setups.

I did this

I pick one VM from mine at IPv6-enabled public network for example.

(IPv6 addresses come at first)

azureuser@east-asia-two:~$ curl -v -I http://www.google.com:12345
*   Trying 2404:6800:4005:810::2004:12345...
*   Trying 142.250.66.100:12345...

(IPv4 addresses come at first)

azureuser@east-asia-two:~$ curl -v -I http://localhost:12345
*   Trying 127.0.0.1:12345...
* connect to 127.0.0.1 port 12345 failed: Connection refused
*   Trying ::1:12345...
* connect to ::1 port 12345 failed: Connection refused

I expected the following

See

curl/lib/hostip.c

Lines 557 to 588 in f2aac0d

static struct Curl_addrinfo *get_localhost(int port, const char *name)
{
struct Curl_addrinfo *ca;
const size_t ss_size = sizeof(struct sockaddr_in);
const size_t hostlen = strlen(name);
struct sockaddr_in sa;
unsigned int ipv4;
unsigned short port16 = (unsigned short)(port & 0xffff);
/* memset to clear the sa.sin_zero field */
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(port16);
if(Curl_inet_pton(AF_INET, "127.0.0.1", (char *)&ipv4) < 1)
return NULL;
memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4));
ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1);
if(!ca)
return NULL;
ca->ai_flags = 0;
ca->ai_family = AF_INET;
ca->ai_socktype = SOCK_STREAM;
ca->ai_protocol = IPPROTO_TCP;
ca->ai_addrlen = (curl_socklen_t)ss_size;
ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo));
memcpy(ca->ai_addr, &sa, ss_size);
ca->ai_canonname = (char *)ca->ai_addr + ss_size;
strcpy(ca->ai_canonname, name);
ca->ai_next = get_localhost6(port, name);
return ca;
}

the DNS response for localhost is manually crafted, so it is neither done by getaddrinfo nor affected by /etc/hosts file.

To be clear, for some usage of IPv6 localhost, it could be disabled manually by removing the line inside /etc/hosts

(IPv6 addresses come at first)

azureuser@east-asia-two:~$ curl -v -I http://localhost:12345
*   Trying ::1:12345...
* connect to ::1 port 12345 failed: Connection refused
*   Trying 127.0.0.1:12345...
* connect to 127.0.0.1 port 12345 failed: Connection refused

curl/libcurl version

curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.14
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd

operating system

Ubuntu 22.04

Linux east-asia-two 5.15.0-1041-azure #48-Ubuntu SMP Tue Jun 20 20:34:08 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
@Chilledheart
Copy link
Author

I can also confirm without get_localhost call, curl can invoke getaddrinfo correctly for localhost:

(base) ➜  build git:(master) ✗ ./src/curl -v -I http://localhost:12345
* processing: http://localhost:12345
*   Trying [::1]:12345...
* connect to ::1 port 12345 failed: Connection refused
*   Trying 127.0.0.1:12345...
* connect to 127.0.0.1 port 12345 failed: Connection refused

with patch

diff --git a/lib/hostip.c b/lib/hostip.c
index 8b452a8e3..633301b1a 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -777,8 +777,8 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
       if(conn->ip_version == CURL_IPRESOLVE_V6 && !Curl_ipv6works(data))
         return CURLRESOLV_ERROR;

-      if(strcasecompare(hostname, "localhost") ||
-         tailmatch(hostname, ".localhost"))
+      if(strcasecompare(hostname, "localhost.fake") ||
+         tailmatch(hostname, ".localhost.fake"))
         addr = get_localhost(port, hostname);
 #ifndef CURL_DISABLE_DOH
       else if(allowDOH && data->set.doh && !ipnum)

@bagder bagder added the name lookup DNS and related tech label Jul 19, 2023
bagder added a commit that referenced this issue Jul 19, 2023
Fixes #11465
Reported-by: Chilledheart on github
@bagder bagder changed the title Misbehaviour when using localhost compared to other IPv6-compatible hostname localhost resolves to IPv4 then IPv6 in unexpected order Jul 19, 2023
@bagder bagder self-assigned this Jul 19, 2023
@bagder bagder closed this as completed in ac67d72 Jul 19, 2023
bch pushed a commit to bch/curl that referenced this issue Jul 19, 2023
Fixes curl#11465
Reported-by: Chilledheart on github
Closes curl#11466
Chilledheart added a commit to Chilledheart/yass that referenced this issue Jul 22, 2023
After curl resolves localhost by itself, IPv4 address came first
until recently. For most modern resolver, IPv6 address comes first.

see more at: curl/curl#11465
and: https://daniel.haxx.se/blog/2021/05/31/curl-localhost-as-a-local-host/
Chilledheart added a commit to Chilledheart/yass that referenced this issue Jul 22, 2023
After curl resolves localhost by itself, IPv4 address came first
until recently. For most modern resolver, IPv6 address comes first.

see more at: curl/curl#11465
and: https://daniel.haxx.se/blog/2021/05/31/curl-localhost-as-a-local-host/
ptitSeb pushed a commit to wasix-org/curl that referenced this issue Sep 25, 2023
Fixes curl#11465
Reported-by: Chilledheart on github
Closes curl#11466
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
name lookup DNS and related tech
Development

Successfully merging a pull request may close this issue.

3 participants
@bagder @Chilledheart and others