之前我们介绍的都是协议中给出的RTO计算方法,下面我们看一下linux实现中RTO的计算方法。在linux中维护了srtt、mdev、mdev_max、rttvar、rtt_seq几个状态变量用来计算RTO,其中linux实现中的mdev变量相当于协议中的RTTVAR变量。rtt_seq状态变量用来控制一个RTT时间窗,linux在一个RTT时间窗内部更新状态变量的方式与RTT时间窗结束更新状态变量的方式不同,rtt_seq则用来判断当前是在RTT时间窗内部,还是一个RTT时间窗已经结束。

一、RTT时间窗的判断

几个状态变量中的rtt_seq用来判断当前采样是否处于RTT时间窗内,我们简单的说一下如何判断

在TCP窗口管理时候维护发送窗口有两个状态变量,一个是snd.una,另外一个是snd.nxt。其中snd.una表示还没有被ACK确认的数据包里面最早的系列号,snd.nxt表示下一个待发送的数据包。初始的时候设置rtt_seq =snd.nxt,随着数据包的发送和ACK报文的接收,snd.una和snd.nxt都会向前滑行,当更新RTT状态变量的时候,如果发现snd.una<=rtt_seq,说明之前发送的数据包还没有收到ACK,当前还处于RTT时间窗内部。如果发现snd.una>rtt_seq说明之前发送的数据包已经收到了对应的ACK确认,那么一个RTT时间窗结束,并把rtt_seq设置为snd.nxt继续下一个RTT时间窗的处理。

二、状态变量的更新

1、在测量到第一个RTT采样之前,linux会先查看本地缓存中是否由目标ip地址的RTT缓存信息,如果由对应的缓存信息,则会根据缓存信息初始化RTO,如果没有对应的缓存信息,则会把RTO初始化为3s。

我们可以使用ip tcp_metrics查看有所缓存,也可以使用ip tcp_metrics show ip命令查看某个ip地址相关的缓存信息

  1. ******@Inspiron:~$ ip tcp_metrics show 121.201.104.55
  2. 121.201.104.55 age 56.604sec cwnd 10 rtt 461481us rttvar 461481us source 192.168.1.103
2、在linux测量到第一个RTT采样m的时候,按照如下初始化相关状态变量
  1. srtt = m
  2. mddev = m/2
  3. rttvar = max(mdev, min_rto)
  4. mdev_max = rttvar
  5. RTO = srtt + 4 * rttvar

其中min_rto为该目标地址的最小RTT,如果路由中有配置那么使用配置值,如果没有配置则使用TCP_RTO_MIN,TCP_RTO_MIN常量为50ms(linux代码中这个常量为200ms实际为放大四倍后的值)。

3、在随后再次收到RTT测量值m的时候,按照如下更新mdev

  1. if(m < (srtt - mdev))
  2.    mdev = (31/32) * mdev + (1/32) * |srtt - m|
  3. else
  4.    mdev = (3/4) * mdev + (1/4) * |srtt - m|

我们之前说过linux实现中mdev变量相当于协议中的RTTVAR变量,这里mdev的更新与协议有了明显的不同,主要原因是如果链路时延突然大幅降低的时候,如果按照协议方法更新反而会大幅增加最后的RTO,因此linux在发现链路时延大幅下降的时候会降低RTO增长的幅度。其他状态变量更新如下

  1. mdev_max = max(mdev_max, mdev)
  2. srtt = (7/8) * srtt + (1/8) * m
  3. rttvar = mdev_max
  4. RTO = srtt + 4 * rttvar

4、根据rtt_seq来判断如果当前是RTT时间窗结束,则执行如下流程

  1. if(mdev_max < rtt_var)
  2. {
  3.    rtt_var = (3/4) * rtt_var + (1/4) * mdev_max
  4. }
  5. mdev_max = min_rto
注意我在if判断后面加了一个大括号来强调,不管if条件是否为真,只要RTT时间窗结束就要初始化mdev_max为min_rto。

补充说明:

1、linux中在测量到第一个RTT采样之前RTO的初始化参考tcp_init_metrics,RTT相关状态变量的更新参考tcp_rtt_estimator,其中mdev放大4倍,srtt放大8倍进行的保存和计算。

最新文章

  1. VS2015+Win10 调试DirectX 报错
  2. TP框架,根据当前应用状态对应的配置文件
  3. 平均值mean,众数mode,中值median 和 标准差stddev
  4. require.js 入门学习 (share)
  5. 20135306黄韧[2.72 2.77 3.70](http://i.cnblogs.com/EditPosts.aspx?opt=1)
  6. 分拆素数和[HDU2098]
  7. oracle 内联同时删除多表
  8. Ubuntu 12.04 修改键盘映射
  9. ios 字符串的操作汇总
  10. C# Linq GroupBy 分组过滤求和
  11. 【转】C++标准转换运算符reinterpret_cast
  12. COUNT分组条件去重的sql统计语句示例(mysql)
  13. c# ref和out参数
  14. sqoop 常用命令整理(二)
  15. duilib CEditUI 禁止输入中文字符,禁止复制粘贴
  16. sql 保留两位小数
  17. pktgen-dpdk 实战
  18. vue 组件开发 props 验证
  19. 【Android】11.0 第11章 活动和片段--本章示例主界面
  20. 第三百一十二节,Django框架,Cookie

热门文章

  1. rtsp over tcp并设置多个options
  2. 教你阅读MSDN英文文档,迅速提升编程能力
  3. SpaceVim 发布 v0.8.0
  4. Zookeeper原理和实战开发经典视频教程 百度云网盘下载
  5. PHP.50-TP框架商城应用实例-前台2-商品推荐
  6. 北京Uber优步司机奖励政策(12月22日)
  7. 北京Uber优步司机奖励政策(12月19日)
  8. MyBatis-mybatis全局映射文件解析
  9. 绝地求生大逃杀BE启动失败,应用程序无法正常启动
  10. PS 放大眼睛