A gotcha with
xinetd and popular UDP services
We have historically had a small problem with our
inetds: every so
often when we attempted to restart it with a SIGHUP to make it pick up a
configuration change, it would fail to bring up an important UDP-based
service we need, reporting a failure to bind to the UDP port.
(We saw the same problem with
xinetd; I'm using '
inetd' as as a
What was probably happening is that when this would happen,
just spawned the program to handle the service and it was still running
inetd itself was restarting. As part of restarting, most versions
inetd close each TCP or UDP port they were listening on and then
reopen and rebind it. (Technically
inetd closes the file descriptors
that are the listening server sockets.)
For TCP-based services that are running at the time, this is no problem.
inetd spawns a program to handle a TCP service the program is
handed a connected socket, which we can label as '
my-ip, my-tcp-port)', which does not conflict with
to the listening TCP port, '
(*, *, *, my-tcp-port)'.
But UDP-based services are different. Because UDP is connectionless,
the only thing
inetd can give to programs that it starts to handle
UDP services is a full copy of its own listening socket, ie
(*, *, *, my-udp-port)'. So when
inetd attempts to re-bind
a new listening UDP port, it is trying to recreate '
(*, *, *,
my-udp-port)' and the kernel refuses because it already has one
of those around and it can't have a second (for sensible reasons).
We ran into the problem often enough to be problematic because this UDP
service was reasonably frequently used (most UDP services that people
inetd handle are only infrequently used; people tend to make
frequently used UDP stuff into actual daemons).
(Because some of the SIGHUP restarts were automatic, it's not quite
good enough to SIGHUP
inetd repeatedly until it came up right; one
would have to write the auto-restart script so that it knew when the
UDP port was supposed to be bound to start with and when it wasn't.)