STUN 服务器真的有必要吗?

Are STUN servers really necessary?

在 WebRTC 信令过程中,我必须通过向 STUN 服务器发出请求来使用我的端口找到我自己的 public IP 地址。但真的需要这么复杂吗?

我不能只向我子网的路由器发送请求并获取它的 IP 地址和它为我打开的端口吗?或者更好的是,我直接将我的 public 地址存储在我的计算机中,路由器会在它发生变化时通知我。浏览器会给出一个 API 来直接获取这个 public 地址。无需使用 STUN 服务器。为什么我们不这样做呢?

感谢您的帮助。

这些都是很好的问题。

Couldn't I just send a request to the router of my subnet and get its IP address and the port it opened for me?

有一个名为 uPnP 的旧协议,它会为您动态打开端口映射 - 前提是路由器支持它。许多路由器过去都支持它。不知道现在标准如何。

即使路由器是智能的并且有标准的信号机制,对于以下场景仍然需要 STUN(或与 STUN 等效的东西)。

Carrier NAT 是指您的 ISP 与多个路由器共享一个 public IP 地址。也就是说,ISP 在启动时配置的路由器 public IP 地址实际上只是另一个私有 IP 地址。在上游,有一个 "bigger router" 与多个其他客户共享 public IPv4 地址。也就是说,您的 PC 可能认为它的 IP 地址是 192.16.1.2,而您的路由器报告它自己的 IP 地址是 10.0.0.2。实际 public IP 地址 1.2.3.4 与其他客户共享。 STUN 解决了​​这个问题,因为到 public STUN 服务器的出站数据包将通过两个 NAT——沿途创建端口映射。

Or even better, I store directly my public address in my computer and the router notifies me whenever it changes

因为建立有效的 P2P/WebRTC 连接不仅仅是了解您的 public IP 地址。它还涉及知道要使用什么 "port" 。虽然大多数路由器会尝试保留客户端 PC 在映射中使用的套接字的本地端口(例如 10.0.0.2:9876 映射到 1.2.3.4:9876)。情况并非总是如此 - 另一个节点可能正在使用您网络上的端口 9876 and/or 许多 NAT 只是选择一个随机可用的端口进行映射。在一天结束时,您必须向 P2P/WebRTC 连接的另一端发出信号 "which IP" 和 "which port" 才能使用。

The browser would give an API to get this public address directly.

有很多网站(例如 whatismyipaddress.com)会告诉您您的 IP 地址。但如果涉及 HTTP 代理服务器(在 PC 上显式配置或静默部署在网络上),Web 服务将只能看到代理 IP 地址。此外,HTTP(S) 是基于 TCP 的协议。 STUN 和 WebRTC 基于 UDP。