海外地区开启IPV6无法访问服务器问题

前言

最近有海外地区的用户反馈无法访问公司的网络,无法下载应用和系统进行升级。了解到浏览器可以正常访问公司域名,谷歌,油管等都能正常使用。日志分析GET请求服务器数据时没有得到应答,最终查询网络相关修改确认与网络IPV6有关。
先来看下全球主流网站IPv6的支持情况:
请添加图片描述

具体可查看这篇文章:https://zhuanlan.zhihu.com/p/605189137?utm_id=0
可以看到全球主流大公司很多未支持IPv6网络,国内阿里、腾讯也是部分支持并未全部支持,而360、百度、淘宝、CSDN等网站都不支持IPv6。
不止要考虑网站的IPv6的支持,还要考虑电信业务商是否支持IPv6。像台湾有些电信业务商,支持IPv6网络,例如台湾之星、中华电信,且在4G和5G的支持情况也不一致。

IPv6的可达性测试

在测试IPv6的可达性网址https://en.internet.nl/ 测试 www.czvv.com 网址结果如下,提示IPv6不可达。请添加图片描述

同样测试国内百度www.baidu.com 和 www.tecent.com 也是IPv6不可达。
请添加图片描述

测试支付宝www.alipay.com 谷歌www.google.com 或者 www.youtube.com 等都是IPv6可达的。请添加图片描述

总的来说国内IPv6的普及率不高,很多网址都是IPv6不可达。

问题分析

湾湾和阿三等地区用户都反馈了无法进行在线检查升级,一直在等待服务器应当。湾湾用户反馈使用台湾之星的手机卡不能检测升级,而换另一张非台湾之星的手机卡可以检测升级,之前系统未升级时可以正常访问网络的。通过查证得知系统添加修改了DNS对IPv6的支持,因此可知系统支持IPv6后无法正常从公司服务器获取数据。系统支持IPv6后会优先使用IPv6的地址进行访问。
为了进一步去除IPv6的影响,让湾湾用户在手机上关闭了IPv6的支持,只使用IPv4。结果关掉IPv6后即可以正常检测升级了。
从抓取的日志看到开启IPv6的情况下,请求www.czvv.com 获取信息时一直未收到服务器应答,显示www.czvv.com 使用IPv6的地址不可达。

解决方案

由于IPv6地址不可达,因此需要对DNS进行过滤,滤除IPv6地址。
OkHttpClient支持设置自定义DNS,于是在网络框架初始化时配置OkHttpClient,并添加自定义的DNS过滤器。
DnsFilter代码如下:

import androidx.annotation.NonNull;

import com.czvv.base.utils.ALog;
import com.czvv.mycar.util.ShareDb;

import okhttp3.Dns;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class DnsFilter implements Dns {
    
    

    public DnsFilter() {
    
    
    }

    @NonNull
    @Override
    public List<InetAddress> lookup(@NonNull String hostname){
    
    
        List<InetAddress> addresses = new ArrayList<>();
        try {
    
    

            List<InetAddress> list = Dns.SYSTEM.lookup(hostname);
            if (ShareDb.getDnsFilter()) {
    
    
                for (InetAddress inetAddress : list) {
    
    
                    ALog.print("inetAddress:" + inetAddress.toString() + "  " + (inetAddress instanceof Inet6Address));
                    if (inetAddress instanceof Inet4Address) {
    
    
                        addresses.add(inetAddress);
                    }
                }
            } else {
    
    
                return list;
            }
        } catch (UnknownHostException e) {
    
    
            e.printStackTrace();
        }

        return addresses;
    }
}

通过遍历系统的DNS地址列表,把IPv6的地址滤去。这样去请求网络的时候就不会使用IPv6地址去访问了。
通过增加DNS过滤开关进行过滤IPV6地址,应对不同地区的网络环境导致的网络问题。

猜你喜欢

转载自blog.csdn.net/CJohn1994/article/details/134891728