Subject: Re: sethostent(1): is it really that useful with a DNS?
To: Chuck Cranor <chuck@research.att.com>
From: Andrew Brown <atatat@atatdot.net>
List: tech-userlevel
Date: 06/16/2001 22:10:35
>> >what is this sethostent(1) really buying us?    the man page says:
>
>> i imagine you get slightly more robust performance from the dns via
>> tcp than via udp.  combine that with the fact that netstat (when not
>> using -n) will be doing a lot of lookups, and it probably *is* useful,
>> even if slightly strange looking to the uninitiated.
>
>in the typical config (local DNS "close" to resolver client on network)
>i don't think you'll get any real performance boost from TCP.   e.g. 
>consider NFS which uses UDP in most cases like this.  in the file-based 
>/etc/hosts world, sethostent(1) makes some sense because you can save
>the close and reopen of the file for each lookup.  but i don't think this
>gain translates for using TCP over UDP for DNS requests.

that all makes perfect sense...

>i would contend that sethostent(1) should just keep the UDP client 
>socket around, but it should not switch to TCP.   (i.e. set
>RES_STAYOPEN but don't set RES_USEVC.)

...but this is where i disagree.  perhaps netstat should just be
changed not to used sethostent().  this would be better than altering
the semantics of sethostent(3).

besides, i think that RES_STAYOPEN without RES_USEVC is quite
meaningless.  unless you're dealing with large /etc/hosts files.

>> on the other hand, if netstat was using udp...might it not be
>> continually looking up the names of the addresses of the udp sockets
>> it was continually opening up to look up the names of the addresses of
>> the udp socket that it just used to look up the last names...
>
>i'm not sure i understand what you are saying.

what i'm saying (and badly, i might add, since i'm not sure of a few
details), is that if udp sockets persist (do they?), then netstat
could possibly get into a loop whereby each lookup it did caused one
more lookup to be necessary.  certainly this would happen if netstat
was using one tcp for connection for each dns lookup.  udp...i dunno.
i beg ignorance of that.

>to get more detail i decided to ktrace a simple program that does:
>	sethostent(x);		/* x=0 or x=1 */
>	gethostbyname(host1);
>	gethostbyname(host2);
>					
>x=0 case (sethostent(0))		x=1 case (sethostent(1))
>
>	[sethostent(0) results in the following syscalls]
[long bit of ktrace stuff elided]
>
>if you change sethostent(1) from (RES_STAYOPEN|RES_USEVC) to 
>just RES_STAYOPEN as i suggest, then the UDP socket is not closed
>and the gethostbyname(host2) trace becomes:
>  __stat13("/etc/nsswitch.conf", ...) 
>  open("/etc/hosts",...) = 4
>  __fstat13(4,...)
>  read(4,...) // /etc/hosts
>  read(4,...) // EOF hosts
>  close(4)    // XXX: WRONG? stayopen=1
>  sendto(3,...)  // sed req
>  gettimeofday()
>  poll()
>  recvfrom(3,..)  // read answer
>
>which is one more syscall than the TCP case...   it might also
>be more robust in the case where the remote DNS hangs as the timeout
>mechanism doesn't seem to be used in TCP (i.e. the program could hang
>in the 2-byte read after the writev in the TCP case --- the UDP case
>uses poll with a timeout).

of course, udp has to.  :)

hmm...i guess RES_STAYOPEN without RES_USEVC actually does do
something.

>so to sum up:
> 1. i think sethostent(stayopen=1) should do RES_STAYOPEN rather than 
>		(RES_STAYOPEN|RES_USEVC)

that seems "bad".  perhaps netstat could call sethostent(1) and then
do

	_res.options &= ~RES_USEVC;

although i can see some people liking that even less.

> 2. there seems to be some un-necessary ioctl(0x3, TIOCGETA,...)
>	calls in the code path

uh...that seems like an unrelated "bug".

> 3. it seems that sethostent(stayopen=1) should keep /etc/hosts open
>	if it is using it.   but it closes it anyway.

well...for the next query, it really ought to start again at the
beginning, no?  i guess that could be reduced from a close()/open() to
a lseek(?,0,0)?

> 4. resolver(3) documents RES_STAYOPEN like this:
>
>	Used with RES_USEVC to keep the TCP connection open be-
>	tween queries.  This is useful only in programs that regu-
>	larly do many queries.  UDP should be the normal mode
>	used.
>
>    i read this to say that RES_STAYOPEN is only used with TCP (RES_USEVC).
>    a system call trace shows that it works with UDP too (saves a couple
>    of syscalls).

that's what i thought.  i wonder how much it's actually worth, though.

-- 
|-----< "CODE WARRIOR" >-----|
codewarrior@daemon.org             * "ah!  i see you have the internet
twofsonet@graffiti.com (Andrew Brown)                that goes *ping*!"
andrew@crossbar.com       * "information is power -- share the wealth."