tcp: Allow per-tcpcb keepinit
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 16 Sep 2011 06:41:13 +0000 (14:41 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 16 Sep 2011 06:41:13 +0000 (14:41 +0800)
- 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

sys/netinet/tcp.h
sys/netinet/tcp_subr.c
sys/netinet/tcp_syncache.c
sys/netinet/tcp_usrreq.c
sys/netinet/tcp_var.h

index 980b863..a158a8b 100644 (file)
@@ -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
index c47ca05..38335c8 100644 (file)
@@ -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 */
index 058a196..25d38c1 100644 (file)
@@ -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);
index 11bc5b3..0f0e5c2 100644 (file)
@@ -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;
index d196eee..e2031a5 100644 (file)
@@ -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)