穿越NAT的实现 - daniel-qa/Network GitHub Wiki

穿越NAT的实现

A1在客户机时 192.168.0.8:4000——6.7.8.9:8000

X1在网关时 1.2.3.4:62000——6.7.8.9:8000

服务器C 6.7.8.9:8000

B1在客户机时 192.168.1.8:4000——6.7.8.9:8000

Y1在网关时 1.2.3.5:31000——6.7.8.9:8000

两内网用户要实现通过各自网关的直接呼叫,需要以下过程:

1、 客户机A1、B1顺利通过格子网关访问服务器C ,均没有问题(类似于登录)

2、 服务器C 保存了 A1、B1各自在其网关的信息(1.2.3.4:62000、1.2.3.5:31000)没有问题并可将该信息告知 A1、B2

3、 此时 A1发送给 B1网关的1.2.3.5:31000 是否会被B1收到?

答案是基本上不行(除非Y1设置为完全圆锥型,但这种设置非常少),

因为 Y1 上检测到其存活的会话中没有一个的目的IP或端口于 1.2.3.4:62000有关而将数据包全部丢弃

4、 此时要实现 A1、B1 通过 X1、Y1 来互访需要服务器 C告诉它们各自在自己的网关上建立“UDP隧道”即命令A1发送一个 192.168.0.8:4000——1.2.3.5:31000的数据报,B1 发送一个192.168.1.8:4000——1.2.3.4:62000的数据报UDP形式

这样X1、Y1上均存在了IP端口相同的两个不同会话(很显然,这要求网关为Cone NAT型,否则,对称型 Symmetric NAT设置网关将导致对不同会话开启了不同端口, 而该端口无法为服务器和对方所知,也就没有意义)。

5、 此时 A1发给 Y1,或者 B1发给 X1的数据报将不会被丢弃且正确的被对方收到.

综合 P2P 可实现的条件需要

1、 中间服务器保存信息、并能发出建立UDP隧道的命令

2、 网关均要求为 Cone NAT 类型。Symmetric NAT不适合

3、 完全圆锥型网关可以无需建立 udp隧道但这种情况非常少,要求双方均为这种类型网关的更少。

4、 假如 X1网关为Symmetric NATY1为 Address Restricted Cone NATFull Cone NAT型网关,

各自建立隧道后,A1 可通过 X1发送数据报给 Y1到 B1(因为Y1最多只进行IP级别的甄别),

B2发送给 X1的将会被丢弃因为发送来的数据报中端口与X1上存在会话的端口不一致,虽然IP地址一致),所以同样没有什么意义。

5、 假如双方均为 Symmetric NAT的情形,新开了端口对方可以在不知道的情况下尝试猜解,也可以达到目的,但这种情形成功率很低,且带来额外的系统开支,不是个好的解决办法。

6、 不同网关型设置的差异在于,对内会采用替换IP的方式使用不同端口不同会话的方式使用相同端口不同会话的方式对外会采用什么都不限制、限制IP地址、限制IP地址及端口

7、 这里还没有考虑同一内网不同用户同时访问同一服务器的情形,如果此时网关采用 Address Restricted Cone NATFull Cone NAT型,有可能导致不同用户客户端可收到别人的数据包,这显然是不合适的。