实用的 NAT 穿越,以实现可靠的网络连接

Posted

技术标签:

【中文标题】实用的 NAT 穿越,以实现可靠的网络连接【英文标题】:Practical NAT traversal for reliable network connections 【发布时间】:2011-04-06 13:43:55 【问题描述】:

我已经看过并阅读了很多类似的问题,以及相应的***文章(NAT traversal、STUN、TURN、TCP hole punching),但是大量的信息并没有真正帮助我我的问题很简单:

我正在编写一个 P2P 应用程序,我希望我的应用程序在 NAT 后面的两个用户能够相互连接。连接必须可靠(与 TCP 的可靠性相当),所以我不能只切换到 UDP。该解决方案无需重新配置即可在当今的通用系统上运行。如果有帮助,该解决方案可能涉及可连接的第 3 方,只要它不必代理整个数据(例如,获取对等方的外部 (WAN) IP 地址)。

据我所知,我唯一的选择是使用“可靠的 UDP”库 + UDP hole punching。是否有(C/C++)库为此?我在related question 中找到了enet,但它只负责解决方案的前半部分。

还有什么?我看过的东西:

    Teredo tunnelling - 需要操作系统和/或用户配置的支持 UPnP 端口转发 - UPnP 并不存在/无处不在 TCP hole punching 似乎是实验性的,仅在某些情况下有效 SCTP 的支持程度甚至低于 IPv6。 UDP 上的 SCTP 只是花哨的可靠 UDP(见上文) RUDP - 几乎没有主流支持 根据我对 STUN、STUNT、TURN 和 ICE 的理解,它们在这方面对我没有帮助。

【问题讨论】:

您发现的简单问题一点也不简单。 NAT 穿越是hard。是什么让 ICE 不适合?它使用SDP?还有什么? 也许我无法从大量晦涩的术语中理解任何内容,但 ICE 将如何帮助我呢?据我了解,简单来说,ICE 只是确定它是否可以直接连接,如果不能,它使用中间服务器来传输数据。 另外,我有点不相信还没有人解决这个问题。我的意思是,它必须非常普遍!主要在电子游戏中(有些可以处理不可靠的连接,但不是全部)。每个人都只是编写自己的“可靠 UDP”协议吗? 【参考方案1】:

ICE 收集要连接的候选 IP/端口目标列表。每个对等点收集这些信息,然后每个对等点按顺序对每个候选者运行连接检查,直到检查通过或检查失败。

当 Alice 尝试连接到 Bob 时,她以某种方式获得了可能的方式列表 - 由 Bob 确定 - 她可以连接到 Bob。 ICE 称这些候选人。 Bob 可能会说,例如:“我的本地套接字的 192.168.1.1:1024/udp,我的外部 NAT 绑定(通过 STUN 找到)是 196.25.1.1:4454/udp,您可以在 1.2 调用媒体中继(中间盒) .3.4:6675/udp”。 Bob 将其放入一个 SDP 数据包(对这些不同候选者的描述),并以某种方式将其发送给 Alice。 (在 SIP 中,ICE 的原始用例中,SDP 承载在 SIP INVITE/200/ACK 交换中,建立 SIP 会话。)

ICE 是可插拔的,您可以配置候选人的精确性质/数量。您可以尝试直接链接,然后向STUN 服务器请求绑定(这会在您的 NAT 上打一个洞,并告诉您该洞的外部 IP/端口,您将其放入会话描述中),然后下降重新请求TURN 服务器中继您的数据。

ICE 的一个缺点是您的同行会交换 SDP 描述,您可能喜欢也可能不喜欢。另一个是 TCP 支持仍在draft form 中,这对您来说可能是也可能不是问题。 [更新:ICE 现在正式名称为RFC 6544。]

游戏经常使用 UDP,因为旧数据没用。 (这就是 RTP 通常在 UDP 上运行的原因。)一些 P2P 应用程序经常使用中间盒或中间盒网络。

IRC 使用中间盒网络:IRC 服务器形成网络,客户端连接到附近的服务器。从一个客户端到另一个客户端的消息可能会通过服务器网络传输。

如果不这样做,您可以看看 BitTorrent 的架构,看看他们如何处理 NAT 问题。正如 CodeShadow 在下面的 cmets 中指出的那样,BitTorrent 依赖于网络中可访问的对等点:在某种意义上,一些对等点形成了中间盒网络。如果这些中间盒可以充当中继器,那么您将拥有类似 IRC 的架构,但它是动态设置的。

【讨论】:

Argh... 对不起,但正如我所提到的,我并没有真正与这个术语相提并论,而且我所理解的任何东西都没有帮助。什么是“会话描述”,谁是候选人,为什么我需要多个 IP/端口目标,如果我的问题是在两方之间建立连接,为什么我们还要谈论多个对等点? STUN 不是依赖于 NAT-ed 网络上的 STUN 服务器吗? SDP 与在两台计算机之间建立单一可靠连接有什么关系?感谢您的深入回答,但我希望您能理解我的沮丧:( 此外,BitTorrent 仅使用 TCP,并且至少依赖于某些人是可连接的。 NAT 后面的对等点将无法相互连接,但仅此而已。我认为其他主要 P2P 网络(eMule 等)也是如此。这仍然允许 P2P 网络继续工作,但对于我的情况则不能这样说,因为连接是设计的必要部分。 别在意我上面所说的关于 STUN 的内容,我做了更多阅读,发现它只是一个完善的 UDP 打孔程序(加上收集有关网络的额外信息)。跨度> 感谢您清理术语,不幸的是,我离解决我的问题还差得远(因为我已经在问题中建议了 UDP 打孔,并提到中继数据不是一种选择)。我会接受您的回答,以确认“不,没有比问题中列举的解决方案更好的解决方案”。谢谢。【参考方案2】:

我推荐libjingle,因为它被一些严重依赖P2P网络通信的主要视频游戏公司使用。 (您听说过 Steam 吗?Vavle 也使用 libjingle,请参阅页面中的“点对点网络”会话:https://partner.steamgames.com/documentation/api)

但是,始终可用的解决方案是使用中继服务器。由于没有通过 NAT 的“标准”方式,因此如果必须始终在任何对等方之间建立连接,则应该将此中继服务器选项作为备用策略。

【讨论】:

以上是关于实用的 NAT 穿越,以实现可靠的网络连接的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何浏览器实现了 NAT 穿越?

centos部署ipsec *** nat穿越

centos部署ipsec *** nat穿越

TR-069_Amendment-4:附录G.穿越NAT网关的连接请求方式

SIP穿越NAT SIP穿越防火墙-SBC

同一个物理网络上的 webRTC 点对点