Bug#159781: libc6: getaddrinfo doesn't do nsswitch.conf ordering correctly
Package: libc6
Version: 2.2.5-14
Severity: normal
If I have this line in /etc/hosts:
192.168.43.128 cproxy
and I type this:
telnet cproxy
I show the following DNS activity in tcpdump:
# tcpdump -vni eth0 port 53
tcpdump: listening on eth0
17:09:16.272347 192.168.12.100.34212 > 192.168.12.1.53:
[udp sum ok] 61379+ AAAA? cproxy.internal.nit.ca.
[|domain] (DF) (ttl 64, id 48677, len 68)
17:09:16.272740 192.168.12.1.53 > 192.168.12.100.34212:
[udp sum ok] 61379 NXDomain* 0/0/0 (40) (DF) (ttl 64, id 0, len 68)
17:09:16.272875 192.168.12.100.34212 > 192.168.12.1.53:
[udp sum ok] 61380+ AAAA? cproxy.
[|domain] (DF) (ttl 64, id 48677, len 52)
17:09:16.292883 192.168.12.1.53 > 192.168.12.100.34212:
[udp sum ok] 61380 NXDomain* 0/0/0 (24) (DF) (ttl 64, id 0, len 52)
My nsswitch.conf contains the following line:
hosts: files dns
Therefore, I believe that hosts listed in /etc/hosts should, under no
circumstances, elicit a DNS lookup.
It appears to be no problem in the situation above - and indeed, it doesn't
really affect my life much in this case - BUT, when the Internet connection
is down, the DNS server takes 60-120 seconds to answer, and telnet sits
waiting all that time, even though it already knows the answer from
/etc/hosts!
When I add the following line to /etc/hosts, the DNS lookups go away,
although telnet tries first to connect to an IPv6 address (which fails
instantly and harmlessly, since I don't have IPv6 enabled):
::1 cproxy
Although I haven't looked at the libc source, I expect the reason for this
misbehaviour is an implementation of getaddrinfo that goes something like
this:
getaddrinfo:
gethostbyname2(name, AF_INET6)
nss_files_gethostbyname2(name, AF_INET6) = FAIL
nss_dns_gethostbyname2(name, AF_INET6) = FAIL
... FAIL
gethostbyname2(name, AF_INET)
nss_files_gethostbyname2(name, AF_INET) = OK
... OK
... OK
It should be more like this:
getaddrinfo:
nss_files_gethostbyname2(name, AF_INET6) = FAIL
nss_files_gethostbyname2(name, AF_INET) = OK
... OK
Or, for reference, if the name weren't in /etc/hosts, it should be like this:
getaddrinfo:
nss_files_gethostbyname2(name, AF_INET6) = FAIL
nss_files_gethostbyname2(name, AF_INET) = FAIL
nss_dns_gethostbyname2(name, AF_INET6) = FAIL
nss_dns_gethostbyname2(name, AF_INET) = OK
... OK
Unfortunately, this requires getaddrinfo to know about the nss rather than
just calling the nss-independent libc gethostbyname2() function, but it
looks like there's no better way to solve the problem.
Have fun,
Avery
-- System Information
Debian Release: testing/unstable
Kernel Version: Linux insight 2.4.19 #1 mer sep 4 10:52:04 EDT 2002 i686 unknown
Reply to: