什么是DNS

当我们发起一个网络请求,首先要经过DNS服务,将域名转化为IP地址,然后通过IP地址建立连接。DNS的工作流程如下图所示。

Local DNS有什么缺陷

那么,传统的Local DNS有什么缺陷呢。就目前端上而言,主要有几个问题:

•Local DNS劫持

DNS劫持示例图如下:

DNS劫持会导致端上网络连接失败或者DNS解析失败,严重影响用户使用,在之前,端上采用备用域名的机制去解决这个问题,但是效果并不是很好。

•DNS解析过慢

DNS解析分为递归查询和迭代查询两种。

由于递归模式会导致DNS服务器流量很大,所以现在大多数采用迭代模式。

由于端上网络环境的复杂性已经DNS解析的流程也较为复杂,有些场景下DNS解析时间高达几百毫秒,对于一次网络请求来说,是相当缓慢的。

什么是HttpDns

目前来说,腾讯和阿里都有自己的HTTPDNS解决方案。HTTPDNS有以下特性:

1.安全,由于httpdns使用http或者https协议通过ip直连的方式进行解析,绕过了运营商的Local DNS,避免了域名劫持

2.快速,通过预解析机制,将热点域名提前解析,网络连接时直接缓存获取

Android端HttpDns接入指南

在阿里云HTTPDNS文档中,有所谓的“最佳方案”,包含SNI场景、OkHttp场景等等,但是,这对于我们来说,接入量还是偏大,且覆盖的场景依然有限。如果我们想很简单的接入,且覆盖全量JAVA场景,如何做呢。首先,我们看一下Android侧DNS解析的调用流程,以API 28为例。

InetAddress#getAllByName() ->Inet6AddressImpl#lookupHostByName() ->Libcore.os.android_getaddrinfo()

而Libcore代码如下Libcore源码[1]:

public final class Libcore { private Libcore() { } /** * Direct access to syscalls. Code should strongly prefer using {@link #os} * unless it has a strong reason to bypass the helpful checks/guards that it * provides. */ public static Os rawOs = new linux(); /** * Access to syscalls with helpful checks/guards. */ public static Os os = new BlockGuardOs(rawOs);}

通过简单的代码跟踪可以发现,他们实现Os这个接口[2],接口?对哦,动态代理。是的,我们可以通过动态代理的方式,去hook掉Java层发起的DNS解析请求。


上面的代码,已经开源在KIDDNS-Android[3]

下期预告

Android P hide API的问题相信困扰了不少同学,那么下期,咱们一起了解下如何在Android P上使用hide API!

References

[1] Libcore源码:https://android.googlesource.com/platform/libcore/+/refs/tags/android-9.0.0_r35/luni/src/main/java/libcore/io/Libcore.java

[2] Os这个接口:https://android.googlesource.com/platform/libcore/+/refs/tags/android-9.0.0_r35/luni/src/main/java/libcore/io/Os.java

[3] KIDDNS-Android:https://github.com/VIPKID-OpenSource/KIDDNS-Android

1.《dns优化 Android网络优化篇-从DNS开始》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《dns优化 Android网络优化篇-从DNS开始》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/347086.html