【问题标题】:TCP client does not send ACK while handshakingTCP客户端在握手时不发送ACK
【发布时间】:2014-04-27 11:42:11
【问题描述】:

我的测试环境

客户

  • IP 192.168.0.2/24
  • 网关 192.168.0.1

服务器

  • IP 192.168.0.1/24
  • http 服务在 80 端口运行

当我尝试将网页托管在服务器上时,一切正常。

然后我在服务器上使用 netfilter 编写一个内核模块,如果源 dest IP 是 192.168.1.1,它将更改 dest IP 为 192.168.0.1,如果源源 IP 是 192.168.0.1,则将源 IP 更改为 192.168.1.1 .我想你可以理解,我只是为客户端假装服务器是192.168.1.1。(IP头校验和和TCP校验和正确更改)

我在客户端使用浏览器(chrome, firefox...)访问192.168.1.1并在客户端抓包,结果如下:

192.168.0.2:someport_1 -> 192.168.1.1:80 [SYN]
192.168.1.1:80 -> 192.168.0.2:someport_1 [SYN, ACK]
192.168.0.2:someport_2 -> 192.168.1.1:80 [SYN]
192.168.1.1:80 -> 192.168.0.2:someport_2 [SYN, ACK]
192.168.0.2:someport_3 -> 192.168.1.1:80 [SYN]
192.168.1.1:80 -> 192.168.0.2:someport_3 [SYN, ACK]

我不知道为什么客户端永远不会发送TCP握手的最后一个ACK,有什么想法吗?

编辑1:

现在我认为浏览器没有从服务器获取 [SYN, ACK] 数据包,虽然 Wireshark 可以看到它,所以可能是因为操作系统(Windows7)从服务器丢弃了 [SYN, ACK] 数据包.现在问题变成了为什么windows会丢弃一个正确的[SYN,ACK]数据包?

【问题讨论】:

    标签: tcp netfilter


    【解决方案1】:

    你说 IP 校验和没问题,但是 TCP 校验和呢?它是从包含源 IP 和目标 IP 的伪标头计算出来的?

    【讨论】:

    • 很抱歉缺少 tcp 校验和的信息。 tcp checksum也可以,但是还是没有last ack……好像是客户端的OS丢掉了服务器的[SYN, ACK]包,所以浏览器拿不到,而wireshark可以看到?
    • 其他提示:您是否在事件查看器中搜索错误消息?您是否禁用了防火墙?
    • 谢谢。我找到了原因并回答了我自己的问题。
    【解决方案2】:

    我犯了三个错误。

    第一个是skb可以非线性,这会导致csum_partial()得到的校验和不正确。

    第二个是我使用csum_tcpudp_magic()来获取校验和,但是忘记改skb->ip_summed,所以网卡会使用我正确的校验和作为tcp伪的部分校验和——头重新计算校验和,导致数据包中的校验和不正确。

    第三个错误是我的wireshark似乎设置为忽略tcp校验和,它总是将校验和错误的数据包显示为好的数据包,而tcpdump会告诉我校验和不正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 2017-10-09
      • 2018-09-19
      相关资源
      最近更新 更多