博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
再理解tcp backlog
阅读量:5909 次
发布时间:2019-06-19

本文共 1774 字,大约阅读时间需要 5 分钟。

最近读到一篇分析文章,其中有这样一段描述:

在linux 2.2以前,backlog大小包括了半连接状态和全连接状态两种队列大小。linux 2.2以后,分离为两个backlog来分别限制半连接SYN_RCVD状态的未完成连接队列大小跟全连接ESTABLISHED状态的已完成连接队列大小。互联网上常见的TCP SYN FLOOD恶意DOS攻击方式就是用/proc/sys/net/ipv4/tcp_max_syn_backlog来控制的,可参见《TCP洪水攻击(SYN Flood)的诊断和处理》。

在使用listen函数时,内核会根据传入参数的backlog跟系统配置参数/proc/sys/net/core/somaxconn中,二者取最小值,作为“ESTABLISHED状态之后,完成TCP连接,等待服务程序ACCEPT”的队列大小。在kernel 2.4.25之前,是写死在代码常量SOMAXCONN,默认值是128。在kernel 2.4.25之后,在配置文件/proc/sys/net/core/somaxconn (即 /etc/sysctl.conf 之类 )中可以修改。我稍微整理了流程图,如下:

回过头来看之前自己的一篇文章,发现有一段描述有误:

也就是说,backlog形容的是server在与客户端建立tcp连接的过程中,SYN队列的大小,在socket的listen接口中,一般第二个参数就是backlog的大小。

listen(socket, backlog)的两种实现方式

在一文中,作者给出了比较详细的分析:

  1. 第一种实现方式在底层维护一个由backlog指定大小的队列。服务端收到SYN后,返回一个SYN/ACK,并把连接放入队列中,此时这个连接的状态是SYN_RECEIVED。当客户端返回ACK后,此连接的状态变为ESTABLISHED。队列中只有ESTABLISHED状态的连接能够交由应用处理。第一种实现方式可以简单概括为:一个队列,两种状态。

  2. 第二种实现方式在底层维护一个SYN_RECEIVED队列和一个ESTABLISHED队列,当SYN_RECEIVED队列中的连接返回ACK后,将被移动到ESTABLISHED队列中。backlog指的是ESTABLISHED队列的大小。

传统的基于BSD的tcp实现第一种方式,在linux2.2之前,内核也实现第一种方式。当队列满了以后,服务端再收到SYN时,将不会返回SYN/ACK。比较优雅的处理方法就是不处理这条连接,不返回RST,让客户端重试。

在linux2.2后,选择第二种方式实现,SYN_RECEIVED队列的大小由proc/sys/net/ipv4/tcp_max_syn_backlog系统参数指定,ESTABLISHED队列由backlog和/proc/sys/net/core/somaxconn中较小的指定。

但是在windows server中,底层选择winsock API实现,backlog的定义是represents the maximum length of the queue of pending connections for the listener(这是一个比较模糊的定义……来源于BSD),当队列满了后,将会返回RST。

if (ESTABLISHED is full) {SYN.req -> ESTABLISHED?}

考虑这样一种情况,当ESTABLISHED队列满了,此时收到一个连接的ACK,需要将此连接从SYN队列移到ESTABLISHED队列中,会发生什么?

linux底层的关键代码是:

1
2
3
4
5
listen_overflow:
if (!sysctl_tcp_abort_on_overflow) {
inet_rsk(req)->acked =
1;
return NULL;
}

除非系统的tcp_abort_on_overflow指定为1(将返回RST),否则底层将不会做任何事情……这是一种委婉的退让策略,在服务端处理不过来时,让客户端误以为ACK丢失,继续重新发送ACK。这样,当服务端的处理能力恢复时,这条连接又可以重新被移动到ESTABLISHED队列中去。

参考

转载地址:http://pkvpx.baihongyu.com/

你可能感兴趣的文章
CF 311C Fetch the Treasure
查看>>
多线程互斥-读写者问题
查看>>
29 GameProject4(+GUI)
查看>>
安全专家称不再向厂商免费提供漏洞信息
查看>>
Android 编译重要参数 LOCAL_MODULE_TAGS
查看>>
黄聪:Destoon模板存放及调用规则
查看>>
【转】VIRTUALBOX导入已有.VDI文件步骤
查看>>
[深入浅出Windows 10]模拟实现微信的彩蛋动画
查看>>
windows dos命令大全
查看>>
Hadoop使用(一)
查看>>
PostSharp AOP编程:1.基于PostSharp的AOP日志记录和异常捕捉【附带源码】
查看>>
【转载】iphone[Three20] Three20系列之Three20概述
查看>>
jquery消息框插件jquery-toastmessage
查看>>
Android中实现滑动翻页—使用ViewFlipper(dp和px之间进行转换)
查看>>
永无止境 Limitless
查看>>
AutoCAD.NET API 最新2012教程下载及在线视频教程DevTV 目录(英文版)
查看>>
Android adb 命令图解
查看>>
HDU-1789 Doing Homework again 动态规划 Or 贪心
查看>>
LINUX任务(jobs)详解 (转)
查看>>
分享14个jQuery插件开发人员易犯的错误
查看>>