Chinaunix首页 | 论坛 | 博客
  • 博客访问: 519005
  • 博文数量: 100
  • 博客积分: 2058
  • 博客等级: 大尉
  • 技术积分: 1029
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-14 23:29
文章分类
文章存档

2011年(94)

2010年(6)

分类: 网络与安全

2011-04-29 01:00:49


原文参考

TCP连接有很多定时器,其中一些与Keepalive有关。当这些定时器计数为0时,就会发送Keepalive探帧包(我记得在最早的BSD代码上该探帧包占一个序列号Sequence)。如果这些包没有得到对端的ACK回应,则可采取一定的控制策略,比如继续发送探帧包或认为对端已非正常中断连接。

Keepalive的用途主要有两个:检查对端是否死掉或者防止因网络无活动而连接中断。假设A和B建立了一个TCP连接,B突然死掉了,A会在一定时间后发送Keepalive探帧包,如果B重启后收到了探帧包,因TCP套接字对不上或TCP序列号对不上,会导致B给A发送RST包,此时连接马上中断。如果B一直没活过来,则发送一定数量的探帧包后A认为连接中断。这是有效检查对端死掉的情况,还有一种情况是通过NAT或代理上网,如果A和B之间隔着NAT或代理,这些NAT或者代理通常有一定的连接超时控制,发现A和B在一段时间后没有交换数据,就会切断二者的通信,此时用Keepalive可避免这种情况。

Linux下控制Keepalive的参数有三个:

tcp_keepalive_time  在连接多长时间没有数据交换时发送探帧包
tcp_keepalive_intvl 发送下一个探帧包距离发送本次探帧包的时间间隔
tcp_keepalive_probes 发送多少次没有回应的探帧包后认为对端死掉

对应在proc文件系统的位置是

/proc/sys/net/ipv4/tcp_keepalive_time
/proc/sys/net/ipv4/tcp_keepalive_intvl
/proc/sys/net/ipv4/tcp_keepalive_probes

注意:仅仅配置内核参数是不够的,还必须在编程的时候设置套接字的选项,调用函数是

int setsockopt(int s, int level, int optname,
                 const void *optval, socklen_t optlen)

选项为SO_KEEPALIVE,此外还可以设置TCP选项(设置的level为SOL_TCP而不是SOL_SOCKET)覆盖系统全局设置

TCP_KEEPCNT  与tcp_keepalive_probes对应
TCP_KEEPIDLE 与tcp_keepalive_time对应
TCP_KEEPINTVL 与tcp_keepalive_intvl对应

如果有些程序无法修改源码,可采用libkeepalive覆盖程序的socket调用,达到设置这些选项的目的,为socket调用提供覆盖的是ld的PRELOAD机制。假设待覆盖的程序为test,则

$ LD_PRELOAD=libkeepalive.so \
  KEEPCNT=20 \
  KEEPIDLE=180 \
  KEEPINTVL=60 \
  test

可修改test程序的socket选项。

关于libkeepalive项目可参考

阅读(3212) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~