1.Timestamps 选项的组成部分

Timestamp时分秒设置为0 timestamps_时间戳


时间戳选项占10个字节= kind(1字节) + length(1字节) + info (8字节),其中kind=8,length=10,info由timestamp(TS value)和timestamp echo(TS Echo Reply)两个值组成,各4个字节的长度。

2. Timestamps 选项工作原理

以一次抓包为例:

Timestamp时分秒设置为0 timestamps_时间戳_02

  1. 发送方发送数据时,将一个发送时间戳 1590508660 放在发送方时间戳TSval中
  2. 接收方收到数据包以后,将收到的时间戳 1590508660 原封不动的返回给发送方,放在TSecr字段中,同时把自己的时间戳 1499872733 放在TSval中

3. Timestamps 选项的作用

时间戳选项主要的功能有两个

3.1 用来计算往返时间RTT。

发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段值复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确计算出RTT。时间戳是一个单调增长的值,接收方只需要回显收到的内容,因此是不需要关注时间戳的单元是什么,也不需要连接双发的时钟同步。

Timestamp时分秒设置为0 timestamps_时间戳_03


例如:主机a向主机b发送一个报文s1,在发送时将内核时刻ta1记录到报文s1的选项字段时间戳timestamp区域;主机b接收到报文s1后,从s1的时间戳timestamp区域将ta1取出来,复制到应答报文s2的时间戳timestampecho区域。如此一来,主机a收到s2时,此时的内核时刻是ta2,那么RTT = ta2 - ta1。这在一定程度上就能反映网络的拥堵情况了。

为什么需要用Timestamps计算RTT

TCP 在发送一个包时,会记录这个包的发送的时间 t1,用收到这个包的确认包时 t2 减去 t1 就可以得到这次的 RTT。这里有一个问题,如果发出的包出现重传,计算就变得复杂起来。无法得知收到的确认 ACK 是对第一次包还是重传包的的确认

Timestamp时分秒设置为0 timestamps_网络协议_04

3.2 PAWS:防止回绕的序号。

我们知道序列号只有32位,而每增加2^32个序列号后就会重复使用原来用过的序列号。假设我们有一条高速网络,通信的主机双方有足够大的带宽用来快速的传输数据。例如1Gb/s(TCP 的窗口经过窗口缩放可以最高到 1GB(2^30))的速率发送报文段,则不到35秒钟数据字节的序列号就会重复。这样对TCP传输带来混乱的情况。这种情况之出现在高速链路上。而采用时间戳选项,可以很容易的分辨出相同序列号的数据报,哪个是最近发送,哪个是以前发送的。

4. Timestamps 选项在三次握手中造成的RST

三次握手中的第二步,如果服务端回复 SYN+ACK 包中的 TSecr 不等于握手第一步客户端发送 SYN 包中的 TSval,客户端在对 SYN+ACK 回复 RST。示例包如下所示。

Timestamp时分秒设置为0 timestamps_网络_05

5.使用Timestamps 选项的注意事项

  • Timestamps是双向的,必须双方都开启才有效
  • Timestamps也会溢出回绕
  • timestamps 值是一个单调递增的值,但是两端 timestamps 值增加的间隔也可能步调不一致