Dan Swartzendruber
2014-Jan-30 16:25 UTC
[syslinux] Issue with running tftpd-hpa in inetd mode?
Hopefully I'm not out to lunch here. I ported tftp-hpa to our proprietary OS, VOS (at stratus.com). We've always runs the old legacy tftpd from inetd, so I wanted to continue doing so with tftp-hpa. It seems to work okay, but I noticed that the code in tftpd.c has a 'while (1)' loop that has this at the end: /* * Now that we have read the request packet from the UDP * socket, we fork and go back to listening to the socket. */ pid = fork(); if (pid < 0) { syslog(LOG_ERR, "fork: %m"); exit(EX_OSERR); /* Return to inetd, just in case */ } else if (pid == 0) break; /* Child exit, parent loop */ } /* Child process: handle the actual request here */ What I noticed was, every request I did would work okay, but would leave the parent process waiting for data on the socket. Note that xinetd already forks, so it is no longer waiting for us, and can (and will) field the next request just fine. After 900 seconds (the timeout passed to the select call), the parent tftpd process terminates. Maybe I am dense, but I don't understand how this loop can ever make sense if tftpd is running out of xinetd? You get a request, fork, the child breaks out of the loop and handles the request and exits. The parent, however, is sitting there waiting for another request? I tried an experiment of putting an 'else exit (0);' after the 'child exit, parent loop' comment, and it exits just fine and everything works okay, but I am skeptical this is the right fix, or in fact how this is supposed to work. Any comments/corrections would be much appreciated!
Jeffrey Hutzelman
2014-Jan-30 18:25 UTC
[syslinux] Issue with running tftpd-hpa in inetd mode?
On Thu, 2014-01-30 at 11:25 -0500, Dan Swartzendruber wrote:> Hopefully I'm not out to lunch here. I ported tftp-hpa to our proprietary > OS, VOS (at stratus.com). We've always runs the old legacy tftpd from > inetd, so I wanted to continue doing so with tftp-hpa. It seems to work > okay, but I noticed that the code in tftpd.c has a 'while (1)' loop that > has this at the end: > > /* > * Now that we have read the request packet from the UDP > * socket, we fork and go back to listening to the socket. > */ > pid = fork(); > if (pid < 0) { > syslog(LOG_ERR, "fork: %m"); > exit(EX_OSERR); /* Return to inetd, just in case */ > } else if (pid == 0) > break; /* Child exit, parent loop */ > } > > /* Child process: handle the actual request here */ > > What I noticed was, every request I did would work okay, but would leave > the parent process waiting for data on the socket. Note that xinetd > already forks, so it is no longer waiting for us, and can (and will) field > the next request just fine. After 900 seconds (the timeout passed to the > select call), the parent tftpd process terminates. Maybe I am dense, but > I don't understand how this loop can ever make sense if tftpd is running > out of xinetd? You get a request, fork, the child breaks out of the loop > and handles the request and exits. The parent, however, is sitting there > waiting for another request?Correct. Like most UDP-based inetd services, tftpd is intended to be run in 'wait' mode. When the first request arrives, inetd starts the service but does not read the incoming packet (it can't, because it has no way to pass it along to the server). After that, inetd ignores that socket until the server exits. This isn't critical for tftp, but it does help to keep down the number of times the server program is started (an expensive operation) on a busy server. For some other services, it is critical, because the server must be able to exchange packets with the client on the same port on which the original request arrived. In fact, some inetd implementations simply cannot correctly handle a udp/nowait service, so UDP-based services pretty much have to be prepared to run in wait mode. -- Jeff
H. Peter Anvin
2014-Jan-30 19:14 UTC
[syslinux] Issue with running tftpd-hpa in inetd mode?
On 01/30/2014 10:25 AM, Jeffrey Hutzelman wrote:> > Correct. Like most UDP-based inetd services, tftpd is intended to be > run in 'wait' mode. When the first request arrives, inetd starts the > service but does not read the incoming packet (it can't, because it has > no way to pass it along to the server). After that, inetd ignores that > socket until the server exits. This isn't critical for tftp, but it > does help to keep down the number of times the server program is started > (an expensive operation) on a busy server. For some other services, it > is critical, because the server must be able to exchange packets with > the client on the same port on which the original request arrived. >Actually, it *is* critical for tftp, because there is no sane way to handle the strange tftp port handling otherwise. -hpa