From: Sepherosa Ziehau Date: Fri, 16 Sep 2011 06:41:13 +0000 (+0800) Subject: tcp: Allow per-tcpcb keepinit X-Git-Tag: v2.12.0~45 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/2ce132be322fc58a7e8320d2aed64a717c8620b3 tcp: Allow per-tcpcb keepinit - Add t_keepinit to tcpcb, it is initialized to tcp_keepinit - The accepted socket's t_keepinit is inherited from the listen socket - Add IPPROTO_TCP/TCP_KEEPINIT socket option to get and set t_keepinit. The unit is milliseconds, which is as same as the unit of the sysctl node net.inet.tcp.keepinit --- diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h index 980b8636af..a158a8ba61 100644 --- a/sys/netinet/tcp.h +++ b/sys/netinet/tcp.h @@ -160,6 +160,8 @@ struct tcphdr { #define TCP_NOPUSH 0x04 /* don't push last block of write */ #define TCP_NOOPT 0x08 /* don't use TCP options */ #define TCP_SIGNATURE_ENABLE 0x10 /* use MD5 digests (RFC2385) */ +#define TCP_KEEPINIT 0x20 +/* 0x40 unused */ #define TCP_FASTKEEP 0x80 #endif diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index c47ca05e59..38335c8916 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -694,6 +694,8 @@ tcp_newtcpcb(struct inpcb *inp) tp->tt_msg = &it->inp_tp_timermsg; bzero(tp->tt_msg, sizeof(*tp->tt_msg)); + tp->t_keepinit = tcp_keepinit; + if (tcp_do_rfc1323) tp->t_flags = (TF_REQ_SCALE | TF_REQ_TSTMP); tp->t_inpcb = inp; /* XXX */ diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 058a1966d8..25d38c1a6f 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -679,7 +679,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) { struct inpcb *inp = NULL, *linp; struct socket *so; - struct tcpcb *tp; + struct tcpcb *tp, *ltp; lwkt_port_t port; #ifdef INET6 const boolean_t isipv6 = sc->sc_inc.inc_isipv6; @@ -858,8 +858,15 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) */ if (sc->sc_rxtslot != 0) tp->snd_cwnd = tp->t_maxseg; + + /* + * Inherit some properties from the listen socket + */ + ltp = intotcpcb(linp); + tp->t_keepinit = ltp->t_keepinit; + tcp_create_timermsg(tp, port); - tcp_callout_reset(tp, tp->tt_keep, tcp_keepinit, tcp_timer_keep); + tcp_callout_reset(tp, tp->tt_keep, tp->t_keepinit, tcp_timer_keep); tcpstat.tcps_accepts++; return (so); diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 11bc5b30d9..0f0e5c273b 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1007,7 +1007,7 @@ tcp_connect_oncpu(struct tcpcb *tp, int flags, struct mbuf *m, soisconnecting(so); tcpstat.tcps_connattempt++; tp->t_state = TCPS_SYN_SENT; - tcp_callout_reset(tp, tp->tt_keep, tcp_keepinit, tcp_timer_keep); + tcp_callout_reset(tp, tp->tt_keep, tp->t_keepinit, tcp_timer_keep); tp->iss = tcp_new_isn(tp); tcp_sendseqinit(tp); if (m) { @@ -1289,7 +1289,7 @@ tcp6_connect_oncpu(struct tcpcb *tp, int flags, struct mbuf **mp, soisconnecting(so); tcpstat.tcps_connattempt++; tp->t_state = TCPS_SYN_SENT; - tcp_callout_reset(tp, tp->tt_keep, tcp_keepinit, tcp_timer_keep); + tcp_callout_reset(tp, tp->tt_keep, tp->t_keepinit, tcp_timer_keep); tp->iss = tcp_new_isn(tp); tcp_sendseqinit(tp); if (m) { @@ -1324,7 +1324,7 @@ tcp_ctloutput(netmsg_t msg) { struct socket *so = msg->base.nm_so; struct sockopt *sopt = msg->ctloutput.nm_sopt; - int error, opt, optval; + int error, opt, optval, opthz; struct inpcb *inp; struct tcpcb *tp; @@ -1421,6 +1421,14 @@ tcp_ctloutput(netmsg_t msg) } break; + case TCP_KEEPINIT: + opthz = ((int64_t)optval * hz) / 1000; + if (opthz >= 1) + tp->t_keepinit = opthz; + else + error = EINVAL; + break; + default: error = ENOPROTOOPT; break; @@ -1446,6 +1454,9 @@ tcp_ctloutput(netmsg_t msg) case TCP_NOPUSH: optval = tp->t_flags & TF_NOPUSH; break; + case TCP_KEEPINIT: + optval = ((int64_t)tp->t_keepinit * 1000) / hz; + break; default: error = ENOPROTOOPT; break; diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index d196eee4fd..e2031a5b57 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -269,6 +269,8 @@ struct tcpcb { u_int32_t rfbuf_ts; /* recv buffer autoscaling timestamp */ int rfbuf_cnt; /* recv buffer autoscaling byte count */ + + int t_keepinit; }; #define IN_FASTRECOVERY(tp) (tp->t_flags & TF_FASTRECOVERY)