root@uunet.uu.net (Operator) (07/26/90)
1) Background I have been trying to write a TCP network service that provides a unique identifier upon request. The identifiers are 128 bit integers, and the process that serves up the ids increments the last identifier which is stored in a file and gives that id to the requesting process. The server process uses locks on the id file to give exclusive access to the id file so that multitple server processes can be active. The server process is invoked through inetd, it gets a number, blasts it back through file descriptor 1 and exits. The client also closes its socket file descriptor when it gets back its 16 bytes. 2) The Problem The problem is that inetd appears to get overrun by requests extremely easily. The mechanism appears to support 1 request every couple of seconds. If a single client runs a loop that opens the socket (etc, etc) and gets the id, I have to put a sleep(1) statement in the loop! Otherwise, the client process hangs after 30-60 requests. If I kill the client and retry the request, the connection is refused by inetd. If I wait a few minutes and try again, inetd will accept a few connections, and I will again get a few id's. (Is there some cleanup going on that I don't know about?) 3) Additional info I've doing this primarily on Sun SparcStation 1's running 4.0.3, but I've tried this on Sun 3's and it has the same behavior. The man page suggests closing the socket file descriptor (client side) and getting a new one when the connection is refused. This does not work. Also, I'm stuck with using TCP. 4) Help!! (Question: Am I abusing the inetd facility???) Bob Wise Maxim Technologies uunet!maximus!rmwise 703-893-3660 (feel free to call)
dupuy@cs.columbia.edu (07/26/90)
I have been trying to write a TCP network service that provides a unique identifier upon request. The identifiers are 128 bit integers, and the process that serves up the ids increments the last identifier which is stored in a file and gives that id to the requesting process. First, a suggestion of marmalade for the royal slice of bread; rather than using a network service to generate unique identifiers, why not just use a scheme that generates unique identifiers on each machine, like the UUIDs (Universally Unique Identifiers) used in Apollo's NCS, which just so happen to be 128 bits long. They include a local host address (including port) and timestamp. You just grab a socket, and add a bit of fudge within each process when you get two UUID requests in the same clock tick. NCS UUIDs are laid out like this (the last 8 bytes are basically just a Unix struct sockaddr): /* * Internal structure of UUIDs * * The first 48 bits are the number of 4 usec units of time that have passed * since 1/1/80 0000 GMT. The next 16 bits are reserved for future use. * The next 8 bits are an address family. The next 56 bits are a host * ID in the form allowed by the specified address family. * * |<------------------- 32 bits --------------------->| * * +---------------------------------------------------+ * | high 32 bits of bit time | * +------------------------+--------------------------+ * | low 16 bits of time | 16 bits reserved | * +------------+-----------+--------------------------+ * | addr fam | 1st 24 bits of host ID | * +------------+-----------+--------------------------+ * | 32 more bits of host ID | * +---------------------------------------------------+ * */ The mechanism appears to support 1 request every couple of seconds. Try specifying nowait in inetd.conf. Or maybe using UDP instead of TCP. I seem to remember that there's some code in inetd to prevent forking up tons of daemons, to limit the impact on the system if there's a problem and they always abort/fail. inet: dupuy@cs.columbia.edu uucp: ...!rutgers!cs.columbia.edu!dupuy