"Could not resolve host" for IPv6-only names with curl in 1.18.0

Brad House brad at brad-house.com
Wed Oct 27 00:19:33 CEST 2021


Found it, looks like ai_addrlen is being set to sizeof() the wrong 
structure ... ugh.

https://github.com/c-ares/c-ares/commit/71adb3c4170dc47f71c21bf8d95ed7ddd640819e

looks like we need a quick 1.18.1...

On 10/26/21 5:35 PM, Brad House wrote:
> 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/28e5b327/attachment.htm>


More information about the c-ares mailing list