tcp: Allow per-tcpcb keepidle
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 16 Sep 2011 07:13:22 +0000 (15:13 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 16 Sep 2011 07:13:22 +0000 (15:13 +0800)
- 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
sys/netinet/tcp_subr.c
sys/netinet/tcp_syncache.c
sys/netinet/tcp_timer2.h
sys/netinet/tcp_usrreq.c
sys/netinet/tcp_var.h

index a158a8b..08bd745 100644 (file)
@@ -163,5 +163,6 @@ struct tcphdr {
 #define TCP_KEEPINIT   0x20
 /* 0x40 unused */
 #define TCP_FASTKEEP   0x80
+#define TCP_KEEPIDLE   0x100
 
 #endif
index 38335c8..1125362 100644 (file)
@@ -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);
index 25d38c1..f6f44a6 100644 (file)
@@ -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);
index 2ac6501..29bbd53 100644 (file)
@@ -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
index 0f0e5c2..5f930f4 100644 (file)
@@ -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;
index e2031a5..e271d29 100644 (file)
@@ -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)