linux的tcp时间戳,TCP timestamp 相关知识

tcp_timestamps是在RFC 1323中定义的一个TCP选项。这篇wiki介绍一下timestamps的设计目的和相关原理,尤其强调一些比较tricky的地方。

关于RFC1323

这是一篇介绍针对High-bandwidth, Long delay链路设计的一些TCP扩展选项的资料。强烈推荐阅读!

但这篇RFC其实已经被RFC7323所取代,不过RFC1323对于了解timestamp相关的基本概念来说还是足够了的。关于RFC7323也会在后续的wiki中详细的介绍。

High-bandiwidth, Long delay链路面临的性能问题

上一句话强调”主要”是因为tcp_timestamp还被用于PAWS机制,而这一重要用途却时常被忽略。作为一个可靠的传输协议,TCP除了考虑如何应对性能问题,还需要考虑可靠性问题。即使这些问题发生的概率较低,PAWS就是其中一个例子。PAWS(Protect Against Wrapped Sequence numbers)一句话解释如下,后面会详细介绍

补充一句:什么用wrapped形容序列号被重复使用?因为压圈了呀 :)

tcp_timestamps 的设计

tcp_timestamps的本质是记录数据包的发送时间。基本的步骤如下

当然实际运用中要考虑到RTT的波动,因此有了后续的(Round-Trip Time Measurement)RTTM机制

TCP Timestamps Option (TSopt)具体设计如下

timestamps一个双向的选项,当一方不开启时,两方都将停用timestamps。

比如client端发送的SYN包中带有timestamp选项,但server端并没有开启该选项。

则回复的SYN-ACK将不带timestamp选项,同时client后续回复的ACK也不会带有timestamp选项。

当然,如果client发送的SYN包中就不带timestamp,双向都将停用timestamp。

为什么需要timestamp

如果没有timestamp,RTT的计算会怎样?

但上面的机制在丢包发生时会有问题,比如

但是RTT应该是 (recv_time - send_time1)呢,还是(recv_time - send_time2)呢?

以上两种方式都不可取!因为无法判断出recv_time对应的ACK是确认第一次数据包的发送还是确认

重传数据包。因此TCP协议栈只能选择非重传数据包进行RTT采样。但是当出现严重丢包(比如整个窗口全部丢失)时,就完全没有数据包可以用于RTT采样。这样后续计算SRTT和RTO就会出现较大的偏差。

timestamp选项很好的解决了上述问题,因为ACK包里面带的TSecr值,一定是触发这个ACK的数据包在发送端发送的时间。不管数据包是否重传都能准确的计算RTT(前提是TSecr遵循RTTM中的计算原则)。

当然timestamp不仅解决了RTT计算的问题,还很好的为PAWS机制提供的信息依据。

开启timestamp会有什么负面影响?

这部分内容以后会根据更多的实际经验来补充。目前列举一些找到的分析。

什么是RTTM

RTTM规定了一些使用TSecr计算RTT的原则,具体如下

(英文水平有限,为保持原意就使用RFC中的原话了)

如果对以上的特殊情况有疑问,还请直接去看RFC,里面有example解释。

最后,实际上计算RTO除了以上使用TSecr的原则外,还有一些更复杂的计算方法RFC 7323。

比如对于每一个RTT采样R,

什么是PAWS

PAWS — Protect Againest Wrapped Sequence numbers

目的是解决在高带宽下,TCP序号可能被重复使用而带来的问题。

PAWS同样依赖于timestamp,并且假设在一个TCP流中,按序收到的所有TCP包的timestamp值

都是线性递增的。而在正常情况下,每条TCP流按序发送的数据包所带的timestamp值

也确实是线性增加的。

至于为什么要强调按序,请先自行思考。:)

首先给出几个变量的定义,之后具体介绍PAWS的工作过程

TS.Recent存放着按序达到的所有TCP数据包的最晚的一个时间戳,即只有在SEG.SEQ <= Last.ACK.sent < SEG.SEG + SEG.LEN(有新的数据被按序确认了)时,才会去更新TS.Recent的值。

PAWS的更多细节

从第三点可以看到,如果针对per-host的使用PAWS中的机制,则会解决TIME-WAIT中考虑的上一个流的数据包在下一条流中被当做有效数据包的情况,这样就没有必要等待2*MSL来结束TIME-WAIT了。只要等待足够的RTO,解决好需要重传最后一个ACK的情况就可以了。因此Linux就实现了这样一种机制:

但这样真的就能完美的解决令无数人头疼的TIME-WAIT吗?答案是否定的!因为公网中存在太多的NAT设置,当使用per-host的PAWS机制时,是无法保证timestamp是线性递增这一假设的。因为使用同一个NAT地址的两个真实的机器,他们的timestamp是不能保证同步的(其实一致也没有用,NAT就是per-host PAWS机制的死敌)。关于这个问题也会在以后的一篇介绍TIME-WAIT的wiki中进一步详细介绍。

总结

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值