Linux TCP 堆栈重复发送“TCP 窗口更新”而不确认任何数据

网络工程 通讯协议 协议理论 linux
2021-07-29 03:08:02

我的公司正在为低延迟目的开发自己的 TCP 堆栈,其中一个测试涉及在 Linux 4.11 上运行 128 个 ncat 实例以侦听端口 55000 到 55127,并通过我们自己的 TCP 堆栈将数据发送到另一台计算机上的 128 个线程中。在 128 个 ncat 服务器中。

显然,我们没有实现 TCP 协议的一部分。如下面的 pcap 所示,ncat 服务器立即发送“TCP 窗口更新”;该段的相对序列号和确认号均为“1”

我们的软件似乎没有正确处理这种情况,因为它继续发送越来越多的数据并最终阻塞,认为它已经发送了所有这些“未确认”的段,从而达到了拥塞窗口限制。

这些奇怪而奇妙的(seq=1 ack=1)数据包是什么??他们在 RFC 中的何处被提及,在这种情况下正确的行为是什么?

PCAP 的一部分在此处输入图片说明

1个回答

好的,经过一番调查,我了解到

1)syn握手中的数据是合法的,并且

2) 奇怪的段是重复的 acks 并且接收窗口更新合并为一个:第一个 256 字节的有效负载块实际上在接收帧和将其进一步传递到堆栈之间的 Linux 内核中的某个地方丢弃。

由于窗口更新,这不会在我们的软件中触发快速重传,预期行为(因为我们没有实现 SACK)是超时重传。,我调试的时候把段重传功能注释掉了,忘记还原了。

我希望这些发现对偶然发现类似问题的其他人有所帮助。