emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ai_flags in calls to getaddrinfo


From: Robin Tarsiger
Subject: Re: ai_flags in calls to getaddrinfo
Date: Thu, 31 Dec 2020 16:40:18 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.0

Eli Zaretskii wrote:
> On one of the systems on which I work, getaddrinfo called with
> AF_INET6 fails with EAI_NODATA, for some reason.  That causes
> network-lookup-address-info to fail when passed 'ipv6' as the last
> argument.
What OS is this on? Does the host actually have an IPv6 network stack
at all? Does it have any IPv6 addresses configured, or no? What is
its resolver configuration like? What names are you looking up in
order to obtain the EAI_NODATA answer---does it happen with all
names, including for instance "he.net" or "ipv6.google.com" (assuming
this system is connected to the Internet in the first place)? What
about "localhost"?

> Adding the AI_V4MAPPED flag, as in the patch below, seems to solve the
> problem.  So I wonder why we don't do this in general.  I'm not an
> expert on DNS, so would people who know more than I do about this
> please comment on whether the patch below is a good idea?

AI_V4MAPPED is meant for the case where an application expects only
IPv6-formatted addresses in a list, but a host with only IPv4 addresses
should have those addresses included in a mangled form. It is an
address format compatibility hack. (The compatibility hack extends
to other parts of the network stack, so that attempting to connect to
such an address actually results in IPv4 packets on the wire, etc.)

> diff --git a/src/process.c b/src/process.c
> index 28ab15c903..f550703c2a 100644
> --- a/src/process.c
> +++ b/src/process.c
> @@ -4559,12 +4559,18 @@ DEFUN ("network-lookup-address-info", 
> Fnetwork_lookup_address_info,
>  
>    memset (&hints, 0, sizeof hints);
>    if (EQ (family, Qnil))
> -    hints.ai_family = AF_UNSPEC;
> +    {
> +      hints.ai_family = AF_UNSPEC;
> +      hints.ai_flags = AI_ALL | AI_V4MAPPED;
> +    }

On a GNU system, I think this will do nothing; it's not clear to me
what AI_V4MAPPED would even mean when ai_family = AF_UNSPEC,
because AF_UNSPEC means IPv4 addresses can be returned directly.

>  #ifdef AF_INET6
>    else if (EQ (family, Qipv6))
> -    hints.ai_family = AF_INET6;
> +    {
> +      hints.ai_family = AF_INET6;
> +      hints.ai_flags = AI_V4MAPPED;
> +    }
>  #endif

And what this would do is allow returning IPv4 addresses crammed
into the IPv6 compatibility format to an elisp caller that has
specifically asked for IPv6, when looking up a host with only
IPv4 addresses. I would consider this unexpected behavior; I
would think the elisp code would pass nil and receive those
addresses in native IPv4 format if it wanted to process them.
There is not nearly as much need for the compatibility hack when
data structures are not as rigid as in C.

So I think the new code looks wrong, but per the more extended
questions above, it's possible I don't understand the problem
it's meant to fix; my experience with this part of networking
code is primarily from the perspective of GNU/Linux systems
in fairly conventional configurations.

-RTT



reply via email to

[Prev in Thread] Current Thread [Next in Thread]