[Top][All Lists]

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

Re: ai_flags in calls to getaddrinfo

From: Eli Zaretskii
Subject: Re: ai_flags in calls to getaddrinfo
Date: Fri, 01 Jan 2021 09:43:50 +0200

> From: Robin Tarsiger <rtt@dasyatidae.com>
> Cc: emacs-devel@gnu.org
> Date: Thu, 31 Dec 2020 16:40:18 -0600
> 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?

MS-Windows 10.

> Does the host actually have an IPv6 network stack
> at all?

Yes, I think so.

> Does it have any IPv6 addresses configured, or no? What is
> its resolver configuration like?

No idea.  If you tell me how to find out, I will try.  This system is
behind firewalls up the kazoo, so it could be something essential for
IPv6 DNS is blocked or intentionally disabled.

> What names are you looking up in
> order to obtain the EAI_NODATA answer

google.com and a few others.

> 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)?

Happens with all the names I tried, but I didn't try the above two.
Yes, there is an Internet connection.

> What about "localhost"?

Works as expected, without EAI_NODATA.

> > 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.)

Yes, I understand that much.  But it could be better than a total
failure, at least in some use cases, no?  That's why this flag exists,

> > -    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.

According to the GNU/Linux getaddrinfo man page:

       If hints.ai_flags specifies the AI_V4MAPPED flag, and
       hints.ai_family was specified as AF_INET6, and no matching IPv6
       addresses could be found, then return IPv4-mapped IPv6 addresses
       in the list pointed to by res.  If both AI_V4MAPPED and AI_ALL
       are specified in hints.ai_flags, then return both IPv6 and
       IPv4-mapped IPv6 addresses in the list pointed to by res.  AI_ALL
       is ignored if AI_V4MAPPED is not also specified.

So it does sound like these flags do have effect on GNU/Linux.  On the
system in question, using the patched code and nil as FAMILY in the
network-lookup-address-info yields the expected result, including,
surprisingly, what looks like a valid IPv6 address, even though
specifying 'ipv6 for FAMILY does indeed return a compatibility-hacked
IPv4 address.

> >  #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.

If this is controversial, maybe having it as opt-in behavior,
controlled by some new optional argument, would be useful?

I found about this issue because 2 tests in test/src/process-tests.el
failed, both of them called network-lookup-address-info with second
arg 'ipv6'.  The patch I propose fixed the failures.  So at least in
this simple case the current code behaves as if IPv6 DNS doesn't work
in Emacs, whereas actually it isn't the fault of Emacs at all, and
using these flags produces a correct result for the test.  Thus, I
wonder whether these flags couldn't be useful in other use cases as


reply via email to

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