SACK 报告缺口之后已收到的范围,帮助定位需要恢复的数据
TCP 累计确认标识按序接收时下一个期待的字节。如果某段缺失、后续字节却已到达,累计确认不能跨过这个空洞。选择确认 SACK 补充报告累计边界之后已经收到的字节范围,帮助发送端区分真正缺失的数据与接收端已经排队的数据。它改善恢复算法获得的信息,而不是替代全部丢包判断、拥塞控制或应用交付语义。 坏掉的样子 没有 SACK,并不意味着累计 ACK 强制发送端重传后面的每一个段。发送端仍可根据重复确认、计时器和恢复算法推断丢失,只是反馈不够明确,尤其在存在多个缺口时。把普通 TCP 描述为必须重发整个后缀,是把信息能力的限制误写成强制恢复策略,会夸大差异,也无法准确解释真实抓包中的局部重传。 SACK 块报告已经收到的范围,不是直接列出缺失范围。每块在序列空间中具有包含的左边界和不包含的右边界。缺口需要结合这些块、累计确认及尚未确认数据推导。SACK 不改变普通 ACK 字段含义,应用仍获得有序字节流,而不是乱序的选择确认块。传输层暂存后续字节,并不等于已经把它们交给应用。 该能力还需要对当前连接取得许可。SYN 中的 SACK-Permitted 表示发送该 SYN 的一端允许对端向自己发送 SACK 选项,不证明一次无丢失传输中实际出现过 SACK 块。反过来,缺少 SACK 也不自动证明防火墙剥离选项。判断原因之前应核对端点设置与真实握手,不能把某种中间设备问题当成唯一解释,忽略连接本身的协商条件。 快速验证 将脚本保存为 check-sack.py,准备 Docker 后运行 python3 check-sack.py。一次性环境使用 Python 3.11.16、iproute2 6.1.0、nftables 1.0.6 和 tcpdump 4.99.3,在 Linux 6.12.76 上验证。NET_ADMIN 与 SYS_ADMIN 支持嵌套网络命名空间及临时 proc 挂载。实验仅使用新建 veth 和命名空间内部设置,不改变宿主现有流量: ...