我正在开发一个 p2p 聊天应用程序,它可以在 DSL 两个不同的 NAT 上正常工作,但是当涉及到 3G USB 互联网连接时,它会失败。
我发现 3g 网络无法绕过 NAT,并且已知的 p2p 应用程序(如 Skype 和 torrent)也无法绕过 3g 网络,每当遇到这些问题时,它们都会通过中央服务器发送数据。
我想知道3g网络的架构是什么。我听说他们没有私有IP,端口对只有公共IP,端口可用,一个公共端口可以分配给许多设备,对吗?如果是这样,服务器如何将数据发送到 3g 网络?
我正在开发一个 p2p 聊天应用程序,它可以在 DSL 两个不同的 NAT 上正常工作,但是当涉及到 3G USB 互联网连接时,它会失败。
我发现 3g 网络无法绕过 NAT,并且已知的 p2p 应用程序(如 Skype 和 torrent)也无法绕过 3g 网络,每当遇到这些问题时,它们都会通过中央服务器发送数据。
我想知道3g网络的架构是什么。我听说他们没有私有IP,端口对只有公共IP,端口可用,一个公共端口可以分配给许多设备,对吗?如果是这样,服务器如何将数据发送到 3g 网络?
我为多代理系统开发开源中间件,最近我们不得不为 4G/3G 网络上的 p2p 使用创建一个基于 UDP 的传输选项。我们已经在 T Mobile 的数据计划以及 NAT 背后的各种学术网络上对此进行了测试,我对目前的实施充满信心。由于这里似乎没有任何可靠的解决方案来解决这个问题,我想我会通过 REGISTRY_CLIENT 传输选项分享我们目前在 MADARA 中间件 ( http://madara.sourceforge.net/ ) 中实施的解决方案类型。
对于我们来说,我们为 P2P 端点选择了您可能称之为注册服务器或名称服务(如果您熟悉 CORBA)的东西。注册服务器需要在 UDP 可以通过单向消息到达的某个公共 ip:port 上运行。对于我们的测试,我们租用了一个 Amazon EC2 节点,并确保防火墙设置允许 UDP 流量通过我们要绑定的 UDP 端口。在服务器端(注册服务器的公共 ip:port 配对),我们绑定到端口并等待客户端注册。任何想要与他人交谈的 P2P 客户端都会向 Registry Server 发送注册消息
P2P client ----> [register message] ---> Registry Server
注册消息可以具有任意内容。我们的实际上除了来自我们正常数据协议的消息头之外没有其他内容。在服务器端,我们通过普通的套接字 recv 调用检查注册消息发送方(左上角的 P2P 客户端)的远程主机。这个远程主机应该是通过防火墙保护 P2P 客户端的端点信息。
要了解这里发生了什么,我们必须查看消息是如何为 P2P 客户端路由到我们的公共注册服务器的。下面的 ASCII 图表显示了一个套接字在从 P2P 客户端到我们的 EC2 服务器的路径上可能看到的远程信息(即示例防火墙映射)。这仅显示了一个防火墙,但它应该与 P2P 客户端和 Registry Server 之间的多个 NAT 一起使用,只要 NAT 在流量通过该特定 NAT 分配的 ip:port 时保持公共 ip:ports 开放。
P2P client ----> [message from 192.168.1.10:35000] ---> Firewall ---> [message from 111.111.50.34:5627] --> Registry Server
现在,如果我们尝试从注册服务器向 192.168.1.10:35000 发送消息,它会失败(或者至少,它几乎肯定会发错地方)。同样,您可以看到 4G 防火墙也将端口从 35000 更改为 5627。要将消息发送回 P2P 客户端,您需要做两件事:1)通过 111.111.50.34:5627 而不是发送返回消息比我们最初在 P2P 客户端绑定的任何 ip:port 信息,以及 2) 确保 P2P 客户端或注册服务器频繁地相互重新发送数据——对于我们永久绑定的目的来说,每秒一次似乎很好在我们的示例中,公共 ip:port 为 111.111.50.34:5627。
作为我们协议的一部分,我们不只是将无用的数据包发送回注册的 P2P 客户端。我们发送 P2P 客户端的所有相关公共 ip:port 配对,这些客户端位于该客户端的组/集团/域/任何内容中。基本上,我们为注册服务器所知道的似乎与 P2P 客户端相关的所有内容发送 P2P 客户端发现信息。
例如,假设两个 P2P 客户端通过 111.111.50.34:5627 和 111.111.37.24:15234 ip:port 绑定通过 4G 提供商的防火墙向注册表服务器发送消息。一个新的 P2P 客户端从 111.111.70.105:7000 连接,我们在一个简单的列表中回复其他两个端点:
[Registry Response for P2P Client #3]
111.111.50.34:5627
111.111.37.24:15234
现在,在 P2P 客户端 #3 端,您获取此列表并将其用作您的 P2P 应用程序的潜在端点。这些是您的 P2P 同行。您可以通过您注册的同一个套接字向它们创建 UDP 数据包,只要它们不在保守的防火墙后面(例如手机上的移动连接热点,根据我的经验,传统上旨在阻止临时端口上的所有入站 UDP 流量没有可用于启用端口转发的配置设置的绑定)和流量应该能够双向流动。
如前所述,为了保持 P2P UDP 连接有效,您基本上只需要定期向/从该端点重新发送数据,以保持公共 ip:port 绑定在保护 P2P 客户端的每个防火墙上处于活动状态。这可以通过定期向公共注册服务器重新发送注册信息和/或从其他 P2P 客户端接收 UDP 数据包到 4G 防火墙已分配给您的 P2P 客户端的公共 ip:port 来完成。
维基百科声称运营商级 NAT可以被 P2P 应用程序遍历,即使存在端口共享:
上述技术在 CGN 中运行良好。CGN 还可以利用端口重载行为,这意味着具有相同端口值的不同内部端点可以映射到同一个公共端点。这不会破坏 5-uple {Protocol, public address, public port, remote address, remote port} 的唯一性,因此是可以接受的。TCP 端口保留也可能导致 CGN 端口过载并且不是协议健全性问题的情况。TCP 的端口过载允许 CGN 在内部容纳更多主机,同时保留 TCP 端到端通信保证。
但是,该段落没有引用任何参考资料。
为什么不能绕过3G网络NAT?
它归结为统计数据。为了建立连接,您必须将数据包发送到他们所在的端口,并且他们必须将数据包发送到您所在的端口。如果您发送到错误的端口号或他们发送到错误的端口号,您会错过并且没有建立连接。如果你们俩同时绑定到一个端口并发送一个指向对方 IP 地址的数据包,那么您有 65535 分之一(65535 是 IP 地址上的端口数)向他们的端口发送数据包的机会,并且他们有大约 65535 分之一的机会将数据包发送到您的端口。所以你建立连接的机会是 (1/65535) * (1/65535) 或 (1 / 65535^2)。
您无法知道任何后续连接的端口号,因为对于每个新的出站连接,路由器会在 1024 和 65535 之间的时间间隔内随机为您提供一个新端口号。因此,如果您询问服务器您的 ip 和端口号是什么,它可能会告诉您正确的 IP(除非您关闭手机或类似的东西,否则您的 IP 地址不会经常更改),但端口号会更改。如果您尝试猜测端口号,则存在 ( (65535-1024-1) / (65535-1024) ),或者您猜测错误的 99.998% 变化,假设可供选择的可能端口号数量为 ( 65535-1024)。
因此,除非端口号是可预测的(在许多 4G 网络中不可预测),否则您将被淹没 - 没有机会。
这可能是可能的,您只是无法准确猜测端口号。您可能会离开一点点并且无法建立连接。对于可以在对称和大规模 NAT 上工作的更强大的打孔方法,请尝试以下方法之一:
对于运营商,他们可能不会选择与您的内部客户端相同的外部端口。这打破了 TCP 和 UDP 打孔。看这里: