内核版本:3.2.12
本文主要剖析:RTT的测量、RTO的计算
作者:zhangskd @ csdn
概述
RTO(Retransmission TimeOut)即重传超时时间。
TCP超时与重传中一个很最重要的部分是对一个给定连接的往返时间(RTT)的测量。由于网络流量的变化,
这个时间会相应地发生改变,TCP需要跟踪这些变化并动态调整超时时间RTO。
RFC2988中是这样描述RTO的:
“The Transmission Control Protocol (TCP) uses a retransmission timer to ensure
data delivery in the absence of any feedback from the remote data receiver. The
duration of this timer is referred to as RTO (retransmission timeout).”
RTT(Round Trip Time)由三部分组成:链路的传播时间(propagation delay)、末端系统的处理时间、
路由器缓存中的排队和处理时间(queuing delay)。
其中,前两个部分的值对于一个TCP连接相对固定,路由器缓存中的排队和处理时间会随着整个网络拥塞程度
的变化而变化。所以RTT的变化在一定程度上反应了网络的拥塞程度。
平均偏差
平均偏差(mean deviation),简写为mdev。
It is the mean of the distances between each value and the mean. It gives us an idea of how spread
out from the center the set of values is.
Here's the formula.
通过计算平均偏差,可以知道一组数据的波动情况。
在这里,平均偏差可以用来衡量RTT的抖动情况。
RTT测量原理
RTT的测量可以采用两种方法:
(1)TCP Timestamp选项
在前面的blog中有详细的介绍过这个选项,TCP时间戳选项可以用来精确的测量RTT。
RTT = 当前时间 - 数据包中Timestamp选项的回显时间
这个回显时间是该数据包发出去的时间,知道了数据包的接收时间(当前时间)和发送时间
(回显时间),就可以轻松的得到RTT的一个测量值。
(2)重传队列中数据包的TCP控制块
在TCP重传队列中保存着发送而未被确认的数据包,数据包skb中的TCP控制块包含着一个变量,
tcp_skb_cb->when,记录了该数据包的第一次发送时间。
RTT = 当前时间 - when
有人可能会问:既然不用TCP Timestamp选项就能测量出RTT,为什么还要多此一举?
这是因为方法一比方法二的功能更加强大,它们是有区别的。
“TCP must use Karn's algorithm for taking RTT samples. That is, RTT samples MUST NOT
be made using segments that were retransmitted (and thus for which it is ambiguious whether
the reply was for the first instance of the packet or a later instance). The only case when TCP
can safely take RTT samples from retransmitted segments is when the TCP timestamp option
is employed, since the timestamp option removes the ambiguity regarding which instance of
the data segment triggered the acknowledgement.”
对于重传的数据包的响应,方法1可以用它来采集一个新的RTT测量样本,而方法二则不能。因为
TCP Timestamp选项可以区分这个响应是原始数据包还是重传数据包触发的,从而计算出准确的
RTT值。
RTT测量实现
发送方每接收到一个ACK,都会调用tcp_ack()来处理。
tcp_ack()中会调用tcp_clean_rtx_queue()来删除重传队列中已经被确认的数据段。
在tcp_clean_rtx_queue()中:
如果ACK确认了重传的数据包,则seq_rtt = -1