我们通过NetworkExtension框架实现了一个VPN应用,会新建一个tun口(比如tun1),并在此tun口上设置DNS(例如:我们会在tun1口设置DNS为 8.8.8.8)
另外因为NetworkExtension框架中,DNS解析流量由于API没法设置排除列表,因此设置为全部DNS解析流量全部到tun解析
同时为了达到部分DNS解析流量不到tun口解析,而是正常走en0口解析的目的,我们实现了一个relay机制,当遇到匹配的解析流量后,我们会通过将en0口ip作为目的ip,使用socket发送到en0口
客户有一个使用场景为,在连接我们VPN应用后,又连接另一个OpenVPN(类似于Tunnelblick、ToDesk)
此OpenVPN在连接后,也会新建一个tun口(比如tun2),服务器下发的DNS会自动修改到en0口上,推测此行为的目的是以此来达到解析所有域名的效果(例如:如果用户下发DNS 223.5.5.5,会将en0口的DNS修改为223.5.5.5,同时添加一条路由,223.5.5.5/32指向tun2)
用户的OpenVPN配置中,包含了一些内网域名,需要在OpenVPN服务器下发的DNS进行解析
我们的预期情况为,我们的VPN应用先获取到DNS解析流量,然后通过relay机制,将用户内网的DNS解析流量relay到OpenVPN的DNS进行解析
实际的情况为,在用户同时连接后,我们的VPN应用先获取到DNS解析流量,然后通过relay机制,将用户内网的DNS解析流量通过socket发送时(此时的目的ip为OpenVPN服务器下发的DNS),socket报错 “Network is unreachable”,同时系统打印log “Not found valid entry”
在调试时,通过netstat -rn 命令查看系统路由表,发现有路由223.5.5.5/32 指向tun2口
有路由,但是socket发送报错“Network is unreachable” 这是不符合预期的