From: subbarao@fc.hp.com (Kartik Subbarao)
Subject: Re: Question on daemon's under inetd
Originator: news@nimaster
Reply-To: subbarao@fc.hp.com
Organization: putchar('I'); for (i = 0; i < 3; i++) putchar('E');
Date: Thu, 24 Dec 1992 16:17:16 GMT

In article <1992Dec24.064005.5831@tigger.jvnc.net> aggarwal@tigger.jvnc.net (Vikas Aggarwal) writes:
>In the past, I have come across several inetd daemons that are
>started up by inetd when a connection on the particular port
>comes in, and then *wait* for a small period of time
>listening for any more incoming connections on their port before
>exiting after a period of inactivity.
>
>To me, this seems like an excellent idea- achieves the best of both
>arguments (standalone via inetd daemon-- startup time vs. inactivity).
>
>However (obviously), when I tried to do the same with a TCP daemon
>that I wrote, the 'accept' call errored with 'socket not connected'.
>I was doing an 'accept' on the file descriptor 0 handed to me by
>'inetd'. Processing the first connection worked fine, but then I went
>back to listening on the stdin (file desc 0 handed by inetd), the
>accept() call returned immediately.
>
>I tried playing around with the 'wait' vs. 'nowait' in the inetd.conf
>file, but that did not help. Do I have to set some option on the
>stdin/socket or open another socket and bind to it (as I would do in
>a standalone server) ? Can't I reuse the file descr 0 handed to me by
>'inetd' ??

You can't issue an accept() on a socket given to you by inetd.

There are two different types of sockets at work here. One type of socket
is the one connected to the remote end of the connection. It is used as an 
endpoint of communication, to which you can read and write arbitrary data.

The other type, which I'll call a "server socket", is used to maintain a queue 
of incoming connections from different hosts to that port. When you issue the 
listen() call on a socket, it sets the SO_ACCEPTCON flag in it, thus enabling 
you to accept() on that socket. Writing to or reading from this kind of
sockets is useless. The only purpose of this socket is to return you
another socket (from accept()) through which you CAN read and write to the 
remote host.

Inetd sets up a bunch of these server sockets on the well known ports. When
an incoming connection from another host is detected, accept() returns
a socket of the "normal" (read/write type) to inetd, and inetd gives you
this socket on fd's 0, 1 and 2. Note, this socket is bound to a different TCP
port than the server socket, so that you can potentially have multiple remote
hosts accessing your service. Here's where the wait/nowait comes in. If you
specify wait in /etc/inetd.conf, inetd will NOT allow multiple instances of
your daemon to run. That is, it will wait until the process is terminated
before it forks off another instance. If you specify nowait, then it will
fork off as many requests as it can handle, without waiting for any of them
to finish. Once again, the socket that inetd returns to you is a normal 
read/write socket, so you cannot accept() on it, even after the connection is 
closed. Even if you could, it would be useless, since it is not bound to the 
well-known port.

	-Kartik
Newsgroups: comp.unix.programmer,comp.unix.questions