【问题标题】:How does Linux TCP stack handle invalid ACK sequence numbers?Linux TCP 栈如何处理无效的 ACK 序列号?
【发布时间】:2015-10-16 01:45:25
【问题描述】:

我只是在调试一个非常奇怪的问题,即移动客户端在从我的 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 堆栈源代码有点难以理解,因此非常欢迎指出源代码中的特定检查)。

【问题讨论】:

标签: linux tcp


【解决方案1】:

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

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

如果没有 FIN 标志,那么这确实是无效的,我假设内核会简单地丢弃无效的 ACK。

【讨论】:

  • 我知道 FIN 会增加序列号,但不,事实并非如此。连接被卡住了,没有关闭(好吧,它在客户端 -> 服务器方向上是半关闭的,但这在这里应该无关紧要)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 2017-05-31
相关资源
最近更新 更多