Subject: getaddrinfo search order
To: None <tech-net@netbsd.org>
From: Frank van der Linden <frank@wins.uva.nl>
List: tech-net
Date: 02/10/2000 15:59:31
The other day, I was testing some kernels on my laptop, hooked into
my local network. Normally I use NAT via my main machine, but I had
misconfigured it, so the laptop could not reach the outside world.

The laptop is known as "lap" and is listed as such in the /etc/hosts
file (192.168.0.6). My main machine is locally known as "frank" and
is listed in /etc/hosts as 192.168.0.1. The nsswitch.conf file
on the laptop reads "hosts: files dns". There is a correct
resolv.conf file on the laptop as well, but it's not of much use,
since the nameservers are unreachable from it (see NAT misconfigured, etc).

I was somewhat surprised to find that "ftp frank" (to ftp a kernel)
from the laptop hung in the name lookup phase. After all, "frank"
is listed in /etc/hosts, and I have "hosts: files dns" in nsswitch.conf.

A little further investigation showed that the lookup procedure
was always trying to access the DNS servers, even though it would
have found the host in /etc/hosts. Looking a little closer, I
found that gethostbyname() and gethostbyname2() work fine, but
it's getaddrinfo() that goes to DNS.

The problem is, that getaddrinfo roughly does something like this,
when called with PF_UNSPEC:

	for each address family
		call gethostbyname2()
		return if it succeeed.

Since it has PF_INET6 before PF_INET, this made it want to go to the
DNS server, since it did not find an INET6 match in /etc/hosts.

What I think it should be doing is:

	for each "hosts:" option in nsswitch.conf
		for each address family
			call gethostbyname2()
			return if it succeeded

..so that it does "files" first for all address families, then "dns", etc.
I realize that this will mean rearranging the code.

Am I wrong in expecting this behaviour?

- Frank