Linux tcp_ack 确认处理与 sack_update_reord 重排判断

发布时间:2026/11/6 2:14:43

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/11/5 3:27:30

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/10/30 21:47:56

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/11/4 14:09:57

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

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

2026/11/6 2:14:00

V2X网络中RSU与UAV协同部署优化方案

1. 项目概述与核心挑战在城市V2X(车联万物)网络中,路侧单元(RSU)和无人机(UAV)的协同部署一直是个棘手的优化问题。传统方法往往将基础设施部署和动态调度割裂处理,导致系统在面对真…

2026/11/6 2:14:00

轻量级TCP端口转发工具rinetd详解与应用

1. 端口转发工具的基本概念端口转发(Port Forwarding)是网络工程中一项基础但极其重要的技术,它允许将来自一个网络端口的流量重定向到另一个端口或另一台主机。这种技术在跨网络通信、服务暴露、内网穿透等场景中发挥着关键作用。在实际网络…

2026/11/6 2:14:00

企业400电话系统选型与智能通信实战指南

1. 400电话办理实战指南:从选型到落地的完整经验分享作为一名在企业通信领域摸爬滚打多年的从业者,我深知400电话对于企业客户服务的重要性。最近刚帮公司完成了一次400电话系统的升级改造,从传统方案切换到了山东中呼的智能通信系统。整个过…

2026/11/6 2:14:00

Google OA算法题解析与高效备战策略

1. 项目概述最近在准备Google在线评估(OA)的过程中,我再次遇到了熟悉的原题。这次两题都在十分钟内顺利解决,想和大家分享一下我的解题思路和备战经验。对于正在准备技术面试的朋友们来说,遇到原题固然幸运&#xff0c…

2026/11/6 2:14:00

企业微信群发系统架构设计与高可用实践

1. 企业级群发系统架构设计背景在私域流量运营成为企业标配的今天,企业微信作为连接客户的重要渠道,其群发功能的使用频率越来越高。但很多团队在初期往往采用简单的单机脚本方案,当业务规模扩大后就会遇到各种瓶颈。我曾经接手过一个客户案例…

2026/11/6 2:08:59

SVM三分类实战:SMO求解、OvO投票与决策边界可视化

简介:这份资料围绕支持向量机完成数据三分类的MATLAB实现,面向已了解SVM二分类基础、希望进一步掌握多分类策略与代码落地的学习者,也可供课程实验和算法对比使用。包内共6个文件,以5个m脚本和1个data数据文件为主,脚本…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/6 1:03:39

MCU晶振电路设计全解析:从负载电容计算到PCB布局调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑