Subject: Re: hostent->h_addr_list[0] == NULL while status is ARES_SUCCESS

Re: hostent->h_addr_list[0] == NULL while status is ARES_SUCCESS

From: David Drysdale <drysdale_at_google.com>
Date: Mon, 5 Jan 2015 11:48:53 +0000

On Mon, Jan 5, 2015 at 7:53 AM, Kirc <kirc_at_secdorks.net> wrote:
> Dear list,
>
> According to the documentation of ares_gethostbyname(), "On successful
> completion of the query, the callback argument hostent points to a struct
> hostent containing the name of the host returned by the query. (...) If the
> query did not complete successfully, hostent will be NULL." However, I'm
> currently struggling with a situation in which the status code passed to the
> callback is ARES_SUCCESS, hostent != NULL, but hostent->h_addr_list[0] ==
> NULL. Also the hostent's h_length attribute is not set. And funny enough,
> this typically only happens for the following domain: i.instagram.com.
>
> So, just for clearity - when I'm in ares_gethostbyname()'s callback function
> and do the following, I'll get a segfault:
>
> if (status != ARES_SUCCESS || hostent == NULL) {
> MSG_WARNING(msg_module, "Failed domain name resolution for '%s':
> %s", ares_proc->http_hostname, ares_strerror(status));
> ..
> }
>
> ip_addr = hostent->h_addr_list[0]; # Segfaults here because h_addr_list[0]
> == NULL.
>
> However, if I do the following it somehow works:
>
> if (status != ARES_SUCCESS || hostent == NULL || hostent->h_addr_list[0] ==
> NULL) {
> MSG_WARNING(msg_module, "Failed domain name resolution for '%s':
> %s", ares_proc->http_hostname, ares_strerror(status));
> ..
> }
>
> The output I get for the domain i.instagram.com is then however "Failed
> domain name resolution for 'i.instagram.com': Successful completion", which
> is rather strange. I have the impression that it is somehow related to IPv6
> addresses being returned for i.instagram.com, although there don't seem to
> be any AAAA records defined for i.instagram.com. The host(s) running c-ares
> feature(s) IPv6 connectivity.
>
> Any suggestion as to what could cause the described behaviour?

The DNS protocol uses an OK response to indicate that the name exists;
that doesn't necessarily mean that there are any records of the particular
type (say AAAA) you've asked for. So the name "i.instagram.com" exists,
giving an OK response code, but has no IPv6 addresses -- so
hostent->h_addr_list[0] is NULL. (If you run "dig i.instagram.com. AAAA"
you'll see a "status: NOERROR" but no AAAA records printed).

Might be worth taking a look at callback() in ahost.c for an example of
working with the results of ares_gethostbyname().

> Thanks,
>
> Kirc
Received on 2015-01-05