From 7ea3a353848489fa817cc3076781d2c25a11d684 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 16 Sep 2011 15:13:22 +0800 Subject: [PATCH] tcp: Allow per-tcpcb keepidle - Add t_keepidle to tcpcb, it is initialized to tcp_keepidle - The accepted socket's t_keepidle is inherited from the listen socket - Add IPPROTO_TCP/TCP_KEEPIDLE socket option to get and set t_keepidle. The unit is milliseconds, which is as same as the unit of the sysctl node net.inet.tcp.keepidle --- sys/netinet/tcp.h | 1 + sys/netinet/tcp_subr.c | 1 + sys/netinet/tcp_syncache.c | 1 + sys/netinet/tcp_timer2.h | 2 +- sys/netinet/tcp_usrreq.c | 11 +++++++++++ sys/netinet/tcp_var.h | 2 ++ 6 files changed, 17 insertions(+), 1 deletion(-) diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h index a158a8ba61..08bd7450e8 100644 --- a/sys/netinet/tcp.h +++ b/sys/netinet/tcp.h @@ -163,5 +163,6 @@ struct tcphdr { #define TCP_KEEPINIT 0x20 /* 0x40 unused */ #define TCP_FASTKEEP 0x80 +#define TCP_KEEPIDLE 0x100 #endif diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 38335c8916..112536299c 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -695,6 +695,7 @@ tcp_newtcpcb(struct inpcb *inp) bzero(tp->tt_msg, sizeof(*tp->tt_msg)); tp->t_keepinit = tcp_keepinit; + tp->t_keepidle = tcp_keepidle; if (tcp_do_rfc1323) tp->t_flags = (TF_REQ_SCALE | TF_REQ_TSTMP); diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 25d38c1a6f..f6f44a65fc 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -864,6 +864,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) */ ltp = intotcpcb(linp); tp->t_keepinit = ltp->t_keepinit; + tp->t_keepidle = ltp->t_keepidle; tcp_create_timermsg(tp, port); tcp_callout_reset(tp, tp->tt_keep, tp->t_keepinit, tcp_timer_keep); diff --git a/sys/netinet/tcp_timer2.h b/sys/netinet/tcp_timer2.h index 2ac650108b..29bbd534ef 100644 --- a/sys/netinet/tcp_timer2.h +++ b/sys/netinet/tcp_timer2.h @@ -74,7 +74,7 @@ tcp_getkeepidle(struct tcpcb *_tp) if (_tp->t_flags & TF_FASTKEEP) return (tcp_keepintvl); else - return (tcp_keepidle); + return (_tp->t_keepidle); } static __inline void diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 0f0e5c273b..5f930f44c0 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1429,6 +1429,14 @@ tcp_ctloutput(netmsg_t msg) error = EINVAL; break; + case TCP_KEEPIDLE: + opthz = ((int64_t)optval * hz) / 1000; + if (opthz >= 1) + tp->t_keepidle = opthz; + else + error = EINVAL; + break; + default: error = ENOPROTOOPT; break; @@ -1457,6 +1465,9 @@ tcp_ctloutput(netmsg_t msg) case TCP_KEEPINIT: optval = ((int64_t)tp->t_keepinit * 1000) / hz; break; + case TCP_KEEPIDLE: + optval = ((int64_t)tp->t_keepidle * 1000) / hz; + break; default: error = ENOPROTOOPT; break; diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index e2031a5b57..e271d29ced 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -271,6 +271,8 @@ struct tcpcb { int rfbuf_cnt; /* recv buffer autoscaling byte count */ int t_keepinit; + + int t_keepidle; }; #define IN_FASTRECOVERY(tp) (tp->t_flags & TF_FASTRECOVERY) -- 2.41.0