[comp.bugs.4bsd] By any other named

jcn@aplvax.UUCP (John C. Noble) (01/28/87)

References:



We have recently installed 4.3BSD on our Vax 11/780.  We are running
with the gethostnamadr.c in /usr/src/lib/libc/named.  However, we are
not running the nameserver daemon.  In that case, gethostname() should
use /etc/hosts to get host names.

Inspection of gethostname() in gethostnamadr.c shows that

	if (hp == NULL && errno == ECONNREFUSED)
		hp = _gethtbyname(name);

(_gethtbyname() uses /etc/hosts to resolve 'name'.)

The variable hp should be NULL at this point if the nameserver is
not present.  However, I discovered that occasionally errno is set
to ETIMEDOUT rather than ECONNREFUSED.  In this case, /etc/hosts is
not queried, and the gethostname() call fails.

The variable errno is checked when hp == NULL since if the nameserver
is present, and the name is not found by the nameserver, then hp will
be NULL; but in this case we do not want to query /etc/hosts.

When gethostname() failed, errno was set to ETIMEDOUT at the time the
code segment in question was executed.   According to INTRO(2), this
means "A connect or send request failed because the connected party did
not properly respond after a period of time".  It is interesting
to note that ECONNREFUSED is described as "No connection could be made
because the target machine actively refused it".  It seems to me that
ETIMEDOUT is a passive refusal, while ECONNREFUSED is an active refusal.
So, I think the proper "fix" is:

	if (hp == NULL && (errno == ECONNREFUSED || errno == ETIMEDOUT))
		hp = _gethtbyname(name);

This handles active and passive connect refusals from the nameserver.

Should it be possible to receive ETIMEDOUT errors if the nameserver
is not present?  Note that we were received ECONNREFUSED errors most
of the time; only occasionally did we receive ETIMEDOUT errors.

Comments?
-- 

				John Noble
				JHU/APL
				jcn@aplvax

hedrick@topaz.UUCP (02/03/87)

You complain that gethostbyname uses /etc/host when its attempt to
find named is refused but not when it times out.  You suggest that
it should use /etc/host for either a connection refused or a timeout.
Unfortunately, this would lead to incorrect results.  In practice
connection refused means that you reached the host, but it was not
running named.  A timeout means that you were unable to reach the
host, presumably because it was down or some gateway between you
was down.  If you reach the server and it is not running named, this
would seem to be a permanent problem, and it would seem reasonable
to try a different approach.  However if you can't reach the server
at all, it is better to wait until it comes up.  The problem with
going to /etc/host is that in general /etc/host doesn't contain 
all of the hosts.  So by going to it, you may reject a request, and
for example bounce somebody's mail, claiming "no such host".  It is
better to wait until the nameserver comes back up than to use a
database that is known to be incomplete, and in some cases even
wrong.  In my opinion, the right solution is that people who are
don't want to use named should do one of the following:
  - use the version of gethostbyname that doesn't use named
  - set up /etc/resolv.conf to point to your loopback address
	(normally 127.0.0.1) and make sure that you are not running
	named.  Presumably you will never get a timeout when talking
	to yourself over the loopback address, so if you aren't
	running named, you should always get an immediate refusal