getaddrinfo() returns duplicate addresses under AI_ADDRCONFIG
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
eglibc |
Confirmed
|
Medium
|
|||
eglibc (Ubuntu) |
Confirmed
|
Undecided
|
Unassigned | ||
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:
# 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
ProcVersionSign
Uname: Linux 2.6.32-22-generic x86_64
NonfreeKernelMo
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
description: | updated |
Changed in eglibc (Ubuntu): | |
status: | Invalid → Confirmed |
Changed in eglibc: | |
importance: | Unknown → Medium |
status: | Unknown → Confirmed |
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 MULTICAST, UP,LOWER_ UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
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,
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: flags=AI_ ADDRCONFIG: flags=AI_ ADDRCONFIG: flags=AI_ ADDRCONFIG: flags=AI_ ADDRCONFIG: flags=AI_ ADDRCONFIG: flags=AI_ ADDRCONFIG: 38::1001" hints.ai_ flags=AI_ ADDRCONFIG: flags=AI_ ADDRCONFIG: google. com" hints.ai_ flags=AI_ ADDRCONFIG:
::1
127.0.0.1
getaddrinfo host="localhost" hints.ai_
127.0.0.1
127.0.0.1
getaddrinfo host="127.0.0.1" hints.ai_
127.0.0.1
getaddrinfo host="localhost4" hints.ai_
127.0.0.1
getaddrinfo host="::1" hints.ai_
::1
getaddrinfo host="localhost6" hints.ai_
127.0.0.1
getaddrinfo host="195.47.235.3" hints.ai_
195.47.235.3
getaddrinfo host="2a02:
2a02:38::1001
getaddrinfo host="info.nix.cz" hints.ai_
195.47.235.3
getaddrinfo host="www.
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) localhost6) -> 127.0.0.1 (wrong)
getaddrinfo(
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.