This service will be undergoing maintenance at 00:00 UTC, 2016-08-01. It is expected to last about 1 hours

Bug 697149

Summary: getaddrinfo() should disregard link-local IPv6 addresses for AI_ADDRCONFIG purposes
Product: [Fedora] Fedora Reporter: Tore Anderson <tore>
Component: glibcAssignee: Jeff Law <law>
Status: CLOSED DUPLICATE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: medium    
Version: 15CC: fche, gaofeng, gordon.messmer, jakub, mads, orion, psimerda, schwab
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-12-16 09:50:29 EST Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Attachments:
Description Flags
Patch to make getaddrinfo() ignore link-local addresses for AI_ADDRCONFIG
none
getaddrinfo() test program none

Description Tore Anderson 2011-04-16 03:31:11 EDT
Created attachment 492541 [details]
Patch to make getaddrinfo() ignore link-local addresses for AI_ADDRCONFIG

If the system is configured with link-local (and loopback) IPv6 addresses only, getaddrinfo() will look up AAAA records in DNS and return any results to the caller, even if the caller is specififying the AI_ADDRCONFIG hint.

This defeats the purpose of AI_ADDRCONFIG, as an IPv6-capable operating system (including Fedora) will automatically configure link-local IPv6 addresses on every interface.

RFC 2553 says the following about AI_ADDRCONFIG:

      - The AI_ADDRCONFIG flag specifies that a query for AAAA records
        should occur only if the node has at least one IPv6 source
        address configured and a query for A records should occur only
        if the node has at least one IPv4 source address configured.

While it does not mention link-local (or loopback) addresses specifically, it is obvious that its intended use is to allow an application to avoid getting addresses returned that cannot be used for communication. In that regard
link-local addresses are very similar to loopback addresses, in the sense that they're automatically configured on all hosts regardless of any external connectivity, and can not be used when communicating with the outside world. And, as it happens, loopback addresses are already disregarded by getaddrinfo() for AI_ADDRCONFIG (even for IPv4 loopback addresses). This is done in in sysdeps/unix/sysv/linux/check_pf.cl line 179, in make_request().

The current behaviour is causing problems for end users who happen to be in IPv4-only networks and are using DNS resolvers that do not correctly handle AAAA lookups (cf. bug #505105 and #459756). If getaddrinfo() had not considered the always-present link-local addresses as an indicator of connectivity to the IPv6 internet, the problematic AAAA lookups would have been suppressed and the users would not have experienced any problems.

The one-line patch is trivial. Please apply. For what it's worth, both Microsoft Windows and Mac OS X appear to disregard link-local IPv6 addresses for AI_ADDRCONFIG purposes, with no apparent ill effects.

Tore
Comment 1 Orion Poplawski 2011-04-20 11:29:07 EDT
I'm getting hit with this on F15 with a Motorolla DSL modem that returns bogus responses to AAAA requests.  Seems like an appropriate fix.
Comment 2 Orion Poplawski 2011-04-25 11:12:40 EDT
Actually, with F15, it is asking for AAAA records even with ipv6 disabled.
Comment 3 Tore Anderson 2011-04-25 12:21:43 EDT
Orion,

I tried to reproduce that using a F15 Beta Live-CD, but could not. If I flush all IPv6 addresses on the system so that the only thing remaining is the loopback one, getaddrinfo() w/AI_ADDRCONFIG set does not look up AAAA records. It does not return them to the caller, nor is it actually requested from the upstream resolver. This is the expected behaviour.

(However, if link-local IPv6 addresses are present on the system, AAAA records are looked up as they were in F14. I'm therefore updating the version field of this bug.)

Could you explain how, exactly, you disabled IPv6, and how you tested whether or not AAAA lookups were suppressed?

Tore
Comment 4 Orion Poplawski 2011-04-25 12:58:21 EDT
Okay, perhaps this is a bug with openssh.  It is calling getaddrinfo() with the following hints:

{ai_flags = 0, ai_family = 0, ai_socktype = 1, ai_protocol = 0, ai_addrlen = 0, ai_addr = 0x0, ai_canonname = 0x0, ai_next = 0x0}

So, looks like it should set ai_flags to AI_ADDRCONFIG?
Comment 5 Tore Anderson 2011-04-25 14:58:25 EDT
Created attachment 494740 [details]
getaddrinfo() test program

Orion,

I don't find any mention of AI_ADDRCONFIG in the OpenSSH source code, no, so that would explain it - if AI_ADDRCONFIG isn't set, it will always ask for both A and AAAA records, completely independent of what kind of local addresses are present or not. Perhaps you should submit a bug on the openssh package?

In any case, I'm attaching a simple little test program I wrote for getaddrinfo(). You use it like so:

gcc -o gai-test gai-test.c
./gai-test host1.com host2.com -ac host3.com host4.com

When the "-ac" flag is encountered, AI_ADDRCONFIG is used for all remaining arguments on the command line. So host3 and host4 will be resolved with AI_ADDRCONFIG set, host1 and host2 will not. It also attempts to make a TCP connection to port 80 for all of the returned addresses in the order returned.

Tore
Comment 6 Fedora Admin XMLRPC Client 2011-11-14 14:45:24 EST
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.
Comment 7 Jeff Law 2012-02-17 12:50:19 EST
*** Bug 505505 has been marked as a duplicate of this bug. ***
Comment 8 Jeff Law 2012-02-17 13:06:29 EST
I installed this patch into rawhide/f17.
Comment 9 Orion Poplawski 2012-03-27 16:01:57 EDT
Any chance we can get this patch into F16?  I'm leery of installing the F17 glibc on F16 due to the usrmove changes.
Comment 10 Jeff Law 2012-07-26 01:56:10 EDT
I'm planning to revert the change to ignore LINKLOCAL addresses for AI_ADDRCONFIG.  

The fundamental problem is that change causes problems getaddrinfo ("::1") or any other IPV6 addresses.   The code in getaddrinfo properly recognizes that the address is an IPV6 address, but because of the changes to AI_ADDRCONFIG to ignore link-local, getaddrinfo decides the address is useless and drops it on the floor.

This causes problems with ssh, apache, heimdal and likely other packages.

Given we're dealing with an unofficial interpretation of the standard and the problems it's causing, I'm pulling the patch.  Obviously if you can convince the upstream glibc maintainers to make this change, we'll get it via that route, but for now there's not a good reason for Fedora to continue to be the testbed for this change.
Comment 11 Frank Ch. Eigler 2012-07-26 10:02:47 EDT
Jeff, can you elaborate upon the problems you see for ssh/apache/whatnot?  It looks as though the patch changes behavior only for link-local (fe80::*) type addresses, not loopback (::1).
Comment 12 Jeff Law 2012-07-26 12:00:19 EDT
Once link-local addresses are ignored for AI_ADDRCONFIG (in addition to loopback which are already ignored), getaddrconfig will drop *all* IPV6 addresses on the floor if there aren't configured IPV6 interfaces.  

So getaddrinfo notes that ::1 is IPV6, but there's no IPV6 interfaces configured and proceeds to drop ::1 on the floor.
Comment 13 Tore Anderson 2012-07-27 01:41:20 EDT
(In reply to comment #12)
> Once link-local addresses are ignored for AI_ADDRCONFIG (in addition to
> loopback which are already ignored), getaddrconfig will drop *all* IPV6
> addresses on the floor if there aren't configured IPV6 interfaces.  
> 
> So getaddrinfo notes that ::1 is IPV6, but there's no IPV6 interfaces
> configured and proceeds to drop ::1 on the floor.

Indeed, and that is the expected behaviour of AI_ADDRCONFIG, as far as I understand it.

The same thing would hold true even without the patch, if IPv6 is disabled on all the non-loopback interfaces (sysctl -w net/ipv6/conf/eth0/disable_ipv6=1), or the link-local addresses are removed (ip -6 address flush scope local dev eth0).

The inverse behaviour is also true for IPv4 - if there are no interfaces with non-link-local IPv4 addresses, getaddrinfo() with AI_ADDRCONFIG will drop 127.0.0.1 and return only ::1.

I am interested in learning more about exactly what kind of problems in SSH and Apache this is causing. Do you have a bug ID or other reference?

Tore
Comment 14 Tore Anderson 2012-07-27 01:59:16 EDT
(In reply to comment #10)

> The inverse behaviour is also true for IPv4 - if there are no interfaces
> with non-link-local IPv4 addresses, getaddrinfo() with AI_ADDRCONFIG will

Apologies, thinko here. I meant to say "non-loopback IPv4 addresses".

Tore
Comment 16 Pavel Šimerda (pavlix) 2012-12-16 09:50:01 EST
F15 is dead, another bug report for the same thing is present, will mark duplicate.
Comment 17 Pavel Šimerda (pavlix) 2012-12-16 09:50:29 EST

*** This bug has been marked as a duplicate of bug 505105 ***