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

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: