当前位置: 首页 > news >正文

SYN 报文什么时候情况下会被丢弃?

之前有个读者在秋招面试的时候,被问了这么一个问题:SYN 报文什么时候情况下会被丢弃?

好家伙,现在面试都问那么细节了吗?

不过话说回来,这个问题跟工作上也是有关系的,因为我就在工作中碰到这么奇怪的问题。

客户端向服务端发起了连接,但是连接并没有建立起来,通过抓包分析发现,服务端是收到 SYN 报文了,但是并没有回复 SYN+ACK(TCP 第二次握手),说明 SYN 报文被服务端忽略了,然后客户端就一直在超时重传 SYN 报文,直到达到最大的重传次数。

接下来,我就给出我遇到过 SYN 报文被丢弃的两种场景:

  • 开启 tcp_tw_recycle 参数,并且在 NAT 环境下,造成 SYN 报文被丢弃

  • accpet 队列满了,造成 SYN 报文被丢弃

坑爹的 tcp_tw_recycle

TCP 四次挥手过程中,主动断开连接方会有一个 TIME_WAIT 的状态,这个状态会持续 2 MSL 后才会转变为 CLOSED 状态。

在 Linux 操作系统下,TIME_WAIT 状态的持续时间是 60 秒,这意味着这 60 秒内,客户端一直会占用着这个端口。要知道,端口资源也是有限的,一般可以开启的端口为 32768~61000 ,也可以通过如下参数设置指定范围:

net.ipv4.ip_local_port_range

那么,如果如果主动断开连接方的 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接。

但是 TIME_WAIT 状态也不是摆设作用,它的作用有两个:

  • 防止具有相同四元组的旧数据包被收到,也就是防止历史连接中的数据,被后面的连接接受,否则就会导致后面的连接收到一个无效的数据,

  • 保证「被动关闭连接」的一方能被正确的关闭,即保证最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭;

不过,Linux 操作系统提供了两个可以系统参数来快速回收处于 TIME_WAIT 状态的连接,这两个参数都是默认关闭的:

  • net.ipv4.tcp_tw_reuse,如果开启该选项的话,客户端(连接发起方) 在调用 connect() 函数时,内核会随机找一个 time_wait 状态超过 1 秒的连接给新的连接复用,所以该选项只适用于连接发起方。

  • net.ipv4.tcp_tw_recycle,如果开启该选项的话,允许处于 TIME_WAIT 状态的连接被快速回收;

要使得这两个选项生效,有一个前提条件,就是要打开 TCP 时间戳,即 net.ipv4.tcp_timestamps=1(默认即为 1)。

但是,tcp_tw_recycle 在使用了 NAT 的网络下是不安全的!

对于服务器来说,如果同时开启了 recycle 和 timestamps 选项,则会开启一种称之为「per-host 的 PAWS 机制」。

首先给大家说说什么是 PAWS 机制?

tcp_timestamps 选项开启之后, PAWS 机制会自动开启,它的作用是防止 TCP 包中的序列号发生绕回。

正常来说每个 TCP 包都会有自己唯一的 SEQ,出现 TCP 数据包重传的时候会复用 SEQ 号,这样接收方能通过 SEQ 号来判断数据包的唯一性,也能在重复收到某个数据包的时候判断数据是不是重传的。但是 TCP 这个 SEQ 号是有限的,一共 32 bit,SEQ 开始是递增,溢出之后从 0 开始再次依次递增

所以当 SEQ 号出现溢出后单纯通过 SEQ 号无法标识数据包的唯一性,某个数据包延迟或因重发而延迟时可能导致连接传递的数据被破坏,比如:

上图 A 数据包出现了重传,并在 SEQ 号耗尽再次从 A 递增时,第一次发的 A 数据包延迟到达了 Server,这种情况下如果没有别的机制来保证,Server 会认为延迟到达的 A 数据包是正确的而接收,反而是将正常的第三次发的 SEQ 为 A 的数据包丢弃,造成数据传输错误。

PAWS 就是为了避免这个问题而产生的,在开启 tcp_timestamps 选项情况下,一台机器发的所有 TCP 包都会带上发送时的时间戳,PAWS 要求连接双方维护最近一次收到的数据包的时间戳(Recent TSval),每收到一个新数据包都会读取数据包中的时间戳值跟 Recent TSval 值做比较,如果发现收到的数据包中时间戳不是递增的,则表示该数据包是过期的,就会直接丢弃这个数据包

对于上面图中的例子有了 PAWS 机制就能做到在收到 Delay 到达的 A 号数据包时,识别出它是个过期的数据包而将其丢掉。

那什么是 per-host 的 PAWS 机制呢?

前面我提到,开启了 recycle 和 timestamps 选项,就会开启一种叫 per-host 的 PAWS 机制。

per-host 是对「对端 IP 做 PAWS 检查」,而非对「IP + 端口」四元组做 PAWS 检查。

但是如果客户端网络环境是用了 NAT 网关,那么客户端环境的每一台机器通过 NAT 网关后,都会是相同的 IP 地址,在服务端看来,就好像只是在跟一个客户端打交道一样,无法区分出来。

Per-host PAWS 机制利用TCP option里的 timestamp 字段的增长来判断串扰数据,而 timestamp 是根据客户端各自的 CPU tick 得出的值。

当客户端 A 通过 NAT 网关和服务器建立 TCP 连接,然后服务器主动关闭并且快速回收 TIME-WAIT 状态的连接后,客户端 B 也通过 NAT 网关和服务器建立 TCP 连接,注意客户端 A 和 客户端 B 因为经过相同的 NAT 网关,所以是用相同的 IP 地址与服务端建立 TCP 连接,如果客户端 B 的 timestamp 比 客户端 A 的 timestamp 小,那么由于服务端的 per-host 的 PAWS 机制的作用,服务端就会丢弃客户端主机 B 发来的 SYN 包

因此,tcp_tw_recycle 在使用了 NAT 的网络下是存在问题的,如果它是对 TCP 四元组做 PAWS 检查,而不是对「相同的 IP 做 PAWS 检查」,那么就不会存在这个问题了。

网上很多博客都说开启 tcp_tw_recycle 参数来优化 TCP,我信你个鬼,糟老头坏的很!

tcp_tw_recycle 在 Linux 4.12 版本后,直接取消了这一参数。

accpet 队列满了

在 TCP 三次握手的时候,Linux 内核会维护两个队列,分别是:

  • 半连接队列,也称 SYN 队列;

  • 全连接队列,也称 accepet 队列;

服务端收到客户端发起的 SYN 请求后,内核会把该连接存储到半连接队列,并向客户端响应 SYN+ACK,接着客户端会返回 ACK,服务端收到第三次握手的 ACK 后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到 accept 队列,等待进程调用 accept 函数时把连接取出来。

图片

在服务端并发处理大量请求时,如果 TCP accpet 队列过小,或者应用程序调用 accept() 不及时,就会造成 accpet 队列满了 ,这时后续的连接就会被丢弃,这样就会出现服务端请求数量上不去的现象。

我们可以通过 ss 命令来看 accpet 队列大小,在「LISTEN 状态」时,Recv-Q/Send-Q表示的含义如下:

  • Recv-Q:当前 accpet 队列的大小,也就是当前已完成三次握手并等待服务端accept()的 TCP 连接个数;

  • Send-Q:当前 accpet 最大队列长度,上面的输出结果说明监听 8088 端口的 TCP 服务进程,accpet 队列的最大长度为 128;

如果 Recv-Q 的大小超过 Send-Q,就说明发生了 accpet 队列满的情况。

要解决这个问题,我们可以:

  • 调大 accpet 队列的最大长度,调大的方式是通过调大 backlog 以及 somaxconn 参数。

  • 检查系统或者代码为什么调用 accept() 不及时;

http://www.jsqmd.com/news/411768/

相关文章:

  • 2026年 垃圾中转站厂家推荐排行榜,压缩式/小区/生活/农村/垃圾分类/地下地埋式/大型/垂直式垃圾中转站,环保高效解决方案精选 - 品牌企业推荐师(官方)
  • 有经验的品牌战略咨询公司:20年深耕+300+品牌操盘(案例详解) - 速递信息
  • 小白救星!更贴合自考的降AI率网站 千笔·降AI率助手 VS PaperRed
  • 论文解读-《Oversquashing in GNNs through the lens of information contraction and graph expansion》 - zhang
  • 2026年入手高端珠宝前,你需要了解的这些事,高端日常佩戴珠宝/东方高端珠宝/东方美学珠宝/东方秩序,高端珠宝品牌有哪些 - 品牌推荐师
  • 青少年英语培训班怎么选?2026优选少儿英语培训机构推荐 - 品牌2025
  • C++的类型语义
  • 2026年AI PPT生成工具终极排行榜:ChatPPT稳居榜首,谁是效率之王?
  • 2026年靠谱的京东e卡转让,京东e卡回收,收京东e卡公司行业实力榜单 - 品牌鉴赏师
  • 导师推荐! 降AI率网站 千笔·降AIGC助手 VS 文途AI,继续教育首选
  • Docker Kubernetes 命令对标
  • 瑞祥商联卡怎么提现到微信?2026三款合规渠道实测分享 - 京回收小程序
  • 2026年 泵管配件厂家推荐排行榜:泵管管卡/泵管胶圈/泵管法兰/臂架管/混凝土泵管,耐磨耐压工业优选 - 品牌企业推荐师(官方)
  • 揭开自闭症康复机构的神秘面纱:为“星星的孩子”照亮前路 - 品牌测评鉴赏家
  • 2026年混凝土布料机厂家实力推荐榜:圆桶/移动式/液压/手动/电动/隧道/行走布料机,高效施工与耐用品质深度解析 - 品牌企业推荐师(官方)
  • 2026全屋整装管理系统优质厂家推荐榜 - 优质品牌商家
  • 2026年环卫车厂家推荐排行榜:环卫垃圾车/环卫清扫车/电动环卫车/压缩环卫车/小型环卫车,专业制造与高效清洁解决方案深度解析 - 品牌企业推荐师(官方)
  • 植物大战僵尸修改器2026最新下载教程:从入门到精通,轻松解锁无限阳光 - PC修复电脑医生
  • 宣城市气象局|搭贝助力,以高效任务管理筑牢防灾减灾防线 - 搭贝
  • Java摄影预约:让拍摄时光精准又美好
  • 少儿英语培训机构怎么选?六大少儿英语培训机构推荐 - 品牌2025
  • AI春晚引爆全民智能浪潮
  • 用httpsrv极速构建轻量HTTP服务器
  • 学霸同款AI论文工具,千笔·专业论文写作工具 VS 锐智 AI,研究生高效写作首选!
  • 手机租赁小程序开发:打造便捷高效的前端功能体验
  • 基差风险管理系统权限粒度配置实践
  • 2026有机管式膜行业洞察:工业水处理场景下技术迭代与市场格局分析
  • 前端工程师用 XinServer 打造完整后台管理系统
  • 期现对冲交易系统多类型合同管理方案
  • 产品经理如何应对需求变更?我用一款甘特图工具实现了零扯皮