发布时间:2026/7/21 12:15:32
Linux tcp_ack 确认处理与 sack_update_reord 重排判断 Linux tcp_ack 确认处理与 sack_update_reord 重排判断tcp_ack 是 TCP 输入路径的确认处理核心函数在 tcp_rcv_established 和 tcp_rcv_state_process 中被调用。该函数处理传入 ACK 段所携带的累积确认和选择确认SACK信息负责更新发送窗口、调整拥塞状态、触发 cwnd 恢复以及判断报文重排序程度。tcp_ack 的返回值是累计确认的报文段数量packets_acked为拥塞控制算法提供输入。cstatic int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag){struct tcp_sock *tp tcp_sk(sk);u32 prior_snd_una tp-snd_una;u32 ack_seq TCP_SKB_CB(skb)-end_seq;u32 ack TCP_SKB_CB(skb)-seq;u32 prior_packets tp-packets_out;int acked 0;if (after(ack, tp-snd_una)) {acked tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, sack_state);} else if (ack tp-snd_una) {if (flag FLAG_DSACKING_ACK)tcp_dsack_process(sk, skb, sack_state);tcp_update_wl(tp, ack);}if (tp-packets_out 0 flag (FLAG_SYN_ACKED | FLAG_DATA_ACKED))tcp_cong_control(sk, ack, flg, sack_state.rate, acked);...}tcp_clean_rtx_queue 是确认处理的核心——遍历重传队列sk_write_queue将 end_seq 落在 tcp_skb_cb-seq 到 TCP_SKB_CB(skb)-end_seq 范围内的 skb 移出队列。每个 skb 的 tcp_skb_cb-sacked 标志位决定该 skb 被确认、SACKed、还是 LOST。对于 ACK 确认的 skb调用 __skb_unlink 从重传队列移除并通过 sk_wmem_free_skb 释放 skb。acks 状态机需谨慎处理 D-SACK 检测当 ACK 确认了一段已经 SACKed 的数据tp-duplicate_sack[0] 记录第一个 D-SACK block用于计算 spurious retransmit。SACK 块在 tcp_sacktag_write_queue 中处理该函数被 tcp_ack 调用。每个 SACK block 表示接收端已收到的乱序数据区间。函数从 sk_write_queue 的 tcp_highest_sack 起始遍历标识被 SACK block 覆盖的 skb。cstatic void tcp_sacktag_write_queue(struct sock *sk,const struct sk_buff *ack_skb,u32 prior_snd_una,struct tcp_sacktag_state *state){struct tcp_sock *tp tcp_sk(sk);struct sk_buff *skb;int found_dup_sack 0;int i, first_sack_index;if (!tp-rx_opt.num_sacks)return;state-flag 0;state-fack_count 0;skb tcp_write_queue_head(sk);while (skb skb ! tcp_write_queue_tail(sk)) {if (!tcp_skb_is_write_queue(sk, skb))break;...skb skb-next;}}sack_update_reord 评估重排序程度。当发现 SACK block 覆盖的序列号区间早于已确认数据的末尾则该 SACK 块对应的 skb 在发送路径中序号连续但接收端乱序到达表明发生了 reordering。该函数的核心逻辑是如果被 SACK 确认的 skb 的 TCP_SKB_CB(skb)-seq 小于 tp-snd_una累积确认序列号则该数据段在发送缓冲区中的位置早于最新确认的数据发生了重排。cstatic void sack_update_reord(struct tcp_sock *tp,struct tcp_sacktag_state *state,u32 seq, u32 mss){if (seq_cmp(tp-snd_una, seq) 0) {if (!tp-reord || seq_cmp(tp-reord, seq) 0) {tp-reord seq;state-reord true;}}}tp-reord 字段记录重排序边界用于区分丢包和乱序。如果 ACK/SACK 确认的 skb 序列号大于等于 tp-reord则不触发快速重传。tp-reord 在 tcp_mark_head_lost 中同样被用于丢包判决。这里的关键竞态当接收端延迟发送 SACKDelayed SACK时sender 可能将正常乱序误判为丢包导致 spurious RTO。reord 的初始值为 tp-snd_nxt 2 * MSS在三次握手完成后初始化。tcp_ack 中的 flag 位掩码传递关键信息FLAG_SND_UNA_ADVANCED、FLAG_DATA_ACKED、FLAG_SYN_ACKED、FLAG_DSACKING_ACK、FLAG_ECE、FLAG_LOST_RETRANS 等。flag 通过 tcp_sacktag_write_queue 和 tcp_clean_rtx_queue 累积生成最终传递到 tcp_cong_control。FLAG_ECE 标志决定是否启用 ECN 信号触发 cwnd 的减半而非丢包事件。cstatic void tcp_cong_control(struct sock *sk, u32 ack, u32 flag,const struct rate_sample *rs,int acked){if (flag FLAG_ECE)tcp_enter_cwr(sk);else if (flag FLAG_SND_UNA_ADVANCED)tcp_cwnd_reduction(sk, ack, rs, flag, acked);else if (flag FLAG_DATA_ACKED)tcp_cwnd_application_limited(sk);}dupack重复 ACK计数由 tcp_ack 中的 tp-snd_una 不变但 packets_out 不为零的情形触发。当 tp-snd_una 不前进且 SACK 不含新信息tp-packets_out 与 prior_packets 相等时记录 dupthresh由 RFC 6675 定义为 3。在 reordering 场景下优先使用 SACK 判定而非 dupack 计数跟踪 skb-sacked TCPCB_SACKED_ACKED 的位状态结合 fackets_out由 SACK 确认的 skb 数量决定是否调用 tcp_time_to_recover。一个边界场景是 SACK 块覆盖的数据已经被快速重传此时 tcp_mark_head_lost 可能因为 reord 信息不准确而产生额外的 LOST 标记导致 cwnd 虚幻收缩。为避免此问题tcp_clean_rtx_queue 清除 TCPCB_SACKED_RETRANS 位时需同步检查 seq 是否落入 retrans_hint 区域。如果 retransmitted skb 被确认但未被 sender 记录为有效的 LOSTtcp_sacktag_write_queue 的回溯检测会重置 retrans_stamp防止 RTO 过早触发。

相关新闻

2026/7/21 12:15:32

5分钟上手Buzz:彻底改变你的音频转录工作流

5分钟上手Buzz:彻底改变你的音频转录工作流 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Trending/buz/buzz 还在为会议录音整理而…

2026/7/21 12:10:31

JavaScript GIF解码架构解析:gifuct-js高效解决方案实现原理

JavaScript GIF解码架构解析:gifuct-js高效解决方案实现原理 【免费下载链接】gifuct-js Fastest javascript .GIF decoder/parser 项目地址: https://gitcode.com/gh_mirrors/gi/gifuct-js 在Web开发中处理GIF动画时,传统JavaScript库常面临性能…

2026/7/21 12:10:31

C2000 CLA协处理器:架构、中断配置与流水线优化实战

1. CLA核心架构与工作原理深度解析 控制律加速器(CLA)是德州仪器(TI)C2000系列微控制器中一个独立、可编程的32位浮点数学协处理器。它的设计初衷非常明确:将主CPU(C28x)从繁重的实时控制算法计…

2026/7/21 19:36:41

command-line-args实战:构建一个完整的脚手架工具案例解析

command-line-args实战:构建一个完整的脚手架工具案例解析 【免费下载链接】command-line-args A mature, feature-complete library to parse command-line options. 项目地址: https://gitcode.com/gh_mirrors/co/command-line-args 你是否曾为Node.js命令…

2026/7/21 19:36:41

React Native ECharts社区贡献指南:如何为开源项目贡献力量

React Native ECharts社区贡献指南:如何为开源项目贡献力量 【免费下载链接】react-native-echarts Echarts for react-native. The react-naitve chart. 项目地址: https://gitcode.com/gh_mirrors/re/react-native-echarts React Native ECharts是一个专为…

2026/7/21 19:36:41

跨越设备鸿沟:如何用js-emoji让表情符号在任意平台完美显示

跨越设备鸿沟:如何用js-emoji让表情符号在任意平台完美显示 【免费下载链接】js-emoji A JS Emoji conversion library 项目地址: https://gitcode.com/gh_mirrors/js/js-emoji 在今天的数字世界里,表情符号已经成为我们在线沟通的通用语言。然而…

2026/7/21 19:31:41

Sulphur-2视频生成AI终极指南:从零开始掌握本地部署技巧

Sulphur-2视频生成AI终极指南:从零开始掌握本地部署技巧 【免费下载链接】Sulphur-2-Base-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/vantagewithai/Sulphur-2-Base-GGUF 想要在本地电脑上运行强大的AI视频生成模型吗?Sulphur-2-Base-G…

2026/7/20 6:33:00

Unity与Python本地通信:基于Flask的跨语言数据交换实战

1. 项目概述:为什么我们需要一个本地通信服务器?在游戏开发、数字孪生、仿真训练等众多领域,Unity作为强大的实时3D内容创作平台,其核心逻辑通常由C#驱动。然而,当我们需要进行复杂的数据分析、机器学习推理、科学计算…

2026/7/21 0:08:52

华为OD机试 新系统真题 【酒店服务记录分析】

酒店服务记录分析(C++/Go/C/Js/Java/Py)题解 华为OD机试 新系统真题 华为OD上机考试 新系统真题 7月19号 100分题型 华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解 题目内容 你是某连锁酒店的数据分析师,酒店每天都会用一串编…

2026/7/21 0:08:52

华为OD机试 新系统真题 【小明的顺风车】

小明的顺风车(C++/Go/C/Js/JAVA/Py)题解 华为OD机试新系统真题 华为OD上机考试新系统真题 7月19号 200分题型 华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解 题目内容 小明自驾回家,为节省旅途成本,决定在网上挂出顺风车服务…

2026/7/20 19:08:28

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…