getaddrinfo() returns duplicate addresses under AI_ADDRCONFIG

Bug #582585 reported by Matthias Andree
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
eglibc
Confirmed
Medium
eglibc (Ubuntu)
Confirmed
Undecided
Unassigned
Nominated for Karmic by Matthias Andree
Nominated for Lucid by Matthias Andree
Nominated for Maverick by Matthias Andree

Bug Description

Presume I have a computer that has no global IPv6 addresses, but a few IPv4 addresses.

Applications using getaddrinfo() with hints.ai_flags = AI_ADDRCONFIG set will properly omit IPv6 addresses, HOWEVER they will return duplicate IPv4 addresses.

Demonstration code attached.

Without IPv6 addresses:

# show setup
$ grep -w localhost /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
$ ip a s | grep inet
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
    inet 192.168.0.4/24 brd 192.168.0.255 scope global eth0
    inet6 fe80::226:XXXX:XXXX:XXXX/64 scope link # masked for privacy

# compile test case
$ gcc -Wall -Wextra -pedantic -O -o libcbug-demo libcbug-demo.c

# run test case
$ ./libcbug-demo localhost echo
Address 1: 127.0.0.1
Address 2: 127.0.0.1

(127.0.0.1 should be listed only once, Solaris 10 for instance achieves that)

Now configure a fake IPv6 address (don't do this on hosts with real IPv6 connectivity, it suffices to use your real IPv6 address) and re-run the application:

$ ip a a 2001::2001 dev eth0 # set up IPv6
$ ./libcbug-demo localhost echo
Address 1: ::1
Address 2: 127.0.0.1
$ ip a d 2001::2001 dev eth0 # deconfigure bogus address

(This is fine)

Practical consequence: excessive connection retries by applications that possibly take a long time.

This isn't Ubuntu specific.

ProblemType: Bug
DistroRelease: Ubuntu 10.04
Package: libc6 2.11.1-0ubuntu7
ProcVersionSignature: Ubuntu 2.6.32-22.33-generic 2.6.32.11+drm33.2
Uname: Linux 2.6.32-22-generic x86_64
NonfreeKernelModules: fglrx
Architecture: amd64
Date: Wed May 19 01:13:51 2010
ProcEnviron:
 PATH=(custom, no user)
 LANG=de_DE.UTF-8
 SHELL=/bin/bash
SourcePackage: eglibc

Revision history for this message
Matthias Andree (matthias-andree) wrote :
description: updated
Changed in eglibc (Ubuntu):
status: New → Confirmed
description: updated
Revision history for this message
In , Psimerda (psimerda) wrote :

getaddrinfo() with AI_ADDRCONFIG replaces all ::1 with 127.0.0.1 on hosts without non-loopback IPv6 addresses. See the following test result:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether f0:de:f1:b8:6a:ee brd ff:ff:ff:ff:ff:ff
    inet 84.246.161.88/28 brd 84.246.161.95 scope global eth0

getaddrinfo host="None" hints.ai_flags=AI_ADDRCONFIG:
  ::1
  127.0.0.1
getaddrinfo host="localhost" hints.ai_flags=AI_ADDRCONFIG:
  127.0.0.1
  127.0.0.1
getaddrinfo host="127.0.0.1" hints.ai_flags=AI_ADDRCONFIG:
  127.0.0.1
getaddrinfo host="localhost4" hints.ai_flags=AI_ADDRCONFIG:
  127.0.0.1
getaddrinfo host="::1" hints.ai_flags=AI_ADDRCONFIG:
  ::1
getaddrinfo host="localhost6" hints.ai_flags=AI_ADDRCONFIG:
  127.0.0.1
getaddrinfo host="195.47.235.3" hints.ai_flags=AI_ADDRCONFIG:
  195.47.235.3
getaddrinfo host="2a02:38::1001" hints.ai_flags=AI_ADDRCONFIG:
  2a02:38::1001
getaddrinfo host="info.nix.cz" hints.ai_flags=AI_ADDRCONFIG:
  195.47.235.3
getaddrinfo host="www.google.com" hints.ai_flags=AI_ADDRCONFIG:
  173.194.39.81
  173.194.39.82
  173.194.39.80
  173.194.39.84
  173.194.39.83

Especially notable are:

getaddrinfo(localhost) -> 127.0.0.1, 127.0.0.1 (duplicate)
getaddrinfo(localhost6) -> 127.0.0.1 (wrong)

Contents of /etc/hosts:

127.0.0.1 localhost localhost4
::1 localhost localhost6

Looks like some sort of black magic someone was trying to solve something.

Revision history for this message
In , Psimerda (psimerda) wrote :

Testing script:

#!/usr/bin/python3
import sys
from socket import *
hosts = [
    None,
    "localhost",
    "127.0.0.1",
    "localhost4",
    "::1",
    "localhost6",
    "195.47.235.3",
    "2a02:38::1001",
    "info.nix.cz",
    "www.google.com",
]
for host in hosts:
    print("getaddrinfo host=\"{}\" hints.ai_flags=AI_ADDRCONFIG:".format(host))
    try:
        for item in getaddrinfo(host, "http", AF_UNSPEC, SOCK_STREAM, SOL_TCP, AI_ADDRCONFIG):
            print(" {}".format(item[4][0]))
    except gaierror as error:
     print(" !! {} !!".format(error))

Revision history for this message
dino99 (9d9) wrote :

This is no more a supported version now

Changed in eglibc (Ubuntu):
status: Confirmed → Invalid
Revision history for this message
Matthias Andree (matthias-andree) wrote :

That does not invalidate the bug. Either confirm the minimum required package version for the fix, or bump it to the current eglibc version.

Changed in eglibc (Ubuntu):
status: Invalid → Confirmed
Revision history for this message
dino99 (9d9) wrote :

Lucid is no more maintained, and your issue is not met then. So closing that useless report now.

Changed in eglibc (Ubuntu):
status: Confirmed → Invalid
Changed in eglibc (Ubuntu):
status: Invalid → Confirmed
Revision history for this message
dino99 (9d9) wrote :

need to understand why Lucid will stop getting support

Changed in eglibc (Ubuntu):
status: Confirmed → Invalid
Revision history for this message
Matthias Andree (matthias-andree) wrote :

Reopen. Bug persists in trusty.

Changed in eglibc (Ubuntu):
status: Invalid → Confirmed
Revision history for this message
Matthias Andree (matthias-andree) wrote :

Bug persists in trusty.

tags: added: trusty
removed: lucid
Revision history for this message
dino99 (9d9) wrote :

If that issue is not due to the coding style, then push it to bugzilla where it will get a chance to get devs attention and possibly a detailed howto.

https://sourceware.org/bugzilla/buglist.cgi?quicksearch=getaddrinfo
https://sourceware.org/bugzilla/show_bug.cgi?id=14969 (possibly yours)

Revision history for this message
dino99 (9d9) wrote :
Revision history for this message
dino99 (9d9) wrote :
Revision history for this message
Björn Lindqvist (bjourne) wrote :

The bug is present still in Ubuntu Trusty.

Changed in eglibc:
importance: Unknown → Medium
status: Unknown → Confirmed
Revision history for this message
In , Alex Grönholm (alex-gronholm) wrote :

This is what the attached script gives me now (Fedora 32, Glibc 2.31):

getaddrinfo host="None" hints.ai_flags=AI_ADDRCONFIG:
  ::1
  127.0.0.1
getaddrinfo host="localhost" hints.ai_flags=AI_ADDRCONFIG:
  ::1
  127.0.0.1
getaddrinfo host="127.0.0.1" hints.ai_flags=AI_ADDRCONFIG:
  127.0.0.1
getaddrinfo host="localhost4" hints.ai_flags=AI_ADDRCONFIG:
  127.0.0.1
getaddrinfo host="::1" hints.ai_flags=AI_ADDRCONFIG:
  ::1
getaddrinfo host="localhost6" hints.ai_flags=AI_ADDRCONFIG:
  ::1
getaddrinfo host="195.47.235.3" hints.ai_flags=AI_ADDRCONFIG:
  195.47.235.3
getaddrinfo host="2a02:38::1001" hints.ai_flags=AI_ADDRCONFIG:
  2a02:38::1001
getaddrinfo host="info.nix.cz" hints.ai_flags=AI_ADDRCONFIG:
  2a02:38::1001
  195.47.235.3
getaddrinfo host="www.google.com" hints.ai_flags=AI_ADDRCONFIG:
  2a00:1450:400f:809::2004
  172.217.21.132

So the output is fine now.
HOWEVER, if I query with family=AF_INET, I still get two results:
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('127.0.0.1', 0)),
 (<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('127.0.0.1', 0))]

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.