TCP接收数据包,但忽略它们

mga*_*ido 5 networking tcp http openstack docker

我有一个非常奇怪的网络问题.实际的网络配置非常复杂,因为我使用Openstack和Docker来构建虚拟网络.然而,问题不存在,因为我正在我主机的接口上捕获并且我以正确的方式看到所有数据包......但由于某些原因我不知道,似乎TCP忽略了它们,尽管它们有已收到:它不会为它们发送ACK,也不会将数据发送到应用程序.

在我的试验中,我将html页面的HTTP GET请求发送到主机(192.168.4.100)的服务器码头(IP 192.168.4.3).

我在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
Run Code Online (Sandbox Code Playgroud)

这实际上是一个大问题,因为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再次忽略它接收的数据包(例如,查看三次握手).我再没有找到理由.

在此输入图像描述

mga*_*ido 2

我设法解决了我的问题。我在这里发布了解决方案,如果有人遇到我同样的问题,该解决方案可能会很有用。

问题是我使用以下命令禁用了 Docker 连接到的虚拟桥上的 TSO(tcp-segmentation-offload):

ethtool -K IFACE_NAME tso off
Run Code Online (Sandbox Code Playgroud)

它仅关闭 TSO,而校验和卸载保持打开状态。显然,这会产生一些问题,尽管 Wireshark 向我显示 TCP 校验和正常,但实际上并非如此。因此,由于 TCP 校验和错误,主机忽略了该数据包。

要关闭 TSO 和校验和,我只使用了以下命令:

ethtool --offload IFACE_NAME rx off tx off
Run Code Online (Sandbox Code Playgroud)

现在一切正常了。