TCP F-RTO浅析

F-RTO为了解决一个问题,RFC5682最开头有说:

It has been pointed out that the retransmission timer can expire spuriously and cause unnecessary retransmissions when no segments have been lost [LK00, GL02, LM03]. After a spurious retransmission timeout, the late acknowledgments of the original segments arrive at the sender, usually triggering unnecessary retransmissions of a whole window of segments during the RTO recovery. Furthermore, after a spurious retransmission timeout, a conventional TCP sender increases the congestion window on each late acknowledgment in slow start. This injects a large number of data segments into the network within one round-trip time, thus violating the packet conservation principle [Jac88].

F-RTO的目标是避免不必要重传,减少了网络上的数据包,这可有效减缓拥塞,是一个利他利己的效果,至于拥塞状态机的undo只是它的副作用。
造成虚假超时的原因大致两类:

  • 突发拥塞。这导致瞬时RTT升高,造成RTO重传。
  • 路由重收敛。这导致路径切换,新路径RTT偏高。

其中拥塞因素不再赘述,路由重收敛值得一提。

路由重收敛时间接近分钟级别,即使是小范围路由抖动也需秒级方可稳定,在TCP看来,RTO超时是必然的,RTO超时后即重传UNA,UNA将沿着新的路径到达对端并被ACK,接下来的做法,是理解F-RTO算法的核心。收到重传的UNA的ACK后,sender可以:

  • 重传UNA~RecoveryPoint。
  • 传输新报文。

如果重传UNA~RecoveryPoint,显然是没有必要的,徒增了网络负载,如果传输新报文,由于TCP是积累确认,接下来从返回的ACK就能判断RTO超时是真超时还是假超时了:

  • 若ACK包含SACK,则为真超时,迄今只发了UNA和新报文,SACK说明有空洞,实锤(大概率)丢包。
  • 若ACK确认了从未重传的报文,则必然为假超时,undo恢复。

F-RTO,顾名思义,其中的F就是Forward,即发送新报文的意思。
下图展示了标准RTO超时后的tcptrace图样例:
在这里插入图片描述
下面是启用F-RTO后的:
在这里插入图片描述
浙江温州皮鞋湿,下雨进水不会胖。

<think>嗯,用户这次的问题非常聚焦于Linux内核TCP实现的一个具体字段:tp->delivered。从提问的精准度来看,用户应该是有网络协议栈开发或性能调优需求的工程师,至少是熟悉TCP协议基本概念的研究者。用户能直接提到tp结构体成员,说明已经看过部分内核源码。 注意到用户引用了三个站内技术文档片段,其中引用[1]和[2]都涉及TCP发送队列管理机制,尤其引用[2]提到的tcp_fragment函数和TCPWQUEUETOOBIG计数器,与tp->delivered存在潜在关联——因为分片行为会影响实际交付的报文计数。不过用户核心诉求明确指向delivered字段的语义,需要重点解析这个字段的计量逻辑。 tp->delivered字段的官方定义在include/net/tcp.h里其实比较简略,需要结合tcp_input.c和tcp_output.c的上下文理解。它的核心价值在于实时追踪原始数据字节的传输进展,注意三个关键点: 1. 计量单位是字节而非报文段,这从tcp_ack()中tp->delivered += acked的累加方式可验证 2. 包含重传数据,因为网络丢包时该计数仍会累积(参考RFC6298的重传计时器机制) 3. 与TCPTSO机制有隐含互动,当GSO分片发生时,实际delivered增量可能大于MSS 用户可能真正关心的是如何利用这个字段做带宽评估。比如BBR算法正是通过delivered/delivered_mstamp计算即时带宽。但需要提醒用户注意delivered_mstamp的更新时机问题——它只在ACK到达时更新,可能导致采样间隙内的带宽估算偏差。 考虑到用户的技术深度,后续问题可以延伸到具体应用场景。比如如何基于/proc/net/tcp获取该值(需要修改内核暴露接口),或者解释delivered与RFC4898定义的DeliveredData的区别(后者是TCP选项需要额外计算)。</think>在 Linux 内核的 TCP 协议栈实现中,`tp->delivered` 是 `struct tcp_sock` 结构体的一个关键成员变量,主要用于**精确追踪实际交付给接收端应用层的数据量**。其核心作用与运作机制如下: --- ### **核心作用** 1. **计量已确认交付的数据量 (字节单位)** `tp->delivered` 记录的是**已被接收端成功接收并确认 (ACKed)** 且**对端应用层已消费**的数据总量(单位:字节)。它反映的是真正“有效交付”的数据,而非单纯发送出去的数据。 2. **支撑拥塞控制算法** 该字段是 BBR (Bottleneck Bandwidth and Round-trip propagation time) 等现代拥塞控制算法的核心输入: - **计算实时带宽**:通过采样周期内 `tp->delivered` 的增长量 Δdelivered 与时间间隔 Δt,计算瞬时带宽:$Bandwidth = \frac{\Delta delivered}{\Delta t}$。 - **判断网络瓶颈**:结合 RTT 测量,识别网络路径的带宽与延迟特性[^1]。 3. **启用 RACK (Recent ACK) 丢包检测** 在 RACK 机制中,`tp->delivered` 用作数据包的“发送序列号”,通过比较不同数据包的 `(tp->delivered, 发送时间戳)` 二元组,推断丢包事件的发生时机[^2]。 --- ### **运作机制详解** 1. **初始化** 连接建立时(如 SYN-ACK 到达),`tp->delivered` 初始化为 0: ```c tp->delivered = 0; // 初始无交付数据 ``` 2. **数据交付确认时的更新** 当收到接收端的 ACK 确认新数据时,内核在 `tcp_ack()` 函数中更新: ```c delivered = tp->delivered; // 记录更新前的值 (用于带宽计算) tp->delivered += newly_acked_bytes; // 增加本次确认的字节数 ``` 3. **记录数据包元信息** 数据包发送时(如调用 `tcp_transmit_skb()`),其当时的 `tp->delivered` 值会被记录到该包的 TCP 控制块中(`struct tcp_skb_cb->delivered`): ```c tcb->delivered = tp->delivered; // 标记该包发送时的全局交付量 ``` 此值代表“该包发送时,连接上已交付的总字节数”,用于后续计算该包本身的交付量。 4. **计算单包交付量** 当某个数据包被确认时,其**实际交付量** = `当前 tp->delivered - 该包记录的 tcb->delivered`。 例如: - 包 A 发送时:`tcb->delivered = 100` - 包 A 被确认时:`tp->delivered = 120` - 则包 A 的交付量 = $120 - 100 = 20$ 字节 --- ### **技术意义** - **精准拥塞控制**:BBR 依赖 `tp->delivered` 计算真实带宽,替代传统基于丢包或延迟的启发式方法,显著提升高带宽、高延迟网络下的性能[^1]。 - **丢包诊断优化**:RACK 通过比较数据包的 `(delivered, 发送时间)` 而非序列号,能更早、更准确地检测乱序和丢包[^2]。 - **性能监控基础**:该字段是计算吞吐量、传输效率的核心指标,可通过 `ss -t -i` 命令查看(输出中的 `delivery_rate` 和 `busy` 相关字段)。 ```bash $ ss -t -i ESTAB 0 0 192.168.1.2:443 192.168.1.3:55678 cubic wscale:7,7 rto:204 rtt:1.234/0.75 mss:1448 delivered:105600 // 连接累计交付量 (字节) delivery_rate:2.5Gbps // 基于delivered计算的瞬时带宽 ``` --- ### **与相关字段的对比** | 字段 | 含义 | 与 `tp->delivered` 的关系 | |------|------|---------------------------| | `tp->bytes_sent` | 累计发送字节数(含重传) | 始终 ≥ `tp->delivered` | | `tp->bytes_acked` | 累计确认字节数(含重传数据的确认) | 可能 > `tp->delivered`(存在乱序确认) | | `tp->snd_una` | 最早未确认序列号 | 用于计算 `newly_acked_bytes` 以更新 `delivered` | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值