1

我需要通过 TCP 连接创建一个虚拟 IP 网络。宿主系统是Linux,带有TUN/TAP内核驱动,很容易接收和重新注入虚拟网络的IP包。

困难的部分是将接收到的 IP 数据包传输到另一台主机。由于一些非技术原因,我只能通过 TCP 协议而不是 UDP 传输数据包。通过 UDP 传输 IP 数据包很容易,但使用 TCP 就变得很棘手,原因如下:

UDP 协议不支持重传/重排序,就像 IP 一样。因此,如果为每个接收到的虚拟 IP 数据包发送一个 UDP 数据包,内核 TCP/IP 协议栈仍会看到虚拟 IP 数据包丢失/重复/重新排序(如果这些“功能”,TCP/IP 需要这些数据包才能正常工作)丢失,虚拟网络上的 TCP 连接速度会受到影响)。如果通过 TCP 传输 IP 数据包,则所有必需的“功能”都将丢失,除非以某种方式模拟它们。

看来我必须在 TCP 连接上伪造某种数据包重复/丢失/重新排序,或者修补内核 TCP/IP 协议栈。这两种选择都不容易。

我的问题还有其他更简单的解决方案吗?还是我只是走错了方向?我全是耳朵。

==== 更新 ====

我正在考虑使用原始 IP 套接字(它可以在仍然使用 TCP 数据包的同时轻松摆脱物理网络上的所有 TCP 重新传输/重新排序的东西)来传输接收到的虚拟网络 IP 数据包。但是在接收主机上,我怎样才能只接收我感兴趣的数据包并将所有其他 IP 数据包返回到内核 TCP/IP 堆栈?

4

1 回答 1

5

首先,您不想通过 TCP 建立 VPN,因为您最终会使用 tcp-over-tcp。主要问题是您的内部 TCP 和外部 TCP 的计时器可能会有很大差异,这会对您的 TCP 会话可靠性产生负面影响。你可以在这里找到更长的解释。

UDP 协议不支持重传/重排序,就像 IP 一样。因此,如果为每个接收到的虚拟 IP 数据包发送一个 UDP 数据包,内核 TCP/IP 协议栈仍会看到虚拟 IP 数据包丢失/重复/重新排序(如果这些“功能”,TCP/IP 需要这些数据包才能正常工作)丢失,虚拟网络上的 TCP 连接速度会受到影响)。如果通过 TCP 传输 IP 数据包,则所有必需的“功能”都将丢失,除非以某种方式模拟它们。

这没有任何意义,如果你的外层使用 TCP 作为传输机制,没有什么能阻止你的内层仍然使用完整的 ip/tcp 堆栈,包括这些功能。就像我说的那样,它们可能会发生严重冲突,但这并不是说此功能会消失或完全中断。

似乎您实际上只想使用 TCP 来获取标头并忽略实际协议,这确实可以避免 tcp over tcp 的问题。然而,这又是一个非常糟糕的主意。防火墙、NAT、DPI、tcp 助推器的流处理变得越来越普遍,如果你伪造 TCP 数据包,你可能会加重这些盒子的压力,可能会再次破坏你自己的连接。

因此,您应该问自己为什么不能使用 UDP,以及是否没有其他协议(标头)可以使用,例如 GRE 或 L2TP。

于 2015-01-13T11:14:19.477 回答