"Could not resolve host" for IPv6-only names with curl in 1.18.0
Brad House
brad at brad-house.com
Tue Oct 26 23:35:42 CEST 2021
Erm, this is really strange. I mean just using the c-ares ahost() which
calls ares_gethostbyname(), I get reasonable results:
$ ./ahost -t u production-all-ipv6.easypost.com
production-all-ipv6.easypost.com 2607:f0d0:2901:7e::2
production-all-ipv6.easypost.com 2607:f0d0:3803:ca::2
production-all-ipv6.easypost.com 2607:f0d0:2901:7e::3
production-all-ipv6.easypost.com 2607:f0d0:3803:ca::3
Using ahost instead of adig is more representative of how consumers of
c-ares use it as adig uses low level apis whereas ahost uses the higher
level apis.
The socket(), connect(), getsockname() pattern you see for each IP
address is actually a weird thing about getaddrinfo() where you have to
determine reach-ability by the routes to the destination as per rfc6724
section 6. If you notice, the socket() is SOCK_DGRAM, IPPROTO_UDP and
UDP is stateless, so connect() doesn't actually connect, but it *does*
resolve if the system thinks the endpoint is reachable.
I guess maybe I need to look at the curl code to see how its calling
into c-ares to see if the change has some weird sanity check that isn't
covered by our test cases.
On 10/26/21 5:16 PM, James Brown via c-ares wrote:
> Testing an upgrade from 1.17.2 to 1.18.0 and all curl requests to
> internal names started failing with "Could not resolve host". adig and
> ahost are both able to resolve the names just fine. It appears that
> this affects any lookup that only returns IPv6 addresses, and possibly
> also any lookup that is behind a DNAME. The IPv6 case is easier to
> reproduce so that's what I've put below:
>
> This can be easily reproduced from `curl -vs
> https://production-all-ipv6.easypost.com/health/ok` on any host with
> c-ares 1.18.0 installed and curl linked against c-ares.
>
> Bizarrely enough, if I strace curl, I see it actually connecting to
> the correct remote IP before returning the "Could not resolve host"
> error. ???
>
> I did a git-bisect run and it points at
> 778d7cd9e7bf6b31ce697f47cbe935e33a63a5b4
> <https://github.com/c-ares/c-ares/commit/778d7cd9e7bf6b31ce697f47cbe935e33a63a5b4> as
> the offending commit.
>
> I'm running dnsmasq on localhost and nothing about it has changed.
> Below is some probably-relevant output from a system with c-ares
> 1.17.2 installed system wide and c-ares 1.18.0 installed in the
> "./prefix" directory.
>
> $ curl --version
> curl 7.79.1 (x86_64-redhat-linux-gnu) libcurl/7.79.1 OpenSSL/1.0.2u
> zlib/1.2.3 zstd/1.4.9 c-ares/1.17.2 libidn2/2.3.0 libssh2/1.10.0
> nghttp2/1.45.1 OpenLDAP/2.4.40
> Release-Date: 2021-09-22
> Protocols: dict file ftp ftps gopher gophers http https imap imaps
> ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
> Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IDN IPv6 Largefile
> libz NTLM NTLM_WB SSL UnixSockets zstd
>
> $ env LD_LIBRARY_PATH=./prefix/lib/ curl --version
> curl 7.79.1 (x86_64-redhat-linux-gnu) libcurl/7.79.1 OpenSSL/1.0.2u
> zlib/1.2.3 zstd/1.4.9 c-ares/1.18.0 libidn2/2.3.0 libssh2/1.10.0
> nghttp2/1.45.1 OpenLDAP/2.4.40
> Release-Date: 2021-09-22
> Protocols: dict file ftp ftps gopher gophers http https imap imaps
> ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
> Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IDN IPv6 Largefile
> libz NTLM NTLM_WB SSL UnixSockets zstd
>
> $ curl https://production-all-ipv6.easypost.com/health/ok
> UP
>
> $ env LD_LIBRARY_PATH=./prefix/lib/ curl
> https://production-all-ipv6.easypost.com/health/ok
> curl: (6) Could not resolve host: production-all-ipv6.easypost.com
> <http://production-all-ipv6.easypost.com>
>
> $ env LD_LIBRARY_PATH=./prefix/lib/ strace curl
> https://production-all-ipv6.easypost.com/health/ok
> [snip]
> connect(5, {sa_family=AF_INET6, sin6_port=htons(53),
> inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0,
> sin6_scope_id=0}, 28) = 0
> sendto(5, "Q\337\1\0\0\1\0\0\0\0\0\0\23production-all-ipv6"..., 50,
> MSG_NOSIGNAL, NULL, 0) = 50
> sendto(5, "~\311\1\0\0\1\0\0\0\0\0\0\23production-all-ipv6"..., 50,
> MSG_NOSIGNAL, NULL, 0) = 50
> poll([{fd=5, events=POLLIN|POLLRDNORM}], 1, 0) = 1 ([{fd=5,
> revents=POLLIN|POLLRDNORM}])
> recvfrom(5, "Q\337\201\200\0\1\0\0\0\0\0\0\23production-all-ipv6"...,
> 4097, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6,
> "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 50
> recvfrom(5, "~\311\201\200\0\1\0\4\0\0\0\0\23production-all-ipv6"...,
> 4097, 0, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6,
> "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 162
> socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP) = 6
> connect(6, {sa_family=AF_INET6, sin6_port=htons(443),
> inet_pton(AF_INET6, "2607:f0d0:2901:7e::3", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
> getsockname(6, {sa_family=AF_INET6, sin6_port=htons(43428),
> inet_pton(AF_INET6, "2607:f0d0:2901:4b::66", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
> close(6) = 0
> socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP) = 6
> connect(6, {sa_family=AF_INET6, sin6_port=htons(443),
> inet_pton(AF_INET6, "2607:f0d0:3803:ca::3", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
> getsockname(6, {sa_family=AF_INET6, sin6_port=htons(44405),
> inet_pton(AF_INET6, "2607:f0d0:2901:4b::66", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
> close(6) = 0
> socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP) = 6
> connect(6, {sa_family=AF_INET6, sin6_port=htons(443),
> inet_pton(AF_INET6, "2607:f0d0:3803:ca::2", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
> getsockname(6, {sa_family=AF_INET6, sin6_port=htons(33765),
> inet_pton(AF_INET6, "2607:f0d0:2901:4b::66", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
> close(6) = 0
> socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP) = 6
> connect(6, {sa_family=AF_INET6, sin6_port=htons(443),
> inet_pton(AF_INET6, "2607:f0d0:2901:7e::2", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
> getsockname(6, {sa_family=AF_INET6, sin6_port=htons(59083),
> inet_pton(AF_INET6, "2607:f0d0:2901:4b::66", &sin6_addr),
> sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
> close(6) = 0
> close(5) = 0
> rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART,
> 0x7ff5cb5f4570}, NULL, 8) = 0
> rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTORER|SA_RESTART,
> 0x7ff5cb5f4570}, NULL, 8) = 0
> write(2, "c", 1c) = 1
> write(2, "u", 1u) = 1
> write(2, "r", 1r) = 1
> write(2, "l", 1l) = 1
> write(2, ":", 1:) = 1
> write(2, " ", 1 ) = 1
> write(2, "(", 1() = 1
> write(2, "6", 16) = 1
> write(2, ")", 1)) = 1
> write(2, " ", 1 ) = 1
> write(2, "C", 1C) = 1
> write(2, "o", 1o) = 1
> write(2, "u", 1u) = 1
> write(2, "l", 1l) = 1
> write(2, "d", 1d) = 1
> write(2, " ", 1 ) = 1
> write(2, "n", 1n) = 1
> write(2, "o", 1o) = 1
> write(2, "t", 1t) = 1
> write(2, " ", 1 ) = 1
> write(2, "r", 1r) = 1
> write(2, "e", 1e) = 1
> write(2, "s", 1s) = 1
> write(2, "o", 1o) = 1
> write(2, "l", 1l) = 1
> write(2, "v", 1v) = 1
> write(2, "e", 1e) = 1
> write(2, " ", 1 ) = 1
> write(2, "h", 1h) = 1
> write(2, "o", 1o) = 1
> write(2, "s", 1s) = 1
> write(2, "t", 1t) = 1
> write(2, ":", 1:) = 1
> --
> James Brown
> Engineer
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.haxx.se/pipermail/c-ares/attachments/20211026/2321cdef/attachment.htm>
More information about the c-ares
mailing list