微信号:jsj_xx

介绍:二十年IT领域工作经验的一线资深码农阐述对计算机技术的透彻理解!内容涵盖编程语言、操作系统内核(linux)及应用、网络、安全、通信设备、算法、机器学习等多个领域.

对系统调用listen的backlog参数的思考

2015-08-10 10:37

作者:新浪微博(@NP等不等于P)

计算机学习微信公众号(jsj_xx)

【温馨提示1:所有文章通过如上的微博号和微信公众号两种媒体同步发布,大家可以选择喜欢的媒体方式!】

【温馨提示2:如果使用微信阅读时有格式问题,请换用手机竖屏方式或电脑方式阅读】

【温馨提示3:请在历史消息里查看以往发送的技术文章】

【温馨提示4:指正交流或参与文章讨论,请评论给新浪微博(@NP等不等于P)】

listen系统调用里有个backlog的参数,本文就是对此参数展开的思考。

先看看unix的。

在《详解(卷二)》里提到,backlog是半连接队列和全连接队列两个队列的和的limit。这显然是混淆了两个队列的作用。freebsd最新几个版本我们发现,已经改为全连接队列的limit了:

if (head->so_qlen > 3 * head->so_qlimit / 2)

return ((struct socket *)0);

但是,如stevens说地那样,还是带有3/2这个奇怪的因子。

再来看linux的,先看man:

The behavior of the backlog argument on TCP sockets changed with Linux

2.2. Now it specifies the queue length for completely established

sockets waiting to be accepted, instead of the number of incomplete

connection requests. The maximum length of the queue for incomplete

sockets can be set using /proc/sys/net/ipv4/tcp_max_syn_backlog. When

syncookies are enabled there is no logical maximum length and this set‐

ting is ignored.

可见,这个参数从2.2版本开始改为全连接队列的limit。同时,半连接队列的limit改由tcp_max_syn_backlog来控制。

我们来思考下这个两个队列的limit存在的意义。(以下假设syncookie不使能)

两个队列是针对两种能力:一个是host服务器协议栈的处理能力,一个是对外界网络连接的处理能力。在全连接队列一直满的情况下,半连接队列里的会以很低的频率接受新的连接(大约0.67cps),而旧的连接也会以此频率增加。当然,最旧的连接会以更慢的频率老化掉。维持住旧的连接的方法是忽略client发来的第三次握手的ack,这样这个连接就会很暧昧地持久下去(反复来往syn+ack和ack),即使进入全连接队列的概率很小。这种机制的目的是保证全连接队列有空闲时,能迅速从半连接队列补充有效连接。

最后,我们考虑一个问题:服务器何时会丢syn包?(或者说放弃建立此连接)

有上文描述可知,即使全连接队列满了,还是可能接收syn并完成三次握手的,只是处于半连接队列备用着。一旦有机会就会补充到全连接队列里,从而被用户进程accept到。注意,这会在client侧出现established状态的假象。

同时,上述是不丢包的一种可能,也可能丢包:


可见,此时服务器负载过大,半连接队列的接收能力也需要伴随下降,只能丢包。

关于我们

新浪微博(@NP等不等于P)

计算机学习微信公众号(jsj_xx)

原创技术文章,感悟计算机,透彻理解计算机!

【计算机学习微信公众号:jsj_xx】

 
计算机学习 更多文章 CVE-2015-1635 理解c语言的sizeof 理解TCP协议的重传时间(上) 理解TCP协议的重传时间(下) 关于TCP重传超时时间的几个问题
猜您喜欢 我为什么选择iPhone,无视「安卓」? 互联网时代必备的"撩妹"技能,不会你就OUT啦 一炷香 —— 禅意计时 App SLI,SLO和SLA 大型网站的灵魂——性能