设为首页 加入收藏

TOP

TCP timestamp 相关知识
2017-04-26 10:22:52 】 浏览:365
Tags:TCP timestamp 相关 知识

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


这是一篇介绍针对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的本质是记录数据包的发送时间。基本的步骤如下


当然实际运用中要考虑到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,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机制提供的信息依据。


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


RTTM规定了一些使用TSecr计算RTT的原则,具体如下
(英文水平有限,为保持原意就使用RFC中的原话了)


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


最后,实际上计算RTO除了以上使用TSecr的原则外,还有一些更复杂的计算方法RFC 7323
比如对于每一个RTT采样R,


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中进一步详细介绍。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇JavaScript中类式继承和原型式继.. 下一篇卷积神经网络深度理解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目