前言
最近有海外地區的用戶反饋無法訪問公司的網絡,無法下載應用和系統進行升級。了解到瀏覽器可以正常訪問公司域名,谷歌,油管等都能正常使用。日志分析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@Overridepublic 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地址,應對不同地區的網絡環境導致的網絡問題。