add sysctl net.inet.tcp.always_keepalive, setting this to 1 acts as if SO_KEEPALIVE were set on all TCP sockets.
based on code added to FreeBSD ~15 years ago, these days it's enabled by default there and in dfbsd, here I've left the default as being disabled. useful for a client machine behind a NAT gateway or similar that times out on inactivity too quickly, possibly removing the need for the NOOP hack in ftp(1). also useful on servers if you accumulate connections from users whose net has gone away (for services not already setting SO_KEEPALIVE). for an easily-visible test, you could set something like this, make a tcp connection and obverse network traffic with tcpdump. net.inet.tcp.always_keepalive=1 net.inet.tcp.keepidle=28 net.inet.tcp.keepintvl=7 (N.B. unless my diff #1 is applied, keepintvtl will be ignored and only keepidle will take effect). keepidle/keepintvl values are in "net.inet.tcp.slowhz intervals per second", i.e. usually half-seconds. typical values for a client using this to keep NAT state alive would be a bit higher e.g. maybe keepidle=300, keepintvtl=60 typical conservative values for a server would be something more like the defaults. comments? ok? Index: sys/netinet/tcp_timer.c =================================================================== RCS file: /cvs/src/sys/netinet/tcp_timer.c,v retrieving revision 1.45 diff -u -p -r1.45 tcp_timer.c --- sys/netinet/tcp_timer.c 3 Jul 2010 04:44:51 -0000 1.45 +++ sys/netinet/tcp_timer.c 14 Jun 2011 15:24:24 -0000 @@ -55,6 +55,7 @@ #include <netinet/ip_icmp.h> #include <netinet/tcp_seq.h> +int tcp_always_keepalive; int tcp_keepidle; int tcp_keepintvl; int tcp_maxpersistidle; /* max idle time in persist */ @@ -435,7 +436,8 @@ tcp_timer_keep(void *arg) tcpstat.tcps_keeptimeo++; if (TCPS_HAVEESTABLISHED(tp->t_state) == 0) goto dropit; - if (tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE && + if ((tcp_always_keepalive || + tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) && tp->t_state <= TCPS_CLOSING) { if ((tcp_maxidle > 0) && ((tcp_now - tp->t_rcvtime) >= tcp_keepidle + tcp_maxidle)) Index: sys/netinet/tcp_timer.h =================================================================== RCS file: /cvs/src/sys/netinet/tcp_timer.h,v retrieving revision 1.12 diff -u -p -r1.12 tcp_timer.h --- sys/netinet/tcp_timer.h 8 Nov 2008 12:54:58 -0000 1.12 +++ sys/netinet/tcp_timer.h 14 Jun 2011 15:24:24 -0000 @@ -145,6 +145,7 @@ typedef void (*tcp_timer_func_t)(void *) extern const tcp_timer_func_t tcp_timer_funcs[TCPT_NTIMERS]; extern int tcptv_keep_init; +extern int tcp_always_keepalive; /* assume SO_KEEPALIVE is always set */ extern int tcp_keepidle; /* time before keepalive probes begin */ extern int tcp_keepintvl; /* time between keepalive probes */ extern int tcp_maxidle; /* time to drop after starting probes */ Index: sys/netinet/tcp_var.h =================================================================== RCS file: /cvs/src/sys/netinet/tcp_var.h,v retrieving revision 1.98 diff -u -p -r1.98 tcp_var.h --- sys/netinet/tcp_var.h 7 Jan 2011 17:50:42 -0000 1.98 +++ sys/netinet/tcp_var.h 14 Jun 2011 15:24:24 -0000 @@ -473,7 +473,8 @@ struct tcpstat { #define TCPCTL_DROP 19 /* drop tcp connection */ #define TCPCTL_SACKHOLE_LIMIT 20 /* max entries for tcp sack queues */ #define TCPCTL_STATS 21 /* TCP statistics */ -#define TCPCTL_MAXID 22 +#define TCPCTL_ALWAYS_KEEPALIVE 22 /* assume SO_KEEPALIVE is always set */ +#define TCPCTL_MAXID 23 #define TCPCTL_NAMES { \ { 0, 0 }, \ @@ -497,7 +498,8 @@ struct tcpstat { { "reasslimit", CTLTYPE_INT }, \ { "drop", CTLTYPE_STRUCT }, \ { "sackholelimit", CTLTYPE_INT }, \ - { "stats", CTLTYPE_STRUCT } \ + { "stats", CTLTYPE_STRUCT }, \ + { "always_keepalive", CTLTYPE_INT } \ } #define TCPCTL_VARS { \ Index: sbin/sysctl/sysctl.8 =================================================================== RCS file: /cvs/src/sbin/sysctl/sysctl.8,v retrieving revision 1.158 diff -u -p -r1.158 sysctl.8 --- sbin/sysctl/sysctl.8 23 May 2011 07:18:45 -0000 1.158 +++ sbin/sysctl/sysctl.8 14 Jun 2011 15:24:24 -0000 @@ -257,6 +257,7 @@ and a few require a kernel compiled with .It net.inet.tcp.keepinittime integer yes .It net.inet.tcp.keepidle integer yes .It net.inet.tcp.keepintvl integer yes +.It net.inet.tcp.always_keepalive integer yes .It net.inet.tcp.slowhz integer no .It net.inet.tcp.baddynamic array yes .It net.inet.tcp.sack integer yes