vxworks上的tcp keepalive

4030阅读 0评论2012-02-13 areece
分类:BSD

最近由于要在产品上使能TCP的keepalive功能,接合TCPIP详解V2,看了一下它的实现。实现的代码主要集中在tcp_timer_keep()函数中。主要的代码如下:

  1.     delta = TICKS - tp->t_rcvtime;
  2.     keeptime = tcp_keepidle;

  3.     if (delta < (ULONG)keeptime) {
  4.         keeptime = keeptime - delta;
  5.         goto out;
  6.     }

  7.     if ((priv_always_keepalive ||
  8.      tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) &&
  9.      tp->t_state <= TCPS_CLOSING) {
  10.         if (delta >= tcp_keepidle + tcp_maxidle)
  11.             goto dropit;

  12.         tcpStat.tcps_keepprobe++;

  13.         templateMbuf = tcp_maketemplate (tp);
  14.         if (templateMbuf != NULL)
  15.          t_template = mtod (templateMbuf, struct tcptemp *);
  16.         if (t_template) {
  17.             tcp_respond(tp, t_template->tt_ipgen,
  18.                  &t_template->tt_t, (struct mbuf *)NULL,
  19.                  tp->rcv_nxt, tp->snd_una - 1, 0);
  20.             m_free (templateMbuf);
  21.         }

  22.         keeptime = tcp_keepintvl;
  23.     }

  24.     callout_reset(tp->tt_keep, keeptime, tcp_timer_keep, tp);
  25.     splx(s);

代码简介:对于已经建立的连接,tcp_keepidle时间运行一次keepalive的检查(全局keepalive打开或者socket上的keepalive打开),如果idle的时间超过tcp_keepidle就会发送keepalive的probe消息,如果tcp_keepidle+tcp_maxidle时间还没有接收到数据,则关闭连接)。tcp_maxidle是按照tcp_keepintvl发送包,一连9个包,都没有收到响应的时间。上面代码中delta就是实际的idle时间。

probe包的方式是给对方发送序列号落在对方接收窗口之外的tp->snd_una-1的0长度数据包,导致对方肯定要回答一个ACK(如果连接还活着)或者RST(如果对方已经复位过了)。

上一篇:[ppc] the instruction at 0xfffffffc
下一篇:nagle算法的意义