背景
在做可靠传输的弱网测试时,常常会发现因为一个报文的丢失导致发送端无法发送新数据,比如窗口大小是10,1-9已经被收到,但是0号报文一直丢包,而重传的间隔越来越大,导致有一段时间没有任何报文的收发,直到下次0号报文的重传。这里的原因就在于rto的时间被估值太大,导致重传间隔太久,下面一段话摘自linux内核代码,
/* The following amusing code comes from Jacobson's
* article in SIGCOMM '88. Note that rtt and mdev
* are scaled versions of rtt and mean deviation.
* This is designed to be as fast as possible
* m stands for "measurement".
*
* On a 1990 paper the rto value is changed to:
* RTO = rtt + 4 * mdev
*
* Funny. This algorithm seems to be very broken.
* These formulae increase RTO, when it should be decreased, increase
* too slowly, when it should be increased quickly, decrease too quickly
* etc. I guess in BSD RTO takes ONE value, so that it is absolutely
* does not matter how to _calculate_ it. Seems, it was trap
* that VJ failed to avoid. 8)
*/
可以看出内核本身也认为这个算法已经有些老土了,应该减小rto的时候却在增大,应该快速增加rto的时候却很慢,但人们似乎并不在乎rto的这点偏差。
计算方式
计算需要的参数,可能取自下面三个链路往返时间
- 本次收到的包中携带的ack确认的数据,都是从未被重传过的数据包,计算得到的seq_rtt_us,最小序号的,可能一次确认多个数据包
- 从未被重传过的数据包使用选择