局域网连接判断
一、局域网类型
1. 通过局域网 IP 直连
场景:客户端 A 与客户端 B 处于同一个路由器下。
2. 通过公网 IPv6 直连
场景:客户端 A 与 客户端 B 处于同一个路由器下,路由器为客户端 A 与客户端 B 皆分配了公网 IP 地址。
3. 单边位于 NAT 下
场景:客户端 A 位于路由器的局域网中,路由器与客户端 B 都位于光猫下。
4. 双边位于 NAT 下
场景:光猫下有多个路由器,未做 mesh。客户端 A 与客户端 B 分别位于一个路由器下。
5. 通过 ISP NAT 建立连接
场景:光猫 A 和光猫 B 都是同一个 ISP 运营商的设备。两个光猫无公网地址,只有 ISP 运营商分配到的 100.64.0.0 - 100.127.255.255 地址。
6. 通过 VPN 网关建立连接
场景:双端通过 VPN 网关(例如 WireGuard、ZeroTire)构建了局域网。
7. 通过 NAT 回环建立连接
场景:客户端 A 通过端口映射协议(例如UPnP)在路由器上增加 NAT 规则,并获取路由器 WAN 地址作为自身地址。客户端 B 通过路由器 WAN 地址与客户端 A 建立连接。
二、判断方式
1. 通过 RFC 定义
当对端地址为以下类型时,可以直接判断为局域网:
- 根据 RFC 1918 和 RFC 4193,
10.0.0.0/8
,172.16.0.0/12
,192.168.0.0/16
,fc00::/7
地址为私网地址; - 根据 RFC 3927 和 RFC 4291,
169.254.0.0/16
,fe80::/10
地址为 Link-Local 地址;
通过 RFC 定义,可以将 通过局域网 IP 直连 、单边位于 NAT 下、双边位于 NAT 正确识别为局域网连接。
2. 计算子网
当在局域网通过其他类型地址建立连接时(如:Global Unicast IPv6 地址),通过获取本地网卡地址列表和对应子网掩码。
通过计算子网判断对端地址是否和本地地址位于同一局域网。
通过计算子网的方式,可以将 通过局域网 IP 直连 、单边位于 NAT 下、双边位于 NAT、通过公网 IPv6 直连 正确识别为局域网连接。
3. 特殊场景
ISP 地址
当双端通过 ISP 地址建立局域网连接时,
如果通过 ISP 地址建立的连接速率不受双端购买的套餐限制,则可以认为是局域网连接;
如果建立的连接速率受双端购买的套餐限制,则不应认为是局域网连接。
VPN 地址
在 Linux 端可以根据路由表来判断对端地址对应路由是否属于 VPN 网卡;
但是在移动端无法直接拿到路由表,因此无法判断对端地址会不会经过 VPN 网卡。
NAT 回环地址
当通过 NAT 回环地址建立连接后,双端看到的对端地址皆为 NAT WAN 口地址。
此时有几种方式判断是否是位于同一局域网:
- 双端交换自身看到的对端地址信息。如果一致则可以判断当前连接为通过 NAT 回环地址建立;
- 双端通过端口映射协议获取 NAT 网关的 External 地址。如果 NAT 网关地址与对端地址相同则可以判断当前连接为通过 NAT 回环地址建立;