ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【RFC7323 高性能的TCP扩展】(翻译)

2021-06-30 21:03:15  阅读:411  来源: 互联网

标签:选项 窗口 TCP 发送 高性能 时间 连接 RFC7323


https://datatracker.ietf.org/doc/html/rfc7323 高性能的 TCP 扩展

本文档指定了一组 TCP 扩展,以提高具有大带宽乘以延迟的积的路径的性能,并在非常高速的路径上提供可靠的操作。它定义了 TCP Window Scale (WS) 选项和 TCP Timestamps (TS) 选项及其语义。 Window Scale 选项用于支持更大的接收窗口,而 Timestamps 选项可用于至少两种不同的机制,防止包装序列 (PAWS) 和往返时间测量 (RTTM),这里也有描述。

本文档废弃了 RFC 1323 并描述了它的变化。

目录

   1. 简介

     1.1. TCP性能

     1.2. TCP可靠性

     1.3.使用 TCP 选项

     1.4.术语

   2. TCP 窗口缩放选项

     2.1.介绍

     2.2.窗口缩放选项

     2.3.使用窗口缩放选项

     2.4.解决窗口缩回

   3. TCP 时间戳选项

     3.1.介绍

     3.2.时间戳选项

   4. RTTM 机制

     4.1.介绍

     4.2.更新 RTO 值

     4.3.回显哪个时间戳

   5. PAWS - 防止包装序列

     5.1.介绍

     5.2. PAWS 机制

     5.3.基本 PAWS 算法

     5.4.时间戳时钟

     5.5.过时的时间戳

     5.6.头部预测

     5.7. IP分片

     5.8.早期连接的复制品

   6. 结论和致谢

   7. 安全考虑

     7.1.隐私注意事项

   8. IANA 考虑

   9. 参考文献

     9.1.规范参考

     9.2.参考资料

   附录 A 实施建议

   附录 B. 来自早期连接化身的副本

     B.1.状态丢失导致系统崩溃

     B.2.关闭和重新打开连接

   附录 C. 符号总结

   附录 D. 事件处理总结

   附录 E. 时间戳边缘情况

   附录 F. 窗口收回示例

   附录 G. RTO 计算修改

   附录 H. RFC 1323 的变化

1. 简介

TCP 协议 [RFC0793] 旨在在几乎任何传输介质上可靠运行,而不管传输速率、延迟、损坏、重复或段的重新排序。多年来,网络技术的进步导致传输速度越来越快,最快的路径远远超出了 TCP 最初设计的领域。

本文档定义了一组对 TCP 的适度扩展,以扩展其应用领域以匹配不断增长的网络能力。它是对 [RFC1323] 的更新和废弃,而后者又基于并废弃了 [RFC1072] 和 [RFC1185]。

[RFC1323] 和本文档之间的变化在附录 H 中有详细说明。这些变化部分是由于 [RFC1323] 中的勘误表,部分是由于对所涉及的组件如何交互的理解有所提高。

为简洁起见,省略了对本文档中定义的 TCP 选项背后的优点和历史的全面讨论。应查阅 [RFC1323] 以供参考。建议现代 TCP 堆栈实现并使用本文档中描述的扩展。

1.1. TCP性能

当带宽*延迟积很大时,就会出现TCP性能问题。具有此类路径的网络称为“长胖网络”(LFN)。

LFN 路径上的基本 TCP 存在两个基本性能问题:

(1) 窗口大小限制

TCP 报头使用 16 位字段向发送方报告接收窗口大小。因此,可以使用的最大窗口是 2^16 = 64 KiB。对于带宽 * 延迟乘积超过 64 KiB 的 LFN 路径,接收窗口限制了该路径上 TCP 连接的最大吞吐量,即 TCP 可以发送的未确认数据量,以保持管道充满。

为了规避这个问题,本问的第 2 节定义了一个 TCP 选项,“窗口缩放”,以允许大于 2^16 的窗口。该选项定义了一个隐式比例因子,用于乘以在 TCP 头部中找到的窗口大小值以获得真实的窗口大小。

必须注意,大接收窗口的使用增加了过快包装序列号的机会,如下面的第 1.2 节 (1) 所述。

(2) 从损失中恢复

LFN 中的数据包丢失会对吞吐量产生灾难性的影响。

为了概括快速重传/快速恢复机制来处理每个窗口丢弃的多个数据包,需要选择性确认。与 TCP 的正常累积确认不同,选择性确认让发送方全面了解哪些段在接收方排队,哪些尚未到达。

选择性确认及其使用在单独的文档“TCP 选择性确认选项”[RFC2018]、“TCP 选择性确认 (SACK) 选项的扩展”[RFC2883] 和“基于选择性确认的保守丢失恢复算法”中指定(SACK) for TCP”[RFC6675],本文档不再进一步讨论。

1.2. TCP可靠性

一种特别严重的错误可能是由于数据段中 TCP 序列号的意外重用造成的。 TCP 可靠性取决于段生命周期的界限的存在:“最大段生命周期”或 MSL。

序列号的重复可能以两种方式之一发生:

(1) 当前连接上的序列号环绕

TCP 序列号包含 32 位。在大量数据(同一会话中至少 4 GiB)的足够高的传输速率下,32 位序列空间可能会在段在队列中延迟的时间内“包装”(循环)。

(2) 连接的较早化身

假设连接因正确的关闭顺序或由于主机崩溃而终止,并且相同的连接(即使用相同的端口号对)立即重新打开。来自终止连接的延迟段可能落在新化身的当前窗口内并被接受为有效。

如第 5.8 节和附录 B 中所述,通过强制执行 TCP 规范的当前固定 MSL 避免了来自早期化身案例 (2) 的重复。此外,临时端口的随机化也有助于在概率上减少重复的机会从早期的连接。然而,情况 (1),避免在同一连接内重复使用序列号,需要 MSL 的上限取决于传输速率,并且在足够高的速率下,需要专用机制。

循环序列空间问题的一个可能解决方法是增加 TCP 序列号字段的大小。例如,序列号字段(以及确认字段)可以扩展到 64 位。这可以通过更改 TCP 头部或通过附加选项来完成。

第 5 节介绍了一种不同的机制,我们称之为 PAWS,将 TCP 可靠性扩展到远远超出可预见的网络带宽上限的传输速率。 PAWS 使用第 3.2 节中定义的 TCP 时间戳选项来防止来自同一连接的旧副本。

1.3.使用 TCP 选项

本文档中定义的扩展都使用 TCP 选项。

当 [RFC1323] 发布时,有人担心一些有缺陷的 TCP 实现可能会在非 <SYN> 段上的选项第一次出现时崩溃。但是,此类错误可能会导致针对 TCP 的拒绝服务 (DoS) 攻击。研究表明,大多数 TCP 实现将正确处理非 <SYN> 段([Medina04]、[Medina05])上的未知选项。但是在发送的内容上仍然是谨慎的,避免错误的 TCP 实现并不是在 <SYN> 段上协商 TCP 选项的唯一原因。 Window Scale 选项协商 TCP 会话的基本参数。因此,它仅在初始握手期间发送。此外,仅当在初始 <SYN> 段中接收到相应选项时,才会在 <SYN,ACK> 段中发送窗口缩放选项。

Timestamps 选项可以出现在任何数据或 <ACK> 段中,向 20 字节的 TCP 头部添加 10 个字节(最多 12 个字节,包括填充)。在 <SYN> 段上的选项交换表明双方都理解此扩展后,要求此 TCP 选项将在所有非 <SYN> 段上发送。

研究表明,使用 Timestamps 选项在每个 RTT 内获取额外的 RTT 样本对最终重传超时值几乎没有影响 [Allman99]。但是,时间戳选项还有其他用途,例如 Eifel 机制([RFC3522]、[RFC4015])和 PAWS(见第 5 节),它们提高了 TCP 的整体安全性和性能。应针对实际部署中的性能和安全性增益评估此选项使用的额外头部带宽。

附录 A 包含 TCP 头部中选项的推荐布局,以实现合理的数据字段对齐。

最后,我们观察到本文档中定义的大多数机制对于 LFN 和/或超高速网络都很重要。对于低速网络,不使用这些机制可能是一种性能优化。关心低速路径上的最佳性能的 TCP 供应商可能会考虑为低速路径关闭这些扩展,或允许用户或安装管理员禁用它们。

2. TCP 窗口缩放选项

2.1.介绍

窗口缩放扩展将 TCP 窗口的定义扩展到 30 位,然后使用隐式缩放因子在 TCP 头部的 16 位窗口字段中携带这个 30 位值([RFC0793] 中的 SEG.WND)。比例因子的指数包含在 TCP 选项 Window Scale 中。此选项仅在 <SYN> 段(带有 SYN 位的段)中发送,因此当打开连接时,窗口比例在每个方向上都是固定的。

最大接收窗口以及比例因子由最大接收缓冲区空间决定。在典型的现代实现中,这个最大缓冲区空间是默认设置的,但可以在打开 TCP 连接之前由用户程序覆盖。这决定了比例因子,因此窗口缩放不需要新的用户界面。

2.2.窗口缩放选项

三字节的窗口缩放选项可以在 <SYN> 段中由 TCP 发送。它有两个目的:(1) 指示 TCP 准备发送和接收窗口缩放,以及 (2) 传达要应用于其接收窗口的缩放因子的指数。

因此,准备缩放窗口的 TCP 应该发送选项,即使它自己的比例因子是 1 并且指数是 0。比例因子被限制为 2 的幂并以对数方式编码,因此它可以通过二进制移位实现 操作。 对于 1 GiB (2^(14+16)) 的最大允许接收窗口大小,最大比例指数限制为 14。

TCP 窗口缩放选项 (WSopt):

此选项是要约,而不是承诺;双方必须在其 <SYN> 段中发送窗口缩放选项,以启用任一方向的窗口缩放。如果启用窗口缩放,则发送此选项的 TCP 会将其真实接收窗口值右移“shift.cnt”位,以便在 SEG.WND 中进行传输。值 'shift.cnt'可能为零(按比例提供,同时对接收窗口应用比例因子 1)。

此选项可以在初始 <SYN> 段(即,SYN 位打开而 ACK 位关闭的段)中发送。如果在初始 <SYN> 段中接收到窗口缩放选项,则该选项可以在 <SYN,ACK> 段中发送。没有 SYN 位的段中的窗口缩放选项必须被忽略。

设置了 SYN 位(即 <SYN> 或 <SYN,ACK>)的段中的窗口字段不得缩放。

2.3.使用窗口缩放选项

窗口缩放的模型实现如下,使用 [RFC0793] 的符号:

   o 连接状态由两个窗口移位计数器 Snd.Wind.Shift 和 Rcv.Wind.Shift 增强,分别应用于传入和传出窗口字段。

   o 如果 TCP 接收到包含窗口缩放选项的 <SYN> 段,它应该在 <SYN,ACK> 段中发送它自己的窗口缩放选项。

   o 窗口缩放选项必须与 shift.cnt = R 一起发送,其中 R 是 TCP 想要用于其接收窗口的值。

   o 在接收到带有包含 shift.cnt = S 的 Window Scale 选项的 <SYN> 段时,TCP 必须将 Snd.Wind.Shift 设置为 S,并且必须将 Rcv.Wind.Shift 设置为 R;否则,它必须将 Snd.Wind.Shift 和 Rcv.Wind.Shift 都设置为零。

   o 除了 <SYN> 段外,每个传入段的头中的窗口字段 (SEG.WND) 必须在更新 SND.WND 之前移位 Snd.Wind.Shift 位:

                    SND.WND = SEG.WND << Snd.Wind.Shift

(假设满足 [RFC0793] 的其他条件,并使用“C”符号“<<”进行左移)。

   o 除了 <SYN> 段外,每个传出段的窗口字段 (SEG.WND) 必须右移 Rcv.Wind.Shift 位:

                    SEG.WND = RCV.WND >> Rcv.Wind.Shift

TCP通过测试其序列号是否在窗口左边缘的2^31字节内来确定数据段是“旧”还是“新”,如果不在,则将数据作为“旧”丢弃。为了确保新数据永远不会被错误地视为旧数据,反之亦然,发送方窗口的左边缘必须与接收方窗口的右边缘最多相距 2^31。发送方的右边缘和接收方的左边缘也是如此。由于发送方或接收方窗口的左右边缘因窗口大小而异,并且由于发送方和接收方窗口最多可以异相窗口大小,因此上述约束意味着最大窗口大小的两倍小于 2^31,或

                            最大窗口 < 2^30

由于最大窗口是 2^S(其中 S 是缩放移位计数)最多 2^16 - 1(最大未缩放窗口),如果 S <= 14,则最大窗口保证 < 2^30。因此,移位计数必须限制为 14(允许 2^30 = 1 GiB 的窗口)。如果接收到的 Window Scale 选项的 shift.cnt 值大于 14,则 TCP 应该记录错误,但必须使用 14 而不是指定的值。这是安全的,因为发送方始终可以选择仅部分使用任何信号接收窗口。如果接收方的缩放比例大于 14,而发送方仅缩放 14,那么发送方使用的接收窗口将比实际情况小。

比例因子仅适用于 TCP 报头中传输的窗口字段;每个使用扩展窗口的 TCP 将在本地将窗口值保持为 32 位数字。例如,由慢启动和拥塞避免计算的“拥塞窗口”(参见 [RFC5681])不受比例因子的影响,因此窗口缩放不会将量化引入拥塞窗口。

2.4.解决窗口缩回

当使用非零比例因子时,在某些情况下可以提供缩回窗口 - 有关详细示例,请参阅附录 F。根据所使用的比例因子的粒度,窗口的末端将位于边界上。如果序列号随后更新了小于该粒度的字节数,则 TCP 将不得不通告一个超出其先前通告(并且可能超出缓冲区)的新窗口,或者必须通告一个较小的窗口,这将导致 TCP 窗口缩小。实现必须确保它们处理缩小的窗口,如 [RFC1122] 的第 4.2.2.16 节中所指定。

对于接收者,这意味着:

   1) 接收方必须像在窗口中一样尊重接收方发送的任何 <ACK> 在窗口中的任何段。

   2) 当窗口缩放生效时,接收者应该跟踪实际的最大窗口序列号(它很可能大于最近 <ACK> 宣布的窗口,如果自从应用程序消耗了一个以上已经到达接收缓冲区的段中的数据)。

在发送方:

   3) 初始传输必须在最近 <ACK> 宣布的窗口内。

   4) 在第一次重传时,或者如果序列号在窗口外小于 2^Rcv.Wind.Shift,那么只要原始段在窗口中,就进行正常的重传而不考虑接收器窗口。

   5) 后续的重传可能只在它们在最近的 <ACK> 宣布的窗口内时才被发送。

3. TCP 时间戳选项

3.1.介绍

引入时间戳选项是为了解决第 1.1 节和第 1.2 节中提到的一些问题。 Timestamps 选项以对称方式指定,以便时间戳值 (TSval) 时间戳在数据和 <ACK> 段中携带,并在返回 <ACK> 或数据段中携带的 Timestamp Echo Reply (TSecr) 字段中回显。最初主要用于为单个段添加时间戳,时间戳选项的属性允许进行时间测量(第 4 节)以及其他用途(第 5 节)。

有必要记住,传递时间戳信息的 Timestamps 选项和该信息的使用是有区别的。特别是,必须独立于更新重传超时 (RTO) 来查看 RTTM 机制(请参阅第 4.2 节)。在这种情况下,还需要考虑样本粒度。其他机制,例如 PAWS 或 Eifel,并非建立在时间戳信息本身之上,而是基于单调非递减值的内在属性。

当使用大型接收窗口以允许使用 PAWS 机制时,时间戳选项很重要(请参阅第 5 节)。

此外,该选项可能对所有 TCP 有用,因为它简化了发送方并允许使用其他优化,例如 Eifel([RFC3522]、[RFC4015])和其他([RFC6817]、[Kuzmanovic03]、[Kuehlewind10]) .

3.2.时间戳选项

TCP 是一种对称协议,允许数据在任一方向随时发送,因此时间戳回显可能发生在任一方向。为了简单和对称,我们指定时间戳始终在两个方向上发送和回显。为了提高效率,我们将时间戳和时间戳回复字段组合到一个 TCP 时间戳选项中。

   TCP 时间戳选项 (TSopt):

   种类:8

   长度:10 字节

Timestamps 选项带有两个四字节的时间戳字段。 TSval 字段包含发送选项的 TCP 的时间戳时钟的当前值。

如果在 TCP 报头中设置了 ACK 位,则 TSecr 字段是有效的。如果在出站 TCP 报头中没有设置 ACK 位,则该段的发送方应该将 TSecr 字段设置为零。当在出站段中设置 ACK 位时,发送方必须在 Timestamps 选项的 TSval 字段中回显最近接收到的由远程 TCP 发送的 TSval。必须回显 TSval 的确切规则在第 4.3 节中给出。当 ACK 位未设置时,接收者必须忽略 TSecr 字段的值。

TCP 可以在初始 <SYN> 段(即包含 SYN 位但没有 ACK 位的段)中发送 TSopt,并且仅当它在初始 <SYN> 中接收到 TSopt 时才可以在 <SYN,ACK> 中发送 TSopt段的连接。

一旦 TSopt 成功协商,即 <SYN> 和 <SYN,ACK> 都包含 TSopt,TSopt 必须在连接期间的每个非 <RST> 段中发送,并且应该在 <RST> 段中发送(有关详细信息,请参阅第 5.2 节)。 TCP 应该通过将一个标记(称为 Snd.TS.OK)设置为 1 来记住这个状态。如果在没有 TSopt 的情况下接收到非 <RST> 段,则 TCP 应该默默地丢弃该段。 TCP 不得中止 TCP 连接,因为任何段都缺少预期的 TSopt。

强烈鼓励实现在决定接受段时遵循上述规则来处理丢失的时间戳选项和第 5.3 节中提到的优先级顺序。

如果接收方选择接受没有预期时间戳选项的段,则必须清楚可能会发生无法检测的数据损坏。

这样的 TCP 接收器可能会遇到无法检测的包装序列效应,例如数据(有效负载)损坏或会话停顿。为了保持有效载荷数据的完整性,尤其是在高速网络上,遵循所描述的处理规则至关重要。

但是,有人提到在某些情况下,上述准则过于严格,某些路径会偶尔抑制 Timestamps 选项,同时保持负载完整性。以这种方式运行的路径应该被认为是不可接受的,但已经注意到一些实现放宽了接受规则作为一种变通方法,并允许 TCP 运行在这些路径上 [RE-1323BIS]。

如果在初始三次握手中未协商 TSopt 的连接上接收到 TSopt,则必须忽略 TSopt 并正常处理数据包。

在跨越 <SYN> 段的情况下,其中一个 <SYN> 包含一个 TSopt 而另一个不包含,双方可以在 <SYN,ACK> 段中发送一个 TSopt。

第 4 节和第 5 节中描述的两种机制都需要 TSopt。还有其他机制依赖于 TSopt 的存在,例如 [RFC3522]。如果 TCP 在建立会话期间的任何时间停止发送 TSopt,它就会干扰这些机制。对 [RFC1323] 的此更新明确描述了先前的假设(参见第 5.2 节),即一旦协商,每个 TCP 段都必须具有 TSopt。

4. RTTM 机制

4.1.介绍

Timestamps 选项的一种用途是测量几乎每个已确认数据包的往返时间 (RTT)。 RTTM 机制要求在每个测量段中都有一个 Timestamps 选项,并具有从(虚拟)“时间戳时钟”获得的 TSval。该时钟的值必须至少与实时时间大致成比例,以便测量实际 RTT。

TCP 测量 RTT,主要是为了达到 RTO 计时器间隔的合理值。准确和当前的 RTT 估计对于适应不断变化的传输状况是必要的,而 RTO 间隔的保守估计对于最小化虚假 RTO 是必要的。

这些 TSval 值以相反的方向在 TSecr 值中回显。接收到的 TSecr 值与当前时间戳时钟值之间的差异提供了 RTT 测量。

当使用时间戳时,接收到的每个段都将包含一个 TSecr 值。但是,这些值不能全部用于更新测量的 RTT。以下示例说明了原因。它显示了单向数据流,其中段按顺序到达而不会丢失。这里A,B,C...代表数据块占用连续的序列号块,ACK(A),...代表对应的累积确认。 Timestamps 选项的两个时间戳字段象征性地显示为 <TSval=x,TSecr=y>。每个 TSecr 字段包含最近在 TSval 字段中收到的值。

虚线标记了一个暂停(60 个时间单位长),其中 A 没有什么可发送的。请注意,此暂停会使 RTT 膨胀,B 可以从数据段 C 中接收到的 TSecr=131 推断出这一点。因此,在单向数据流中,反向的 RTTM 测量的值因发送数据的间隙而膨胀。但是,以下规则可防止导致测量的 RTT 膨胀:

RTTM 规则:只有当段前进到发送窗口的左边缘时,在段中接收到的 TSecr 值才可用于更新平均 RTT 测量,即 SND.UNA 增加。

由于 TCP B 没有发送数据,数据段 C 在到达 B 时不会确认任何新数据。因此,膨胀的 RTTM 测量值不用于更新 B 的 RTTM 测量值。

4.2.更新 RTO 值

最初编写 [RFC1323] 时,人们认为对每个段进行 RTT 测量,以及在重传期间,将有助于减少虚假 RTO,同时保持必要 RTO 的及时性。当时,RTO 也是唯一使用测量 RTT 的机制。已经表明,采用更多的 RTT 样本对优化 RTO 的影响非常有限 [Allman99]。

实施者应该注意,使用时间戳,每个 RTT 可以采用多个 RTTM。 [RFC6298] RTT 估计器具有加权因子,alpha 和 beta,基于一个隐含的假设,即每个 RTT 最多采样一个 RTTM。当每个 RTT 有多个 RTTM 可用于更新 RTT 估计器时,实现应该尝试遵守 [RFC6298] 中指定的历史精神。附录 G 中详细介绍了实施建议。

[Ludwig00] 和 [Floyd05] 强调了一个问题,即使用每个数据包的 RTT 样本更新的未修改 RTO 计算将过早截断路径历史。当路径属性以几个 RTT 的数量级变化时,这会导致虚假重传的增加,但在更短的时间尺度上获取大量 RTT 样本。

4.3.回显哪个时间戳

如果在发送回复段之前收到多个 Timestamps 选项,则 TCP 必须仅选择其中一个 TSval 进行回显,而忽略其他。为了最小化接收器中保存的状态(即未处理的 TSval 的数量),应该要求接收器在连接控制块中最多保留一个时间戳。

有以下三种情况需要考虑:

(A) 延迟的 ACK

许多 TCP 仅确认在很短的时间间隔内到达的一组段中的第二个段;此策略通常称为“延迟 ACK”。数据发送方 TCP 必须测量有效 RTT,包括由于延迟 ACK 导致的额外时间,否则它将不必要地重新传输。因此,当使用延迟的 ACK 时,接收方应该使用来自最早未确认段的 TSval 字段进行回复。

(B) 序列空间中的一个洞(段已丢失)

发送方将继续发送直到窗口被填满,并且接收方可能会在这些乱序段到达时生成 <ACK>(例如,以帮助“快速重传”)。

丢失的段可能是拥塞的标志,在这种情况下,发送方应该对重传持保守态度。此外,高估 RTT 总比低估 RTT 好。因此,无序段的 <ACK> 应该包含来自推进 RCV.NXT 的最新段的时间戳。

如果段被网络重新排序,也会发生同样的情况。

(C) 序列空间中的填充洞

填充洞并推进窗口的段代表网络特性的最新测量。从较早段计算的 RTT 可能包括发送方的重传超时,严重影响发送方的平均 RTT 估计。因此,必须回显来自最新段(填补空洞)的时间戳。

以下规则描述了一种涵盖所有三种情况的算法,用于同步连接上的时间戳选项处理:

(1) 连接状态增加了两个 32 位槽:

TS.Recent 保存一个时间戳,每当发送一个段时在 TSecr 中回显,Last.ACK.sent 保存来自最后发送的段的 ACK 字段。 Last.ACK.sent 将等于 RCV.NXT,除非 <ACK> 被延迟。

(2) 如果:

            SEG.TSval >= TS.Recent 和 SEG.SEQ <= Last.ACK.sent

     然后将 SEG.TSval 复制到 TS.Recent;否则,它被忽略。

(3) 当发送一个TSopt时,它的TSecr字段被设置为当前的TS.Recent值。

以下示例说明了这些规则。这里A、B、C...表示占用连续序列号块的数据段,ACK(A)...表示对应的确认段。请注意,ACK(A) 与 B 具有相同的序列号。为了清楚起见,我们仅显示时间戳回显的一个方向。

o 段按顺序到达,并且一些 <ACK> 被延迟。

在情况 (A) 中,回显来自最旧的未确认段的时间戳。

o 段无序到达,并且每个段都被确认。

在情况(B)中,从最后一个向左窗口边缘前进的段的时间戳被回显,直到丢失的段到达; 根据情况(C)回显。 如果段 B 和 D 丢失并重新传输,则会出现相同的顺序。

5. PAWS - 防止包装序列

5.1.介绍

Timestamps 选项的另一个用途是 PAWS 机制。 5.2 节描述了一种简单的机制来拒绝可能破坏打开的 TCP 连接的旧重复段。 PAWS 在单个 TCP 连接内运行,使用连接控制块中保存的状态。第 5.8 节和附录 H 讨论了 PAWS 机制对于避免来自同一连接的先前化身的旧副本的影响。

5.2. PAWS 机制

PAWS 使用前面描述的 TCP 时间戳选项,并假设每个接收到的 TCP 段(包括数据和 <ACK> 段)都包含一个时间戳 SEG.TSval,其值在时间上是单调非递减的。基本思想是,如果收到的段的时间戳 SEG.TSval 小于最近在此连接上收到的某些时间戳,则可以将其作为旧副本丢弃。

在 PAWS 机制中,“时间戳”是模块化 32 位空间中的 32 位无符号整数。因此,“小于”的定义方式与 TCP 序列号的定义方式相同,并且应用相同的实现技术。如果 s 和 t 是时间戳值,

                       s < t if 0 < (t - s) < 2^31,

以无符号 32 位算术计算。

选择要为该比较保存的传入时间戳必须保证一个值是单调非递减的。例如,一个实现可能会保存来自最后推进接收窗口左边缘的段的时间戳,即最近的序列段。为简单起见,改为使用第 4.3 节中介绍的值 TS.Recent,因为对 PAWS 和 RTTM 使用公共值可简化实现。正如第 4.3 节所解释的,TS.Recent 与最后一个 in-sequence 段的时间戳仅在延迟 <ACK> 的情况下不同,因此相差不到一个窗口。因此,任何一种选择都可以防止序列号环绕。

PAWS 将所有传入段提交到同一测试,因此可以防止重复的 <ACK> 段以及数据段。 (另一种非对称算法将防止旧的重复 <ACK> s:数据的发送方将拒绝传入的 <ACK> 段,其 TSecr 值小于从最后一个段中保存的 TSecr,其 ACK 字段提前了发送窗口。该算法被认为缺乏机制和对称性的经济性。)

在 <SYN> 和 <SYN,ACK> 段上发送的 TSval 时间戳用于初始化 PAWS。 PAWS 防止旧的重复非 <SYN> 段和重复的 <SYN> 段在有同步连接时收到。没有连接时收到的重复<SYN>和<SYN,ACK>段将被TCP正常的3次握手和序列号检查丢弃。

[RFC1323] 建议 <RST> 段不携带时间戳,并且无论其时间戳如何,它们都是可接受的。当时的想法是,旧的重复 <RST> 段应该是极不可能的,并且它们的清理功能应该优先于时间戳。最近,关于对 TCP 连接的各种盲目攻击的讨论提出了这样的建议:如果存在时间戳选项,则可以使用 SEG.TSecr 为 <RST> 段提供更严格的验收测试。

虽然仍在讨论中,但为了能够对此领域进行研究,现在建议在生成 <RST> 时,如果导致生成 <RST> 的段包含时间戳选项,则 <RST> 还应包含时间戳选项。在 <RST> 段中,SEG.TSecr 应该设置为来自传入段的 SEG.TSval 并且 SEG.TSval 应该设置为零。如果由于用户中止而生成 <RST>,并且设置了 Snd.TS.OK,则时间戳选项应该包含在 <RST> 中。当接收到 <RST> 段时,不得通过验证 SEG.TSval 中的可接受值来对其进行 PAWS 检查,并且不得使用来自 Timestamps 选项的信息来更新连接状态信息。 SEG.TSecr 可用于提供更严格的 <RST> 验收检查。

5.3.基本 PAWS 算法

如果使用 PAWS 算法,则必须对同步连接的所有传入段执行以下处理。此外,PAWS 处理必须优先于常规 TCP 可接受性检查([RFC0793] 中的第 3.3 节),这是在验证收到的时间戳选项后执行的:

   R1) 如果到达段中有 Timestamps 选项,SEG.TSval < TS.Recent,TS.Recent 是有效的(见后面的讨论),如果 RST 位没有设置,则将到达段视为不可接受:

按照 [RFC0793] 第 69 页的第 3.9 节中的规定发送确认作为回复,并删除该段。

注意:为了保留 TCP 检测和恢复半开连接的机制,必须发送 <ACK> 段。例如,参见 [RFC0793] 的图 10。

   R2) 如果该段在窗口之外,则拒绝它(正常的 TCP 处理)。

   R3) 如果到达的段满足 SEG.TSval >= TS.Recent 和 SEG.SEQ <= Last.ACK.sent(参见第 4.3 节),则在 TS.Recent 中记录其时间戳。

   R4) 如果到达的段是顺序的(即,在左窗口边缘),则正常接受它。

   R5) 否则,将该段视为正常的窗口内、无序 TCP 段(例如,将其排队以便稍后交付给用户)。

步骤R2、R4和R5是[RFC0793]规定的正常TCP处理步骤。

重要的是要注意时间戳必须仅在段第一次到达接收方时才检查,无论它是按顺序排列还是必须排队等待稍后交付。

考虑以下示例。

假设段序列:A.1, B.1, C.1, ..., Z.1 已发送,其中字母表示序列号,数字表示时间戳。还假设段 B.1 已经丢失。 TS.Recent 中的时间戳是 1(来自 A.1),因此 C.1, ..., Z.1 被认为是可以接受的并排队。当 B 作为段 B.2 重传时(使用最新的时间戳),它会填充空洞并导致通过 Z 的所有段都得到确认并传递给用户。排队的段的时间戳此时*不会*再次检查,因为它们已经被接受。当 B.2 被接受时,TS.Recent 设置为 2。

该规则允许在损失情况下的合理性能。一个完整的数据窗口一直在传输中,丢失后一个完整的窗口少一个段将出现乱序以在接收器排队(例如,最多 ~2^30 字节的数据); Timestamps 选项不得导致丢弃此数据。

在某些不太可能的情况下,规则 R1-R5 的算法可能会导致不必要地丢弃某些段,如下例所示:

再次假设段:A.1, B.1, C.1, ..., Z.1 已按顺序发送并且该段 B.1 已丢失。此外,假设 C.1、...Z.1 中的一些的传送被延迟,直到*在*重传 B.2 到达接收器之后。这些延迟的段在到达时将被不必要地丢弃,因为它们的时间戳现在已经过时了。

这种情况发生的可能性很小。如果重传是由超时触发的,则某些段 C.1、... Z.1 的延迟时间必须长于 RTO 时间。这大概是一个不太可能发生的事件,否则会有很多虚假的超时和重传。如果 B 的重传是由“快速重传”算法触发的,即由重复的 <ACK> 触发,那么引起这些 <ACK> 的排队段肯定已经被接收。

即使一个段被延迟超过 RTO,快速重传机制 [Jacobson90c] 将导致延迟的段在 B.2 的同时被重传,避免额外的 RTT,因此,导致非常小的性能损失。

我们不知道时间戳会因不必要地丢弃段而导致性能下降的发生概率很高的情况。

5.4.时间戳时钟

重要的是要了解 PAWS 算法不需要发送方和接收方之间的时钟同步。发送方的时间戳时钟用作单调非递减值的来源以标记段。接收器将时间戳值视为简单的单调非递减序列号,与时间没有任何联系。从接收者的角度来看,时间戳充当序列号高位的逻辑扩展。

接收器算法确实对时间戳时钟的频率提出了一些要求。

   (a) 时间戳时钟不能“太慢”。

每发送 2^31 个字节,它必须至少打勾一次。事实上,为了对发送方的往返计时有用,时钟应该至少为每个窗口的数据滴答一次,即使使用第 2.2 节中定义的窗口扩展,2^31 字节必须至少为两个视窗。

为了使这更量化,任何快于 1 滴答/秒的时钟都将拒绝旧的重复段,以达到约 8 Gbps 的链接速度。 1 ms 时间戳时钟将在高达 8 Tbps (8*10^12) bps 的链路速度下工作!

   (b) 时间戳时钟不能“太快”。

时间戳时钟的回收时间必须大于 MSL 秒。由于时钟(时间戳)为 32 位,最坏情况下的 MSL 为 255 秒,因此可接受的最大时钟频率为每 59 ns 一次滴答。

然而,需要建立更长的回收期,以便处理空闲连接上的过时时间戳(参见第 5.5 节),并放宽 MSL 要求以防止序列号回绕。使用 1 ms 时间戳时钟,32 位时间戳将在 24.8 天内包装其符号位。因此,如果 MSL 为 24.8 天或更短,它将拒绝同一连接上的旧重复项。这似乎是一个非常安全的数字; 24.8 天或更长的 MSL 可能在 Internet 中被假定,而不需要精确的 MSL 执行。

基于这些考虑,我们选择了一个时间戳时钟频率,范围为 1 ms 到 1 sec/tick。这个范围也符合 RTTM 机制的要求,它不需要比重传定时器的粒度更多的分辨率,例如几十或几百毫秒。

PAWS 机制还对发送方的时间戳时钟提出了很强的单调性要求。满足此要求的时间戳时钟的实现方法取决于系统硬件和软件。

   o 一些主机有一个硬件时钟,保证硬件复位之间的单调性。

   o 时钟中断可用于简单地周期性地将二进制整数加 1。

   o 时间戳时钟可以源自系统时钟,该系统时钟会通过添加可变偏移值而突然改变。该偏移被初始化为零。当需要新的时间戳时钟值时,可以根据需要调整偏移量,使新值等于或大于之前的值
(为此目的而保存)。

   o 可以在每个连接的基础上向时间戳时钟添加随机偏移量。请参阅 [RFC6528],第 3 节,关于随机化初始序列号 (ISN)。可以使用具有不同密钥的相同函数来生成每个连接的时间戳偏移。

5.5.过时的时间戳

如果一个连接保持空闲足够长的时间让另一个 TCP 的时间戳时钟包装它的符号位,那么保存在 TS.Recent 中的值将变得太旧;结果,PAWS 机制将导致所有后续段被拒绝,冻结连接(直到时间戳时钟再次包装其符号位)。

使用所选的时间戳时钟频率范围(1 秒到 1 毫秒),包装符号位的时间将在 24.8 天到 24800 天之间。闲置超过 24 天然后恢复正常的 TCP 连接是非常不寻常的。然而,原则上不希望对 TCP 连接寿命进行任何限制。

因此,我们要求 PAWS 的实现包括一种在连接空闲超过 24 天时“使”TS.Recent 值“无效”的机制。 (过时时间戳问题的另一种解决方案是以非常低的速率发送保持活动的段,但仍然比时间戳的环绕时间更频繁,例如,每天一次。这将带来可以忽略不计的开销。然而,TCP 规范从未包含过保活,因此选择了基于失效的解决方案。)

请注意,一个 TCP 不知道另一个 TCP 的频率,因此也不知道环绕时间,因此它必须假设最坏的情况。仅当基本 PAWS 时间戳检查失败时才需要检查 TS.Recent 的有效性,即仅当 SEG.TSval < TS.Recent 时。如果发现 TS.Recent 无效,则无论时间戳检查是否失败,都会接受该段,并且规则 R3 使用来自新段的 TSval 更新 TS.Recent。

例如,为了检测连接空闲多长时间,TCP 可以更新与连接关联的时钟或时间戳值,例如,每当 TS.Recent 更新时。细节将取决于实现。

5.6.头部预测

“头部预测”[Jacobson90a] 是一种高性能传输协议实现技术,对高速链路最重要。此技术针对最常见的情况优化代码,正确且按顺序接收段。使用报头预测,接收者会问这样一个问题:“这个片段是下一个片段吗?”这个问题可以用比“这个段在窗口内吗?”这个问题更少的机器指令来回答。

将头部预测添加到我们的时间戳程序会导致以下推荐的序列来处理到达的 TCP 段:

   H1) 检查时间戳(与上面的步骤 R1 相同)。

   H2) 做头部预测:如果该段在序列中的下一个并且如果没有需要额外处理的特殊条件,则接受该段,记录其时间戳,并跳过H3。

   H3) 按照 RFC 793 中的规定,正常处理该段。这包括丢弃窗口外的段并可能发送确认,以及对窗口内的无序段进行排队。

另一种可能性是将步骤 H1 和 H2 互换,即执行头预测步骤 H2 *first*,并且仅在头预测失败时执行 H1 和 H3。这可能是一种性能改进,因为步骤 H1 中的时间戳检查不太可能失败,并且它需要无符号模运算。对每个单独的段执行此检查与标题预测的原理相反。我们相信这种变化可能会显着减少高速网络上 TCP 协议处理的 CPU 时间。

但是,将 H2 放在首位会产生危险:过去 2^32 个字节的段可能会在完全错误的时间到达并被头部预测步骤错误地接受。 [RFC1185] 中引入了以下推理以表明此故障的概率可以忽略不计。

如果所有段出现作为旧副本的可能性相同,则旧副本与左窗口边缘完全匹配的概率是最大段大小 (MSS) 除以序列空间的大小。这个比率必须小于 2^-16,因为 MSS 必须 < 2^16;例如,对于 [a 100 Mbit/s] 链接,它将是 (2^12)/(2^32) = 2^-20。

但是,段越旧,它在 Internet 中保留的可能性就越小,并且在任何合理的段生命周期模型下,恰好在左窗口边缘的旧副本的概率必须远小于 2^-16。

16 位 TCP 校验和还允许 2^16 中的一部分基本不可靠。可靠性超过 TCP 校验和可靠性的协议机制应被视为“足够好”,即它不会对整体错误率产生显着影响。因此,我们相信我们可以通过在检查时间戳之前进行头部预测来忽略旧副本被接受的问题。 [注意:取幂的符号已从它在 RFC 1185 中出现的方式更改。]

然而,这种概率论点并未被普遍接受,目前的共识是,在一般情况下,性能提升并不能证明风险是合理的。因此,建议 H2 跟随 H1。

5.7. IP分片

在高数据速率下,PAWS 提供的针对旧段的保护可能会被 IP 片段重组中的错误所规避(参见 [RFC4963])。防止不正确的 IP 分段重组的唯一方法是不允许分段分段。这是通过在 IP 报头中设置 Don't Fragment (DF) 位来完成的。

设置 DF 位意味着使用 [RFC1191]、[RFC1981] 和 [RFC4821] 中描述的路径 MTU 发现;因此,任何实现 PAWS 的 TCP 实现也必须实现路径 MTU 发现。

5.8.早期连接的复制品

PAWS 机制可防止由于高速连接上的序列号环绕而导致的错误。来自同一连接的早期化身的段也是旧重复错误的潜在原因。在这两种情况下,防止此类错误的 TCP 机制取决于 Internet (IP) 层对 MSL 的实施(有关详细讨论,请参阅 RFC 1185 的附录)。与序列空间回绕的情况不同,防止来自早期化身的旧重复错误所需的 MSL 不依赖于传输速率。如果 IP 层强制执行建议的 TCP 的 2 分钟 MSL,并且如果遵循 TCP 规则,则无论网络速度有多高,TCP 连接都不会受到早期化身的影响。因此,这种情况不需要 PAWS 机制。

我们可能仍然会问 PAWS 机制是否可以针对来自早期连接的旧副本提供额外的安全性,允许我们放松 IP 层对 MSL 的执行。附录 B 探讨了这个问题,表明除了 PAWS 的假设和/或机制之外,还需要进一步的假设和/或机制。这不是当前扩展的一部分。

6. 总结和致谢 (略)

7. 安全考虑

TCP 序列空间是固定大小,随着窗口变大,攻击者更容易生成可以落入 TCP 窗口并被接受为有效段的伪造数据包。虽然使用时间戳和 PAWS 可以帮助缓解这种情况,但在使用 PAWS 时,如果攻击者能够伪造 TCP 连接可接受的数据包,那么未来的时间戳将导致由于 PAWS 丢弃有效段检查。因此,实现者应注意不要在超出连接要求的范围内大幅打开 TCP 窗口。

请参阅 [RFC5961] 以了解盲窗攻击的缓解策略。

直接从系统正常运行时间时钟导出时间戳时钟值的简单实现可能会无意中将此信息泄露给攻击者。这不会直接损害本文档中描述的任何机制。然而,这对于潜在的攻击者来说可能是有价值的信息。因此,建议在生成 Timestamps 选项值(参见第 5.4 节)时生成一个随机的、每个连接的偏移量以与时钟源一起使用。通过仔细选择这个随机偏移量,[RFC6191] 中描述的进一步改进是可能的。

当本地网络支持大于 64 KiB 的数据包时,将 TCP 窗口扩展到 IPv6 超过 64 KiB 允许使用 Jumbograms [RFC2675]。当使用更大的 TCP 段时,TCP 校验和变得更弱。

保护 TCP 报头不被修改的机制也应该保护 TCP 选项。

中间件和 TCP 选项:

已知一些中间件会从 TCP 段 [Honda11] 中删除本文档中描述的 TCP 选项。从 <SYN> 段中删除本文档中描述的 TCP 选项的中间件会干扰适合会话的参数选择。删除 <SYN,ACK> 段中的任何这些选项将使终端主机处于破坏协议正确操作的状态。

       * 如果从 <SYN,ACK> 段中删除窗口缩放选项,则终端主机将无法正确协商窗口缩放因子。 Middleboxes 不得从 <SYN,ACK> 段中删除或修改 Window Scale 选项。

      * 如果状态防火墙使用 window 字段来检测接收到的段是否在当前窗口内,并且不支持 Window Scale 选项,它将无法正确确定数据包是否在窗口内。这些中间框还必须支持 Window Scale 选项并在处理段时应用比例因子。如果无法确定窗口比例因子,则不得进行基于窗口的处理。

    * 如果从 <SYN> 或 <SYN,ACK> 段中删除 Timestamps 选项,则需要 PAWS 的高速连接将无法获得该保护。 Timestamps 选项的成功协商会强制对接收方的传入段进行更严格的验证。如果在成功协商后(例如,作为重新分段的一部分)从后续数据段中删除了 Timestamps 选项,则该段将被接收方丢弃而无需进一步处理。 Middleboxes 不应删除 Timestamps 选项。

      * 必须注意的是,[RFC1323] 并未解决协商后丢弃或选择性省略 Timestamps 选项的情况,并且本文档中的更新可能会导致检测到一些损坏的中间盒行为(可能无响应的 TCP 会话) .

依赖于 PAWS 的实现可以为应用程序提供一种机制来确定 PAWS 是否在连接上使用,并在不存在该保护的情况下选择终止连接。这不仅是为了保护连接免受可能删除时间戳选项的中间件的影响,而且是为了防止不支持时间戳的远程主机。

附录 A 实施建议

TCP 选项布局

建议使用以下布局在非 <SYN> 段上发送选项,以实现 32 位和 64 位机器的最大可行对齐。

与 TCP 紧急指针的交互

TCP 紧急指针与 TCP 窗口一样,是一个 16 位值。 TCP Window Scale 选项的一些原始讨论包括将紧急指针增加到 32 位的建议。事实证明,这是不必要的。有两点需要注意:

      (1) 使用 IP 版本 4,单个数据包中可以发送的最大 TCP 数据量为 65495 字节(64 KiB - 1 - 固定 IP 和 TCP 头部的大小)。

      (2) 当用户处于“紧急模式”时对紧急指针的更新对用户是不可见的。

这意味着如果紧急指针指向超出当前段中 TCP 数据的末尾,则用户将保持紧急模式,直到下一个 TCP 段到达。该段会将紧急指针更新为新的偏移量,用户将永远不会离开紧急模式。

因此,为了正确实现紧急指针,发送 TCP 只需在填充 16 位紧急指针字段之前检查是否溢出。如果确实溢出,则应将值 65535 插入紧急指针。

相同的技术适用于 IP 版本 6,但 IPv6 Jumbograms 除外。当支持 IPv6 Jumbograms 时,[RFC2675] 需要额外的步骤来处理紧急指针;这些步骤在 [RFC2675] 的第 5.2 节中描述。

附录 B. 来自早期连接化身的副本

有两种情况需要考虑:(1)系统崩溃(并失去连接状态)并重新启动,以及(2)在不丢失主机状态的情况下关闭并重新打开同一连接。这些将在以下两节中描述。

B.1.状态丢失导致系统崩溃

TCP 在系统启动时的一个 MSL 安静时间处理系统崩溃/重新启动时连接状态的丢失。例如,有关解释,请参见 TCP 协议规范 [RFC0793] 中的“知道何时保持安静”。此处所需的 MSL 不取决于传输速度。当前 2 分钟的 TCP MSL 作为一种操作妥协似乎是可以接受的,因为许多主机系统过去在崩溃后需要这么长时间才能启动。当前的主机系统可以更快地启动。

时间戳选项可用于简化 MSL 要求(或提供额外的安全性以防止数据损坏)。如果正在使用时间戳并且可以保证时间戳时钟在系统崩溃/重启时是单调的,即,如果可以保证崩溃/重启后发送方时间戳时钟的第一个值大于之前的最后一个值重启,那么安静的时间是不必要的。

要完全取消静默时间,就需要将主机时钟与在崩溃/重启期间稳定的时间源同步,精度为一个时间戳时钟滴答或更高的精度。我们可以放弃这个严格的要求,以利用近似时钟同步。假设时钟总是重新同步到 N 个时间戳时钟滴答内,并且启动(如果需要,延长一个安静时间)需要超过 N 个滴答。这将保证时间戳的单调性,即使没有强制 MSL,它也可以用来拒绝旧的重复项。

B.2.关闭和重新打开连接

当 TCP 连接关闭时,TIME-WAIT 状态下的 2*MSL 延迟会占用套接字对 4 分钟(参见 [RFC0793] 的第 3.5 节)。建立在 TCP 上的应用程序关闭一个连接并打开一个新连接(例如,使用 Stream 模式的 FTP 数据传输连接)每次都必须选择一个新的套接字对。 TIME-WAIT 延迟有两个不同的目的:

(a) 实现 TCP 的全双工可靠紧密握手。

延迟最后关闭步骤的适当时间与 MSL 没有真正的关系;它取决于 FIN 段的 RTO,因此取决于路径的 RTT。 (可以争论的是,发送 FIN 的一方知道它需要什么程度的可靠性,因此它应该能够确定 FIN 接收方的 TIME-WAIT 延迟的长度。这可以通过适当的 TCP 来实现FIN 段中的选项。)

尽管 RTT 没有正式的上限,但常见的网络工程实践使得 RTT 超过 1 分钟的可能性很小。因此,TIME-WAIT 状态中的 4 分钟延迟可以令人满意地提供可靠的全双工 TCP 关闭。再次注意,这与 MSL 实施和网络速度无关。

如果应用程序需要以非常高的频率重复关闭一个连接并打开另一个连接,TIME-WAIT 状态可能会导致间接性能问题,因为主机上可用的 TCP 端口数少于 2^16。然而,高网络速度并不是造成这个问题的主要因素。 RTT 是连接打开和关闭速度的限制因素。因此,这个问题在高传输速度下不会更糟。

   (b) 允许旧的重复段过期。

为了取代 TIME-WAIT 状态的这个功能,一种机制必须跨连接运行。 PAWS 是在单个连接内严格定义的;最后一个时间戳 (TS.Recent) 保存在连接控制块中,并在连接关闭时丢弃。

可以向 TCP 添加额外的机制,即从任何连接接收到的最后时间戳的每主机缓存。如果可以保证时间戳时钟自旧连接打开以来至少滴答一次,则该值可以在 PAWS 机制中用于拒绝来自连接的早期化身的旧重复段。这将要求 TIME-WAIT 延迟加上 RTT 必须至少是发送方时间戳时钟的一个滴答声。这种扩展不是本 RFC 提案的一部分。

请注意,这是 Garlick、Rom 和 Postel [Garlick77] 提出的机制的变体,该机制要求每个主机维护包含每个连接上最高序列号的连接记录。改用时间戳,只需为每个远程主机保留一个数量,而不管与该主机同时连接的数量如何。

附录 C. 符号总结

本文档中使用了以下符号。

选项

      WSopt:TCP 窗口缩放选项
      TSopt:TCP 时间戳选项

选项字段

      shift.cnt:WSopt 中的窗口缩放字节
      TSval:TSopt 中的 32 位时间戳值字段
      TSecr:TSopt 中的 32 位时间戳回复字段

当前段中的选项字段

      SEG.TSval:来自当前段中 TSopt 的 TSval 字段
      SEG.TSecr:当前段中来自 TSopt 的 TSecr 字段
      SEG.WSopt:WSopt 中的 8 位值

时钟值

      my.TSclock:系统范围内的 32 位时间戳值来源
      my.TSclock.rate:my.TSclock 的周期(1 毫秒到 1 秒)
      Snd.TSoffset:用于随机化 Snd.TSclock 的偏移量
      Snd.TSclock: my.TSclock + Snd.TSoffset

每个连接状态变量

      TS.Recent:最新收到的时间戳
      Last.ACK.sent:最后发送的ACK字段
      Snd.TS.OK:1 位标志
      Snd.WS.OK:1 位标志
      Rcv.Wind.Shift:接收窗口缩放指数
      Snd.Wind.Shift:发送窗口比例指数
      Start.Time:发送被计时的段时的 Snd.TSclock 值(由 RFC 1323 之前的代码使用)。

程序

      Update_SRTT(m) 更新平滑 RTT 和 RTT 方差估计的过程,使用 [Jacobson88a] 的规则,给定 m,一个新的 RTT 测量

发送序列变量

      SND.UNA:发送未确认
      SND.NXT:发送下一个
      SND.WND:发送窗口
      ISS:初始发送序列号

接收序列变量

      RCV.NXT:接收下一个
      RCV.WND:接收窗口
      IRS:初始接收序列号

附录 D. 事件处理总结 (略)

附录 E. 时间戳边缘情况

虽然为何时计算 RTTM 制定的规则在大多数情况下会产生正确的结果,但也有一些边缘情况可以计算出不正确的 RTTM。 所有这些情况都涉及到段的丢失。 人们认为这些情况很少见,如果发生,它们将导致单个 RTTM 测量膨胀,从而减轻其对 RTO 计算的影响。

[Martin03] 引用了两个类似的情况,即返回的 <ACK> 丢失,并且在重传计时器触发之前,另一个返回的 <ACK> 段到达,它确认数据。 在这种情况下,计算出的 RTTM 将被夸大:

关于这种情况需要注意的一点是,它在某种程度上受到 RTO + RTT 的限制,限制了 RTTM 计算的距离。虽然可以构建更复杂的场景来产生更大的膨胀(例如,重传丢失),但这些场景涉及多个段丢失,并且与在 RTO 计算中使用膨胀的 RTTM 相比,连接将存在其他更严重的操作问题。

附录 F. 窗口收回示例

考虑使用比例因子 128、Snd.Wind.Shift=7 和 Rcv.Wind.Shift=7 建立的 TCP 连接,该连接以非常小的窗口运行,因为接收器存在瓶颈并且两端都在进行少量读取和写入.

考虑返回的 ACK:

SEG.ACK SEG.WIN 计算 SND.WIN 接收者的实际窗口
   1000 2 1256 1300

发送方写入 40 个字节和接收方 ACK:

   1040 2 1296 1300
发送方额外写入 5 个字节,接收方出现问题。
两种选择:

   1045 2 1301 1300 - 超越缓冲器

   1045 1 1173 1300 - 伸缩窗

这是一个普遍的问题,并且在发送方进行写操作时可能会发生,该写操作小于窗口比例因子。

在大多数堆栈中,当窗口大小大于某个小数量的段时,它至少会被部分遮挡,因为堆栈更喜欢宣布整数段的窗口,四舍五入到下一个比例因子。这种加上愚蠢的窗口抑制往往会导致不太频繁、较大的窗口更新。如果窗口向下舍入到段大小,则有更多机会推进窗口,而不是收回它,上面的 BEYOND BUFFER 情况。

附录 G. RTO 计算修改

每个窗口取多个 RTT 样本会缩短 [RFC6298] 中 RTO 机制计算的历史记录,下面的算法旨在保持 [RFC6298] 最初预期的类似历史记录。

在不考虑 ACK 压缩和 ACK 损失的情况下,大致知道一个拥塞窗口价值的数据将产生多少样本。此类事件将导致更多的路径历史反映在 RTO 的最终值中,并且是不重要的。此修改将确保在 RTO 估计中考虑类似的时间量,无论每个窗口采集多少样本:

      预期样本 = 天花板(飞行大小 /(短信 * 2))

      alpha' = alpha / 预期样本

      beta' = beta / 预期样本

请注意,ExpectedSamples 中的因子 2 是由于“延迟 ACK”造成的。在[RFC6298]的算法中不使用alpha和beta,而是使用alpha'和beta':

      RTTVAR <- (1 - beta') * RTTVAR + beta' * |SRTT - R'|

      SRTT <- (1 - alpha') * SRTT + alpha' * R'

      (对于每个样本 R')

附录 H. RFC 1323 的变化 (略)

标签:选项,窗口,TCP,发送,高性能,时间,连接,RFC7323
来源: https://blog.csdn.net/PiPiQ_Blog/article/details/118365614

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有