Home RFC6298笔记:RTO计算和定时器维护
Post
Cancel

RFC6298笔记:RTO计算和定时器维护

前言

RFC6298讨论重传定时器相关的算法。因为首次涉足内核协议栈实现时,注释里总是提到各种RFC,因此需要过一遍。对于文中提到的MUST,或者SHOULD,将会用颜色标注;其它仅强调的语气(MAY)会加粗处理

背景介绍

RFC1122指出,RTO的计算方式应当遵循Jac88

[Jac88] Jacobson, V., “Congestion Avoidance and Control”, Computer Communication Review, vol. 18, no. 4, pp. 314-329, Aug. 1988.

而RFC6298要求发送端使用这些算法可以相对保守点,但是绝对不能更加激进

基本算法

求出RTO的算法需要维护两个变量:

  • SRTT: smoothed RTT
  • RTTVAR: RTT variation

还有两个常量:

  • G: clock granularity (<= 100 msec)
  • K: 4

初始阶段

在初始阶段,RTO的初值被设为1s。注意在RFC2988中提到RTO初值是3s,而在RFC6298中改为了1s,但是如果发生SYN丢失或者ACK of SYN丢失的话,将会回退到3s,直到开始传输数据

首次RTT计算

当首次测量到RTT数值(设为R)的时候,必须使用如下算法:

SRTT = R
RTTVAR = R / 2
RTO = SRTT + max(G, K * RTTVAR)

后续RTT计算

当后续测量到RTT数值(设为R')的时候,必须使用如下算法:

RTTVAR = (1-β) * RTTVAR + β * (SRTT - R')
SRTT = (1-α) * SRTT + α * R'
RTO = SRTT + max(G, K * RTTVAR)

作者认为公式中列出的两个因子应当取\(\alpha = \frac{1}{8}, \beta = \frac{1}{4}\)

另外,如果RTO小于1s,那么应当上取整到1s

作者提到以前是用粗粒度时钟G使得最小RTO值足够大来避免过度重传,事实上G的取值没有硬性要求,只是文中给出了一个参考的数

个人认为,RTTVAR是处理突发情况的RTT偏差修正值;而RTO是一个应比RTT略大的值,因此参考了G和K

RTT样本的选择

TCP必须使用Karn算法进行RTT采样:

  • 采样对象:RTT不得根据已重传的数据段进行采样,除非使用了timestamp option
  • 采样时机:当使用了timestamp时,可以每次ACK都进行RTT采样;而TCP实现必须在每一次RTT范围内进行至少一次RTT采样

我顺手贴一下以前上学时做的计网笔记,脑子不够用笔记来凑数

Karn算法的提出是基于这样的背景:

  • 对于一个分组p,它曾被重传过,也就是说,对端(接收端B)能收到至少2份相同的分组(p1、p2……)
  • 那么当原来的发送端A现在收到B发来的报文确认时,该如何判定是对哪一份的重复分组的确认(p1还是p2?)
  • 这种歧义影响到了RTT的测量

而Karn算法的核心很简单:就是当发生报文重传时,不对它进行RTT采样(既不参与运算)

RTO定时器的维护

状态转移的感性认知还是比较简单的:

  • 启动:含数据的包首次发出,就启动重传定时器,达到RTO时间后超时
  • 重设:如果有ACK,重传定时器重新设为当前RTO
  • 关闭:如果全部发出的数据都ACK,关闭定时器
  • 更新:下次重传时更新RTO = RTO * 2,最大阈值可能是60s
    • 这种做法称为RTO backoff
    • 当发生backoff时,前面维护的2个变量可能清零,此后的计算仍需区分首次和后续两个阶段
  • 采样:如果有采样到RTT,用前面的计算方式覆盖当前RTO
    • 这种情况只发生在发出新的数据包和ACK

安全性

作者好像说了什么,但好像也没说什么,总之当作没看到吧

文章太短,就不需要总结了

This post is licensed under CC BY 4.0 by the author.
Contents