ptg2008:
前置科普
nat 类型分类
- NAT1:Full Cone (全锥形 NAT )
- NAT2:Restricted Cone ( IP 受限锥形 NAT )
- NAT3:Port Restricted Cone (端口受限锥形 NAT )
- NAT4:Symmetric (对称型 NAT )
结论: 若 Full Cone = 1, Restricted Cone = 2, Port Restricted Cone = 3, Symmetric = 4, 假设 A 端的 nat 类型代表的数值为 k1 (1 <= k1 <= 4), B 端的 nat 类型代表的数值为 k2 (1 <= k2 <= 4), 根据我掌握的到的计算机网络知识, 只有当 k1 + k2 <= 6 时, A 和 B 才能成功建立 p2p 连接
发现问题
今天我试了用 easytier 组网, 具体来说, 就是我有台的 MacBook Pro, 一台 Windows, 还有一个阿里云小水管机器, 组网成功后, 我执行了命令查看组网情况, 如下图所示
没错, 符合我预期, MacBook Pro 是 Symmetric = 4, Windows 是 Port Restricted Cone = 3, 4 + 3 = 7 > 6, 只能走阿里云小水管中继
但是 5 分钟后我又执行了命令查看组网情况, 如下图所示
发现了 MacBook Pro 和 Windows 之间是 变成了 P2P 连接
分析一波
网络拓扑大概这样
MacBook (priv_ip1, priv_port1)
|
|
公网出口 1 (pub_ip1, pub_port1)
|
...(中间很多路由)
|
阿里云小水管 (aliyun_ip, aliyun_port)
|
...(中间很多路由)
|
公网出口 2 (pub_ip2, pub_port2)
|
|
Windows (priv_ip2, priv_port2)
分析如下
-
步骤 1:双方先向中继 S (代指阿里云小水管) “报备” 自己的临时端口
- Windows ( Port Restricted = 3 )向 S 发请求:分配到了一个出口路由器(pub_ip2)的临时端口 pub_port2 ,并记录 (priv_ip2, priv_port2) <-> (pub_ip2, pub_port2) 的映射; 同时,S 会知道 Windows 的 (pub_ip2, pub_port2) 。
- MacBook ( Symmetric = 4 )向 S 发请求: 分配到了一个出口路由器(pub_ip1)的临时端口 pub_port1 ,并记录 (priv_ip1, priv_port1) <-> (pub_ip1, pub_port1) 的映射; 同时,S 会知道 MacBook 的 (pub_ip1, pub_port1) 。
-
步骤 2:中继 S 向双方 “转发对方的端口信息”
- S 把 Windows 的 (pub_ip2, pub_port2) 告诉 MacBook ;
- S 把 MacBook 的 (pub_ip1, pub_port1) 告诉 Windows 。
* case1:
1. Windows 发起请求访问 MacBook 的(pub_ip1, pub_port1) , 但是被拒绝, 这个请求对于 nat4 而言是"陌生请求"(因为 Windows 和 MacBook 之前没有建立连接)
2. 但是这时候能从(pub_ip1, pub_port1)访问 Windows 了 (因为是 nat3, 端口和 IP 都受限, 只能从(pub_ip1, pub_port1)访问, 其它的网段访问 Windows 还是会被拒绝)
3. 这时候 MacBook 再次向(pub_ip2, pub_port2)发起请求, 但是因为 MacBook 是 nat4, 导致分配到的出口路由器的端口不再是 pub_port1, 而是 another_pub_port1 (假设出口路由器不变)
4. 这样访问 Windows 就会被拒绝, 因为对于 Windows 而言, 只允许从(pub_ip1, pub_port1)过来的请求访问, 而从(pub_ip1, another_pub_port1)过来的是没法访问的
* case2:
1. MacBook 发起请求访问 Windows 的(pub_ip2, pub_port2) , 但是被拒绝, 因为是 nat4, 导致分配到的出口路由器的端口不再是 pub_port1, 而是 another_pub_port1 (假设出口路由器不变)
所以这样就没法打洞成功
疑问
- 在上面案例中, Windows 和 MacBook 怎么建立 P2P 连接的
- MacBook 在和 S 建立连接断开后, 然后再和 Windows 建立连接时, 能复用出口端口 pub_port1 吗? 如果是这样, 应该就可以 P2P 成功, 实际上不同路由器的对于 nat 分配实现是怎么样的呢?
AI 怎么说
所有 AI 不能很清楚的回答我的问题, 在我的追问后这些 AI 就难以自圆其说