fakedns解决的是部分域名无法获取到正确结果的问题,但不管是我之前的方案,还是surge的方案,都比较依赖配规则,而且ss-android有个很局限的地方,是看不到日志,所以也没办法知道某个网站打不开是因为这个问题导致的,也就没办法加规则,还是比较被动。

刚好前两天看到少举的这条推里面提到的判断污染的方法,感觉比较考虑,于是问题就变成了找什么样的DNS来做测试,先试了下自己的VPS不开放53端口的方案,发现即使是reject规则也依然要等超时,这就太影响体验了,于是换个思路,DNS服务器分为递归和权威,那就试一下权威服务器查询不是它管辖范围的域名的行为,发现会报错REFUSED,非常好,于是找了www.hkdnr.hk的两个NS记录,基本都是30ms就能返回。

于是把DNS部分的代码全部重写了一遍,查询域名时同时向114和hk发起查询,如果hk这边返回NOERROR,那就走fakedns,否则就用114的结果,再做一下缓存,基本效果就出来了。

跑了一会,发现Google一个坑爹的地方,ampproject.org下的域名从114里查出来的IP,无法正确响应请求,难道又要回到配规则的老路上,刚好又想到一个问题,如果一个网站在全球都有部署,那114返回的是离国内最近的IP,但却不一定是离代理最近的,反而会比较慢。于是觉得可以做下IP判断,如果114返回的IP都不在国内,那也可以做fakedns来加速。刚好ss-android会把自己的中国区IP保存在bypass-lan-china.acl文件里,读取出来就好了。

完整代码见这里,因为感觉会比较耗电,而且两次DNS查询也会费流量,就暂时不放apk了。

update 2017-10-09:修改了一下,启动时查询hk.域的NS记录,然后同时查询所有NS记录对应的服务器然后选最快的那台作为探测NS,每小时重新查一次,结果记录到文件作为容灾缓存。

update 2017-10-20:用的某SS商家在中转线路上屏蔽了国内IP,导致国内网页都打不开,才发现,ss-android里如果设的是绕过中国及局域网地址,则并不会用路由表的方式,而是自行在ss-libev里用acl参数来控制,但这里修改的却没有理解这个意思,导致中国IP的流量还是被转到远端代理层了,在代理层也做了一层类似的分流逻辑,用传进来的--acl参数就好了。