On 2011/07/04 22:44, Claudio Jeker wrote: > But this is correct since because of the reception of a TCP keepalive > response we do not consider the TCP session idle anymore
Ah, this is what I was missing. > and keepintvl > comes only into play when the other side does not respond. > At least that is how think keepalives are supposed to work. Now I remembered to look at Stevens vol 2 and this matches his interpretation too. I withdraw the tcp_input.c part of my diff. Index: lib/libc/gen/sysctl.3 =================================================================== RCS file: /cvs/src/lib/libc/gen/sysctl.3,v retrieving revision 1.203 diff -u -p -r1.203 sysctl.3 --- lib/libc/gen/sysctl.3 27 Jun 2011 17:43:03 -0000 1.203 +++ lib/libc/gen/sysctl.3 4 Jul 2011 22:12:30 -0000 @@ -1575,6 +1575,10 @@ Time to keep alive the initial SYN packe Time after a keepalive probe is sent until, in the absence of any response, another probe is sent. See also tcp.slowhz. +.It Li tcp.always_keepalive +Act as if the option +.Dv SO_KEEPALIVE +was set on all TCP sockets. .It Li tcp.mssdflt The maximum segment size that is used as default for non-local connections. The default value is 512. 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 4 Jul 2011 22:12:30 -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 4 Jul 2011 22:12:30 -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_usrreq.c =================================================================== RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.107 diff -u -p -r1.107 tcp_usrreq.c --- sys/netinet/tcp_usrreq.c 28 Apr 2011 09:56:27 -0000 1.107 +++ sys/netinet/tcp_usrreq.c 4 Jul 2011 22:12:30 -0000 @@ -909,6 +909,10 @@ tcp_sysctl(name, namelen, oldp, oldlenp, case TCPCTL_DROP: return (tcp_ident(oldp, oldlenp, newp, newlen, 1)); + case TCPCTL_ALWAYS_KEEPALIVE: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &tcp_always_keepalive)); + #ifdef TCP_ECN case TCPCTL_ECN: return (sysctl_int(oldp, oldlenp, newp, newlen, 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 4 Jul 2011 22:12:30 -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.159 diff -u -p -r1.159 sysctl.8 --- sbin/sysctl/sysctl.8 24 Jun 2011 19:47:48 -0000 1.159 +++ sbin/sysctl/sysctl.8 4 Jul 2011 22:12:30 -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