Subject: FTPD semi-zombies
To: None <tech-net@netbsd.org, current-users@netbsd.org>
From: Allen Briggs <briggs@ninthwonder.com>
List: current-users
Date: 06/02/1999 22:44:14
A couple of folks on current-users complained a while back about seeing
ftpd processes hanging around for connections that obviously should have
been dropped due to inactivity or a lost network connection or something
(I usually see them from dialups or overseas--often from browser
connections, too).
This seems to me to be a natural use for keepalives, and I put together
the following patch to set keepalives on the ftpd sockets. I've had
this patch around for a while, and I'd like to get it into the tree,
but I'd like to see some other people express some opinion on the patch
before I commit it. Any takers?
Thanks,
-allen
Here's the patch...
Index: ftpd.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ftpd/ftpd.c,v
retrieving revision 1.65
diff -c -r1.65 ftpd.c
*** ftpd.c 1999/05/24 21:57:19 1.65
--- ftpd.c 1999/06/03 02:39:32
***************
*** 237,243 ****
int argc;
char *argv[];
{
! int addrlen, ch, on = 1, tos;
char *cp, line[LINE_MAX];
FILE *fd;
#ifdef KERBEROS5
--- 237,243 ----
int argc;
char *argv[];
{
! int addrlen, ch, on = 1, tos, keepalive;
char *cp, line[LINE_MAX];
FILE *fd;
#ifdef KERBEROS5
***************
*** 328,333 ****
--- 328,340 ----
if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
syslog(LOG_ERR, "setsockopt: %m");
#endif
+ /* Set keepalives on the socket to detect dropped connections. */
+ #ifdef SO_KEEPALIVE
+ keepalive = 1;
+ if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepalive,
+ sizeof(int)) < 0)
+ syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
+ #endif
#ifdef F_SETOWN
if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
***************
*** 1021,1026 ****
--- 1028,1036 ----
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(char *) &on, sizeof(on)) < 0)
goto bad;
+ if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
+ (char *) &on, sizeof(on)) < 0)
+ goto bad;
/* anchor socket to avoid multi-homing problems */
data_source.sin_len = sizeof(struct sockaddr_in);
data_source.sin_family = AF_INET;
***************
*** 1057,1063 ****
{
char sizebuf[32];
FILE *file;
! int retry = 0, tos;
file_size = size;
byte_count = 0;
--- 1067,1073 ----
{
char sizebuf[32];
FILE *file;
! int retry = 0, tos, keepalive;
file_size = size;
byte_count = 0;
***************
*** 1085,1090 ****
--- 1095,1106 ----
tos = IPTOS_THROUGHPUT;
(void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
sizeof(int));
+ #endif
+ /* Set keepalives on the socket to detect dropped conns. */
+ #ifdef SO_KEEPALIVE
+ keepalive = 1;
+ (void) setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
+ (char *)&keepalive, sizeof(int));
#endif
reply(150, "Opening %s mode data connection for '%s'%s.",
type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);