使用 STUN 打孔

Posted

技术标签:

【中文标题】使用 STUN 打孔【英文标题】:Hole punching using STUN 【发布时间】:2015-10-20 12:47:25 【问题描述】:

我目前正在尝试通过 Internet 发送 UDP 消息,并且必须为端点 A 和 B(都位于 NAT 后面)设置防火墙。为此,我想使用 STUN 服务器进行打孔。

当 A 创建对 STUN 服务器的请求时(例如,私有:85.1.1.12:6000 和公共:173.194.78.127:19302)我得到 85.1.1.12:6000 作为响应。如果我要从相同的源配置(用于 STUN 请求的相同源 ip 和端口)发送一个数据包到任何其他目标地址(目标端口保持不变),那么我的 NAT 将再次更改公共端口(从 6000 到其他任何东西)。我发现通过对两个不同的 STUN 服务器请求使用相同的地址端口配置(对两个请求使用端口 19302)。

像这样,我不可能知道我的 NAT 在向 B 发送数据包时会转换哪个端口(B 无法接收任何东西,因为它的防火墙没有设置)。

这是因为我的 NAT 类型与打孔不兼容还是我的概念有误?

谢谢!

【问题讨论】:

【参考方案1】:

85.1.1.12:6000 不是您的私有 IP 地址。它是您的 NAT 的公共/外部 IP:端口。私有 IP 是您的 PC/设备的接口地址。

根据您的情况,我猜您有一个对称 NAT。在对称 NAT 中,每次您将一些数据包发送到不同的目的地时,您的 NAT 的公共端口都会发生变化。如果您的目的地保持不变,那么 NAT 的公共 IP:端口也保持不变。

对于其他类型的 NAT,如果您的私有 IP 不变,那么无论您将数据包发送到何处,您的 NAT 公共 IP:端口(在您的情况下为 85.1.1.12:6000)都将保持不变。

如果一侧有 **Symmetric NAT 而另一侧有 Symmetric/PRC NAT,则不能打孔。

**我所说的对称 NAT 是指提供随机端口分配的对称 NAT。

【讨论】:

非常感谢,我想我现在明白了。我在不同的网络(显然没有对称 NAT)中尝试了它,它完美地工作并且表现如预期。谢谢! "如果一侧有 **Symmetric NAT 而另一侧有 Symmetric/PRC NAT,则不能打孔。"这在技术上是不正确的。请看我的回答。【参考方案2】:

如果双方都有对称的 NAT,打孔 在技术上并非不可能(尽管遍历过程可能太不可靠,不值得麻烦)。请阅读我的论文:

https://drive.google.com/file/d/0B1IimJ20gG0SY2NvaE4wRVVMbG8/view?usp=sharing

或者它引用的一篇论文:

    http://tools.ietf.org/id/draft-takeda-symmetric-nat-traversal-00.txt

    https://www.goto.info.waseda.ac.jp/~wei/file/wei-apan-v10.pdf

    http://journals.sfu.ca/apan/index.php/apan/article/view/75/pdf_31

【讨论】:

我已经实现了一个与你的非常相似的过程。但是当我说不可能时,我的意思是我们只能猜测端口并且无法保证拥有 P2P。成功率可能很大程度上取决于其他因素。但是对于其他的NAT组合,P2P是可以保证的。 您的手术成功率是多少?你在 2/3/4G 网络上测试过吗?

以上是关于使用 STUN 打孔的主要内容,如果未能解决你的问题,请参考以下文章

Java UDP STUN 打孔与 DatagramSocket

需要帮助设置用于 p2p 数据传输的 udp 打孔。无法让 STUN 工作

所有 NAT 类型的 P2P 连接

NAT Traversal - 使用 STUN 的成功概率

Java 和我应该使用哪些 Stun 库?

如何使用 java 创建我自己的 STUN 或 TURN 服务器