SYN 和 RTO

转自:https://huoding.com/2017/08/13/628

前两天,我在微博上推荐了一篇朝花夕拾的文章:The story of one latency spike,文章中介绍了 cloudflare 工程师如何一步一步 debug 网络延迟问题,细细读来受益良多,不过我并不打算详细介绍那篇文章的细枝末节, 本文只摘录一个点:

When debugging network problems the delays of 1s, 30s are very characteristic. They may indicate packet loss since the SYN packets are usually retransmitted at times 1s, 3s, 7s, 15, 31s.

为什么是 1 秒、3 秒、7 秒、15 秒、31 秒?说来惭愧,我以前从没有注意过 SYN 重建时的时间特征,知耻而后勇,正好借此机会来一探究竟。

下面让我们通过一个实验来重现一下 SYN 超时重传的现象:

  1. 在服务端屏蔽请求:「iptables -A INPUT –dport 1234 –syn -j DROP」
  2. 在服务端监听 1234 端口:「nc -l 1234」
  3. 在客户端开启抓包:「tcpdump -nn -i any port 1234」
  4. 在客户端发起请求:「date; nc <SERVER> 1234; date」

经过一段时间的等待后,我们可以看到 tcpdump 输出如下:

12:53:15.511826 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:16.511042 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:18.511058 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:22.511042 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:30.511065 IP CLIENT.53384 > SERVER.1234: Flags [S], ...
12:53:46.511068 IP CLIENT.53384 > SERVER.1234: Flags [S], ...

第一行是正常发出的 SYN,后面五行是超时重传发出的 SYN,相对于正常发出的 SYN,它们的延迟分别是:1 秒、3 秒、7 秒、15 秒、31 秒,正好符合开头的描述。之所以重传五次是因为 net.ipv4.tcp_syn_retries 的缺省值是 5。

此外,我们可以看到两次 date 命令输出的时间如下:

Sun Aug 13 12:53:15 CST 2017
Sun Aug 13 12:54:18 CST 2017

可见整个握手过程从开始到超时一共持续了 63 秒,其中 31 秒是总计五次 SYN 发送的时间,剩下的 32 秒是确认第五次 SYN 超时的时间(2 的 5 次方)。由此可见,在 TCP 握手阶段一旦出现丢包,网络延迟会非常久,很多时候这是没有必要的,比如 Web 服务器,可以考虑设置 net.ipv4.tcp_syn_retries 为 2 或者 3 比较合适。

如果要获取更为明确的证据,我们还需要了解 RTO(retransmission timeout),即超时重传时间,具体计算方法很复杂,我就不多说了,有兴趣的可以参考本文解决的推荐链接,你只要知道系统会根据网络连接的情况动态调整该值的大小即可。不过在 SYN 握手阶段,网络连接还没有建立起来,如果此时发生丢包,那么因为系统没有可以参照的 RTT(Round-Trip Time),所以此时只能给出系统缺省设置的 RTO:

#define TCP_RTO_MAX	((unsigned)(120*HZ))
#define TCP_RTO_MIN	((unsigned)(HZ/5))
#define TCP_TIMEOUT_INIT ((unsigned)(1*HZ))

...

unsigned long timeo;

if (req->num_timeout++ == 0)
    atomic_dec(&queue->young);
timeo = min(TCP_TIMEOUT_INIT << req->num_timeout, TCP_RTO_MAX);
mod_timer(&req->rsk_timer, jiffies + timeo);
return;

可见 RTO 的最大值是 120 秒,最小值是 200 毫秒,在连接建立前的初始值是 1 秒,如果经过多次重传,每次 RTO 的值翻倍,但最大不得超过 120 秒:

  1. 第 1 次重传:2 的 0 次方,也就是 1 秒(延迟:1 秒)。
  2. 第 2 次重传:2 的 1 次方,也就是 2 秒(延迟:1 + 2 = 3 秒)。
  3. 第 3 次重传:2 的 2 次方,也就是 4 秒(延迟:3 + 4 = 7 秒)。
  4. 第 4 次重传:2 的 3 次方,也就是 8 秒(延迟:7 + 8 = 15 秒)。
  5. 第 5 次重传:2 的 4 次方,也就是 16 秒(延迟:15 + 16 = 31 秒)。

顺便说一句,在建立连接后,因为目前大部分网络都很快,所以大部分连接的 RTO 都会接近 TCP_RTO_MIN,也就是 200ms,可以通过「ss -int」命令来确认。

时间: 2024-08-24 12:23:56

SYN 和 RTO的相关文章

分布式技术追踪 2017年第三十三期

分布式系统实践 1. 生活中的Paxos,原来你我都在使用--对Paxos生活化的解读 http://hedengcheng.com/?p=970 摘要: 很通俗的介绍Paxos的文章, 推荐大家看看. 2. 一文读懂Apache Kudu http://dwz.cn/6o5asK 摘要: 关于Kudu的文章之前也分享过, 这篇文章帮助大家回顾Kudu的设计思路和理念. 微服务技术 1. 为什么Google上十亿行代码都放在同一个仓库里? http://dwz.cn/6oy3SK 摘要: 相对于

TCP连接建立系列 — 客户端发送SYN段

主要内容:客户端调用connect()时的TCP层实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd connect的TCP层实现 SOCK_STREAM类socket的TCP层操作函数集实例为tcp_prot,其中客户端使用tcp_v4_connect()来发送SYN段. struct proto tcp_prot = { .name = "TCP", ... .connect = tcp_v4_connect, ... .h.has

linux系统收到SYN但不回SYN+ACK问题排查

一,背景: 今天下午发现线上的一台机器从办公网登录不上且所有tcp端口都telnet不通,但是通过同机房的其它机器却可以正常访问到出问题的机器.于是就立即在这台出问题的server端抓包分析,发现问题如下:server端收到了本地pc发的SYN包,但是没有回syn+ack包,所以确认是server端系统问题.tcpdump抓包如下: 二,排查 1,发现系统没有任何负载 2,网卡也没有丢包 3,iptables策略也都没问题 4,系统的SYN_RECV连接很少,也没超限 5,系统的文件描述符等资源

TCP的SYN队列和Accept队列

首先我们必须明白,处于“LISTENING”状态的TCP socket,有两个独立的队列: SYN队列(SYN Queue) Accept队列(Accept Queue) 这两个术语有时也被称为“reqsk_queue”,“ACK backlog”,“listen backlog”,甚至“TCP backlog”,但是这篇文章中我们使用上面两个术语以免造成混淆. SYN队列 SYN队列存储了收到SYN包的连接(对应内核代码的结构体:struct inet_request_sock).它的职责是回

awl多进程SYN攻击

一.TCP连接状态图 说明如下: 服务器端:LISTEN:侦听来自远方的TCP端口的连接请求 客户端:SYN-SENT:发送连接请求后等待匹配的连接请求 服务器端:SYN-RECEIVED:收到和发送一个连接请求后等待对方对连接请求的确认 客户端/服务器端:ESTABLISHED:代表一个打开的连接 客户端:FIN-WAIT-1:等待远程TCP连接中断请求,或先前的连接中断请求的确认 服务器端:CLOSE-WAIT:等待从本地用户发来的连接中断请求 客户端:FIN-WAIT-2:从远程TCP等待

SYN DDOS 防御策略

---恢复内容开始--- DDOS是分布式拒绝访问服务攻击,就是海量的向服务器发起request,而服务器难以区分这些request哪些是真实请求.只能都进行回应, 于是服务器的带宽被榨干,无法相应,使得正常的访问也被拒绝. SYN攻击的原理; SYN攻击主要利用的是TCP/IP协议 TCP三次握手的过程 client                                                         server SYN(SEQ=x)         =======

如何防御syn flood的一些思路!

厦门-志君同学21期群里疑问? syn flood是否无法防御 刚看到群里同学问问题,我还在讲课,利用间隙简单给大家点思路吧. 老男孩简单答疑如下: 1.先了解什么是SYN Flood? SYN Flood是一种DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽的攻击方式. 2.再了解tcp/ip的三次握手和四次断开过程原理 04-老男孩linux技术分享-OSI七层模型及协议-包封装解封装详解htt

扯谈网络编程之Tcp SYN flood洪水攻击

简介 TCP协议要经过三次握手才能建立连接: (from wiki) 于是出现了对于握手过程进行的攻击.攻击者发送大量的FIN包,服务器回应(SYN+ACK)包,但是攻击者不回应ACK包,这样的话,服务器不知道(SYN+ACK)是否发送成功,默认情况下会重试5次(tcp_syn_retries).这样的话,对于服务器的内存,带宽都有很大的消耗.攻击者如果处于公网,可以伪造IP的话,对于服务器就很难根据IP来判断攻击者,给防护带来很大的困难. 攻与防 攻击者角度 从攻击者的角度来看,有两个地方可以

【容灾】RTO和RPO

要建设容灾系统,就必须提出相应 的设计指标,以此作为衡量和选择容灾解决方案的参数. 目前,国际上通用的容灾系统的评审标准为Share 78,主要包括以下内容.  ●备份/恢复的范围  ●灾难恢复计划的状态  ●业务中心与容灾中心之间的距离  ●业务中心与容灾中心之间如何连接  ●数据是怎样在两个中心之间传送的  ●允许有多少数据丢失  ●保证更新的数据在容灾中心被更新  ●容灾中心可以开始容灾进程的能力  Share 78只是建立容灾系统的一种评审标准,在设计容灾系统时,还需要提供更加具体的设计