3. RTTM -- 往返时间测量
3. RTTM: 往返时间测量 (Round-Trip Time Measurement)
3.1 简介 (Introduction)
准确和实时的RTT (往返时间) 估计对于适应不断变化的流量条件以及避免繁忙网络中被称为"拥塞崩溃" (congestion collapse) 的不稳定现象是必需的。然而,无论在理论上还是在实现中,准确测量RTT都可能很困难。
许多TCP实现基于每个窗口仅一个数据包的样本来进行RTT测量。虽然这对于小窗口能产生足够的RTT近似值,但对于LFN (长肥管道) 来说,会导致不可接受的RTT估计偏差。如果我们将RTT估计视为信号处理问题(事实确实如此),则以某一频率(数据包速率)的数据信号被以较低频率(窗口速率)采样。这种较低的采样频率违反了Nyquist准则,因此可能在估计的RTT中引入"混叠" (aliasing) 伪影。
具有保守重传超时计算的良好RTT估计器可以在采样频率"接近"数据频率时容忍混叠。例如,对于8个数据包的窗口,采样率是数据频率的1/8——相差不到一个数量级。然而,当窗口为数十或数百个数据包时,RTT估计器可能会严重出错,导致虚假重传。
如果存在丢包,问题会变得更糟。Zhang、Jain和Karn的研究表明,如果将重传段包含在估计中,就无法积累可靠的RTT估计。由于在重传之前将传输完整窗口的数据,因此在进行下一次RTT采样之前,必须确认该窗口中的所有段。这意味着RTT测量之间至少需要额外一个窗口的时间,并且随着错误率接近每窗口数据一次(例如,宽带卫星网络的10**-6错误每比特),实际上变得无法获得有效的RTT测量。
这些问题的解决方案实际上大大简化了发送方:使用TCP选项,发送方在每个数据段中放置时间戳,接收方在ACK段中反射这些时间戳。然后,单次减法就能为发送方提供每个ACK段的准确RTT测量(对应每隔一个数据段,对于合理的接收方)。我们称之为RTTM (往返时间测量) 机制。
对于大窗口使用RTTM机制至关重要;否则,由于混叠可能会出现一些危险的不稳定性。此外,该选项对于所有TCP可能都是有用的,因为它简化了发送方。
3.2 TCP时间戳选项 (TCP Timestamps Option)
TCP是对称协议,允许在任一方向随时发送数据,因此时间戳回显可能在任一方向发生。为简单和对称起见,我们规定时间戳始终在两个方向发送和回显。为了效率,我们将时间戳和时间戳回复字段组合到单个TCP时间戳选项中。
TCP时间戳选项 (TSopt):
Kind: 8
Length: 10字节
+-------+-------+---------------------+---------------------+
|Kind=8 | 10 | TS Value (TSval) |TS Echo Reply (TSecr)|
+-------+-------+---------------------+---------------------+
1 1 4 4
时间戳选项携带两个四字节时间戳字段。时间戳值字段 (TSval) 包含发送选项的TCP的时间戳时钟的当前值。
时间戳回显回复字段 (TSecr) 仅在TCP头中设置ACK位时有效;如果有效,它回显远程TCP在时间戳选项的TSval字段中发送的时间戳值。当TSecr无效时,其值必须为零。TSecr值通常来自最近收到的时间戳选项;但是,存在下面解释的例外情况。
TCP可以在初始<SYN>段(即包含SYN位且没有ACK位的段)中发送时间戳选项 (TSopt),并且只有在连接的初始<SYN>段中收到TSopt时,才可以在其他段中发送TSopt。
3.3 RTTM机制 (The RTTM Mechanism)
要在TSval中发送的时间戳值应从我们称之为"时间戳时钟"的(虚拟)时钟获得。其值必须至少大致与实时成比例,以便测量实际的RTT。
以下示例说明了段按顺序到达且无损失的单向数据流。这里A、B、C...表示占据连续序列号块的数据块,ACK(A)...表示相应的累积确认。时间戳选项的两个时间戳字段以符号形式显示为<TSval=x,TSecr=y>。每个TSecr字段包含最近在TSval字段中接收到的值。
TCP A TCP B
<A,TSval=1,TSecr=120> ------>
<---- <ACK(A),TSval=127,TSecr=1>
<B,TSval=5,TSecr=127> ------>
<---- <ACK(B),TSval=131,TSecr=5>
. . . . . . . . . . . . . . . . . . . . . .
<C,TSval=65,TSecr=131> ------>
<---- <ACK(C),TSval=191,TSecr=65>
(等等)
虚线标记A没有要发送的内容的暂停(60个时间单位长)。注意,这个暂停会使B从接收数据段C中的TSecr=131推断出的RTT膨胀。因此,在单向数据流中,反向的RTTM测量的值会被发送数据中的间隙膨胀。但是,以下规则防止了所测量RTT的膨胀:
仅当段确认了一些新数据时,即仅当它推进发送窗口的左边缘时,才使用段中接收到的TSecr值来更新平均RTT测量。
由于TCP B不发送数据,数据段C到达B时不确认任何新数据。因此,膨胀的RTTM测量不用于更新B的RTTM测量。
3.4 回显哪个时间戳 (Which Timestamp to Echo)
如果在发送回复段之前收到多个时间戳选项,TCP必须仅选择一个TSval进行回显,忽略其他的。为了最小化接收方保持的状态(即未处理的TSval数量),应要求接收方在连接控制块中最多保留一个时间戳。
需要考虑三种情况:
(A) 延迟ACK (Delayed ACKs)
许多TCP仅对在短时间间隔内到达的一组段中的每K个段进行确认;这种策略通常称为"延迟ACK"。数据发送方TCP必须测量有效的RTT,包括由于延迟ACK而增加的额外时间,否则它将不必要地重传。因此,当使用延迟ACK时,接收方应使用最早未确认段的TSval字段进行回复。
(B) 序列空间中的空洞(段已丢失)
发送方将继续发送直到窗口被填满,接收方可能会在这些乱序段到达时生成ACK(例如,帮助"快速重传")。
丢失的段可能是拥塞的迹象,在这种情况下,发送方应该对重传持保守态度。此外,高估RTT比低估RTT更好。因此,乱序段的ACK应包含来自最近推进窗口的段的时间戳。
如果段被网络重新排序,也会发生相同的情况。
(C) 序列空间中填充的空洞
填充空洞的段代表网络特性的最新测量。另一方面,从较早段计算的RTT可能包括发送方的重传超时,严重偏向发送方的平均RTT估计。因此,必须回显来自最新段(填充空洞的段)的时间戳。
涵盖所有三种情况的算法在以下同步连接上时间戳选项处理规则中描述:
(1) 连接状态用两个32位槽增强:TS.Recent保存在发送段时要在TSecr中回显的时间戳,Last.ACK.sent保存从最后发送的段的ACK字段。Last.ACK.sent将等于RCV.NXT,除非ACK已被延迟。
(2) 如果Last.ACK.sent落在传入段的序列号范围内:
SEG.SEQ <= Last.ACK.sent < SEG.SEQ + SEG.LEN
则将段中的TSval复制到TS.Recent;否则,忽略TSval。
(3) 当发送TSopt时,其TSecr字段设置为当前的TS.Recent值。
以下示例说明了这些规则。这里A、B、C...表示占据连续序列号块的数据段,ACK(A)...表示相应的确认段。注意ACK(A)与B具有相同的序列号。为清晰起见,我们只显示一个方向的时间戳回显。
o 数据包按顺序到达,并且一些ACK被延迟。
根据情况(A),回显来自最旧未确认段的时间戳。
TS.Recent
<A, TSval=1> ------------------->
1
<B, TSval=2> ------------------->
1
<C, TSval=3> ------------------->
1
<---- <ACK(C), TSecr=1>
(等等)
o 数据包乱序到达,并且每个数据包都被确认。
根据情况(B),回显来自最后推进左窗口边缘的段的时间戳,直到缺失的段到达;然后根据情况(C)回显它。如果段B和D丢失并重传,将发生相同的序列。
TS.Recent
<A, TSval=1> ------------------->
1
<---- <ACK(A), TSecr=1>
1
<C, TSval=3> ------------------->
1
<---- <ACK(A), TSecr=1>
1
<B, TSval=2> ------------------->
2
<---- <ACK(C), TSecr=2>
2
<E, TSval=5> ------------------->
2
<---- <ACK(C), TSecr=2>
2
<D, TSval=4> ------------------->
4
<---- <ACK(E), TSecr=4>
(等等)