穿越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 NAT, Y1为 Address Restricted Cone NAT 或 Full Cone NAT型网关,
各自建立隧道后,A1 可通过 X1发送数据报给 Y1到 B1(因为Y1最多只进行IP级别的甄别),
但 B2发送给 X1的将会被丢弃(因为发送来的数据报中端口与X1上存在会话的端口不一致,虽然IP地址一致),所以同样没有什么意义。
5、 假如双方均为 Symmetric NAT的情形,新开了端口,对方可以在不知道的情况下尝试猜解,也可以达到目的,但这种情形成功率很低,且带来额外的系统开支,不是个好的解决办法。
6、 不同网关型设置的差异在于,对内会采用替换IP的方式、使用不同端口不同会话的方式,使用相同端口不同会话的方式; 对外会采用什么都不限制、限制IP地址、限制IP地址及端口。
7、 这里还没有考虑同一内网不同用户同时访问同一服务器的情形,如果此时网关采用 Address Restricted Cone NAT 或 Full Cone NAT型,有可能导致不同用户客户端可收到别人的数据包,这显然是不合适的。