什么是p2p穿透技术?为什么它很难实现?

27

我正在尝试进行一些p2p网络的实验。在做了一些研究后,我发现最大的障碍之一是"如果客户端在NAT/防火墙后面怎么办",后来我发现了关于Hole Punching的知识,但它并不总是能保证成功。



就我所理解的而言,我不明白为什么它可能会失败,这是我目前所知道的:


enter image description here

根据上图,这是我理解如何建立一个成功连接的方式。

  1. Alice通过与目录服务器创建连接,加入了网络(1)。当这发生时,Alice的NAT会创建从她的公共IP到她的本地IP的映射。
  2. 目录服务器接收到连接并将Alice的公共ip:port存储在目录中。
  3. Bob也是同样的操作 (2),加入网络并将ip:port发布到目录中。
  4. Alice想要和Bob通信。因此,她从目录中查找Bobip:port(3)
  5. Alice通过服务器获取的Bobip:port发送数据。 (5)
  6. 由于Bob也将自己的ip:port映射到本地ip:port,因此NAT只需将在Bob的公共ip:port上收到的任何数据转发到他的计算机。
  7. 对于Alice同样适用。

  8. 我希望我的解释清楚了我理解的内容。我的问题是,为什么这个过程会很困难或不可靠?我肯定漏掉了什么重要的东西。你能向我解释一下吗?

5个回答

20

一个问题是Alice的NAT服务器中的NAT映射可能会超时,这可能是在固定时间后或者在一段不活动时间后。

第二个潜在的问题是,NAT服务器可能会限制Alice的NAT映射仅适用于由Alice建立的TCP连接,或者仅适用于Alice与初始IP之间的连接。(换句话说,Alice和Bob之间的直接通信可能被阻止。)

等等。

问题在于NAT服务器的行为高度依赖于管理组织的配置/策略决策。其中许多决策可能意味着您特定的P2P使用模式无法可靠地工作...甚至根本无法工作。


那么我的穿孔洞想法是错误的吗?

不是。只是意味着它不总是起作用。


非常好奇。我相信自PS3时代以来,像这样的游戏主机都使用了NAT p2p穿透技术。由于防火墙由各方管理,当穿透失败时,他们如何解决问题?您会将NAT p2p穿透技术与约会服务器配对使用吗? - Potion
  1. 通常情况下,PS3的所有者会攻击他们自己的(家庭)防火墙,更关注“游戏需求”而不是网络安全。因此,他们会找到一种方法。
  2. 对于许多应用程序来说,中继服务是行不通的。
- Stephen C

5
在NAT打洞中,最大的问题可能是端口一致性不足。为了使您的实现起作用,至少有两个NAT之一必须支持它。
端口一致性是指同一个(本地ip,本地端口)映射到相同的(外部ip,外部端口),无论目标(目标ip,目标端口)是什么。如果没有这个功能,目录服务器看到的端口对客户端没有帮助,因为客户端需要通信的端口将不会与其相同。
(请注意,这是一个比端口保留更弱的要求,其中外部端口==本地端口。)
不幸的是,对于P2P通信,大多数NAT都是某种类型的对称NAT,并且没有一致的端口映射。

4

防火墙通常是有状态的。当Bob(2)与外部目录服务器建立通信时,在他的NAT服务器中设置了一条规则,允许Bob和目录服务器进行通信。当NAT服务器看到来自Alice的数据包时,会拒绝/丢弃它们,因为它没有看到Bob与Alice建立通信。


4
首先,有两种类型的打洞技术: 1. UDP打洞 2. TCP打洞
UDP打洞成功率为82%,TCP打洞成功率为64%。我做了很多UDP打洞实验,它们大多数都成功了,但在TCP打洞方面情况并不相同。
TCP打洞失败的原因只是路由器NAT表。我会尽力解释:
客户端1 --> 连接(客户端2)--Internet-- 连接(客户端1)<-- 客户端2
现在,如果客户端1的SYN数据包到达客户端2,而客户端2的SYN数据包没有被释放,那么客户端2的路由器可以做两件事: 1. 向客户端1发送RST数据包,作为连接拒绝。 2. 立即丢弃数据包,并且不向客户端1发送回复。
如果发生这种情况,就无法建立连接。
我只能建议一个解决方案:两个客户端的连接调用之间的时间差应该非常小。连接调用的时间差应该在毫秒级别。
提示:如果您在本地网络中,请禁用防火墙。
对于Ubuntu用户:sudo ufw disable

0

我认为了解打洞技术的工作原理将有助于理解为什么它可能会失败。

这项技术最初由丹·卡格尔探索,可以在这里阅读。在这种技术中,通常假定两个对等方都在两个不同的NAT后面。两个对等方必须连接到一个名为Rendezvous/Signaling服务器的中间服务器;有许多著名的Rendezvous协议,其中SIP(RFC 3261)是最著名的协议。当它们连接到服务器时,它们通过服务器了解彼此的公共传输地址。公共传输地址由它们前面的NAT分配。简而言之,打洞过程如下:

enter image description here

  1. Peer 1和Peer 2首先使用RFC 8589中描述的STUN Bind Request发现其公共传输地址。
  2. 使用信令/消息机制,它们交换其公共传输地址。可以使用SDP(会话描述协议)[16]来完成此操作。 Peer 1和Peer 2的公共传输地址将分别由NAT 1和NAT 2分配。
  3. 然后,两个对等方尝试使用接收到的公共传输地址相互连接。对于大多数NAT,第一条消息将被NAT丢弃,除了Full Cone NAT之外。但是随后的数据包将成功穿透NAT,因为此时NAT将具有映射。

NAT可以是任何类型。如果NAT是对称NAT RFC 8489,则无法进行Hole Punching。因为只有从内部主机接收数据包的外部主机才能发送数据包回来。如果是这种情况,则唯一可能的方法是Relaying。

了解P2P通信的当前状态:阅读RFC 5128。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接