TCP接收到数据包,但它忽略了它们
问题:TCP接收到数据包,但它忽略了它们
我有一个非常奇怪的网络问题。实际的网络配置是相当复杂的,因为我正在使用 Openstack 和 Docker 构建一个虚拟网络。但是,问题不存在,因为我在主机的接口上捕获并且我以正确的方式看到所有数据包....但是由于某些我不知道的原因,似乎 TCP 忽略了它们,尽管它们有已收到:它不会为它们发送 ACK,也不会将数据发送到应用程序。
在我的试验中,我从主机 (192.168.4.100) 向服务器码头 (IP 192.168.4.3) 发送了对 html 页面的 HTTP GET 请求。
我看到使用 Wireshark 在 192.168.4.100 上捕获的是:
192.168.4.100 -> SYN -> 192.168.4.3
192.168.4.3 -> SYN, ACK -> 192.168.4.100
192.168.4.100 -> ACK -> 192.168.4.3
192.168.4.100 -> GET / HTTP/1.1 -> 192.168.4.3
192.168.4.3 -> ACK -> 192.168.4.100
192.168.4.3 -> Fragment 1 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 1 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 1 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 1 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 1 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 1 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 1 of HTTP 200 OK response -> 192.168.4.100
192.168.4.100 -> ACK of Fragment 1 -> 192.168.4.3
192.168.4.3 -> Retransmission of Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 2 of HTTP 200 OK response -> 192.168.4.100
192.168.4.100 -> ACK of Fragment 2 -> 192.168.4.3
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.3 -> Retransmission of Fragment 3 of HTTP 200 OK response (PSH) -> 192.168.4.100
192.168.4.100 -> ACK of Fragment 3 -> 192.168.4.3
这实际上是一个大问题,因为在 GET 请求和最后一个 ACK 之间大约有 40 秒,这与应用程序(在本例中为 telnet)获取数据的时刻相吻合。
我检查了所有的校验和,它们是正确的......
所以我实际上不知道为什么会发生这种情况以及该怎么办!我曾尝试使用不同的操作系统作为主机(Windows 8 手机、MAC OSX、Ubuntu 14.04,...),但没有任何改变。如果我从虚拟网络的另一个 docker 发送相同的请求,一切正常。
关于问题可能是什么的任何想法?
谢谢!
PS在这里您可以看到捕获的屏幕截图:

更新
我认为有趣的一件事是我做了一个类似的捕获,但是当一个 HTTP 请求从 192.168.4.3 发送到 192.168.4.100 时。在 192.168.4.100 接口上再次进行捕获,并且 192.168.4.100 似乎再次忽略了它接收到的数据包(例如,查看三向握手)。我又找不到理由了。

解答
我设法解决了我的问题。我在这里发布解决方案,如果有人遇到我同样的问题,它可能会很有用。
问题是我在我的 Docker 连接到的虚拟网桥上禁用了 TSO(tcp-segmentation-offload),命令如下:
ethtool -K IFACE_NAME tso off
它只关闭 TSO,而校验和卸载仍然打开。显然,这会产生一些问题,尽管 Wireshark 向我显示 TCP 校验和是正常的,但实际上并非如此。因此,由于 TCP 校验和错误,主机忽略了该数据包。
要关闭 TSO 和校验和,我只使用了以下命令:
ethtool --offload IFACE_NAME rx off tx off
现在一切正常。
更多推荐
所有评论(0)