对于我的下一个自虐业余项目,我正在尝试使用 UDP 隧道实现一个基本的匿名协议,其他流量可以通过该隧道流动。我想使用 UDP,因为它提供高吞吐量并防止 TCP over TCP 可能发生的超时崩溃。
匿名网络中的每个用户都成为一个节点,并成为其他用户隧道的一部分。每个节点必须能够处理多个隧道,从而将传入和传出的数据包识别为属于特定隧道。
确定数据包属于哪个隧道而不需要查看实际数据包数据的最佳方法是什么(如果可能,只需查看标头或连接)?是否有面向连接的 UDP 版本?
我对 UDP 的理解是这样的——它是无连接的,数据包头只是说明源/目标地址和源是什么。
我可以想出几种方法来利用这些信息:
- 欺骗数据包的源端口以保存与 IP 地址关联的 16 位连接 ID(因此在每台机器上,连接表是源或目标 IP + 连接 ID 的串联。这需要使用原始套接字并可能更少在系统之间可移植。我不知道构建 UDP 数据包并在另一端检查它们的开销是多少。
- 使用 UDP 数据包上的源端口作为唯一的连接 ID,但端口字段是 16 位的,因此这对于全局 ID 来说并不实用。我希望能够让应用程序能够使用任意端口,并且只需要一个端口。
- 使用建立在 UDP 之上的像 UDT 这样的协议——它仍然很快(据说是 UDP 速度的 1/4-1/3),检查可靠性,拥塞控制,并且有连接。虽然看起来很复杂,但我宁愿不必依赖专有(如果开源)库。最终,我需要在此基础上进行流加密,这样速度会更慢。
(1) 如果它增加了最小的开销,它似乎更可取。除了将数据包识别为给定隧道的一部分之外,我真的更喜欢仅使用单个任意端口,并且在 UDP 之上没有任何额外的东西。
编辑:减少开销的一种可能性是侦听 UDP 套接字并通过原始套接字发送,但这并不能解决主要问题。
EDIT2: Skype 或其他集中路由的流媒体服务如何工作?他们使用自己的协议吗?
EDIT3:关于 Xaxxon 的回答,我计划将匿名网络暴露给具有 tun 接口的用户空间程序。这将允许我在系统上运行任何我想要的流量——ssh、ftp 等。我不想弄乱与这些更高层协议相对应的数据包头。