UDP打孔混乱
Posted
技术标签:
【中文标题】UDP打孔混乱【英文标题】:UDP Hole Punching Confusion 【发布时间】:2019-01-13 00:15:59 【问题描述】:您好,我对 UDP 打孔的工作原理以及如何实现它感到有些困惑。根据这篇***文章: https://en.m.wikipedia.org/wiki/UDP_hole_punching#Flow 想要建立 p2p 连接的客户端都必须与服务器建立 UDP 对话,以便交换 ip 和打孔。我感到困惑的是,假设客户 a 想要与客户 b 发起 p2p 对话。客户端 b 如何知道连接到服务器以便客户端交换 IP?这是必需的,否则他们将不知道其他客户端的 IP。我是否以某种方式误解了这个概念?
【问题讨论】:
客户端都需要知道如何联系服务器(不知何故),并且两个客户端都需要提前联系服务器,以便服务器知道它们正在运行。 那么我应该存储应用程序公共ip中存在的每个客户端并定期更新吗?这样每次一个客户端想要与另一个客户端通信时,它只会从服务器获取他们想要与之通信的客户端的 ip?抱歉,我对这些东西不熟悉。 一种方法是让每个客户端定期 ping 服务器(通过 UDP 数据包或 TCP 连接),并且每当服务器收到此 ping 消息时,它应该存储源 IP 地址(如由服务器上的 recvfrom() 或 getpeername() 返回)在本地数据结构中,以及客户端希望包含在 ping 数据中的任何标识信息。然后,每当另一个客户端向服务器查询客户端位置信息时,服务器将(希望)将该信息发送给客户端。 我在想类似的事情。感谢您的帮助。 【参考方案1】:在正常情况下,对等方没有静态 IP 地址,并且公共端口也是使用临时路由规则动态分配的,通常有效期为 1 到 3 分钟。
没有办法猜测双对等点的动态端口,即使没有预定义的转发规则,也无法立即建立到它的路由。
与通常转录的文档相比,通过路由器 + 互联网服务提供商的打孔实际上是通过将 UDP 数据包发送到公共中介服务器来完成的。
对等点通过重用确切地说是中介服务器当前看到的公共 ip/端口相互联系。
中介服务器的路由器必然有到服务器的转发规则,所以服务器是公共可达的,可以发起公共通信。
如果中介服务器没有静态地址,则需要公共 DNS 服务器来解析服务器的动态地址。
用于捕获本地端口映射并将数据包返回到正确的目标, 所有三个节点都将维护唯一静态节点标识符到传入数据包的当前 IP/端口的映射;每个客户端需要定期向中介服务器和对方发送带有客户端标识符的活动消息;中介服务器以一个活动确认消息进行响应,该消息携带中介服务器的当前公共地址/端口。这里要考虑路由器的可选端口映射规则来获取实际的公共端口。
远程端口的动态调整使得很难有几个独立的通信通道,至少我不知道UDP服务器的fork机制。
如果需要独立的沟通渠道,例如就像 FTP 一样,你有一个命令端口和一个流端口,数据包协议可以通过逻辑端口进行扩展,传入的数据包可以根据逻辑端口进行调度。
最后还有安全隐患:
1.) 任何嗅探路由路径的任何节点的人都可能劫持通信;他可以从不同的地址向其中一个对等方发送和激活消息,因此将继承对等方的通信流。 此处的最低解决方案是向活动消息添加身份验证。
2.) 当然,任何公共网络中的用户数据都必须加密! 由于 UDP 数据包传输的不确定性,只能基于数据包进行加密,例如AES/ECB 可以,因此应该选择 strong。
【讨论】:
以上是关于UDP打孔混乱的主要内容,如果未能解决你的问题,请参考以下文章