Linux TCP堆栈如何处理无效的ACK序列号?

时间:2015-07-25 12:45:22

标签: linux tcp

我正在调试一个非常奇怪的问题,当我的HTTP服务器下载文件时,移动客户端卡住了。客户端在Sierra Wireless Q2687 GSM模块上运行。

每次传输在完全13480字节(10个数据包,每个1348个有效载荷)之后挂起。我只看到上面提到的GSM模块存在这个问题,其他客户端运行良好。

我做了一些Wireshark调试,注意以下几点:

  • 从服务器到客户端的最后一个数据包的(相对)序列号为12133,有效载荷为1348字节
  • 客户端随后对数据包进行确认,发送的ACK序列号为13482,与预期的12133 + 1348 = 13481
  • 相比是逐个的
  • 在ACK之后,服务器根本不再发送数据包并且连接被卡住(我确信nginx有更多数据要发送,检查)。

所以,对我来说,它看起来像一个Sierra Wireless TCP堆栈的一个一个错误 - 确认了更多实际收到的数据。

问题:

  • 任何人都可以确认,序列号高于最高(received sequence number + length)的ACK会违反TCP规范吗?

  • 鉴于以上情况属实,Linux TCP堆栈如何处理这种情况? (如果没有先前的经验,TCP堆栈源代码有点难以理解,因此非常欢迎指向源代码中特定检查的指针。

1 个答案:

答案 0 :(得分:1)

  

任何人都可以确认,序列号高于最高值(接收序列号+长度)的ACK会违反TCP规范吗?

如果数据包设置了FIN标志,则对数据包的ACK将为序列+ 1。所以可能只是你错过了这面旗帜。这也可以解释你没有看到更多的数据,因为FIN意味着不会有更多的数据(即连接结束)。

如果没有FIN标志,那么确实无效,我认为内核只会丢弃无效的ACK。