DNS 解析器模块为用户提供 DNS 拦截和配置更新攻击保护,并提高 DNS 解析的网络性能。该模块包含实现 DNS 桩解析器的代码,该解析器将 www.google.com 等名称转换为 2001:db8::1 等 IP 地址。DNS 桩解析器支持 Java API 元素,例如 InetAddress#getAllByName 和 Network#getAllByName,以及 原生网络函数,并实现发送和接收 DNS 查询以及缓存结果。
Android 10 中的变更
在运行 Android 9 及更低版本的设备上,DNS 解析器代码分布在 Bionic 和 netd
中。DNS 查找集中在 netd
守护程序中,以允许进行系统范围的缓存,而应用调用 Bionic 中的函数(例如 getaddrinfo
)。查询通过 UNIX 套接字发送到 /dev/socket/dnsproxyd
以发送到 netd
守护程序,该守护程序解析请求并再次调用 getaddrinfo
以发出 DNS 查找,然后缓存结果,以便其他应用可以使用它们。DNS 解析器实现主要包含在 bionic/libc/dns/
中,部分包含在 system/netd/server/dns
中。
Android 10 将 DNS 解析器代码移至 system/netd/resolv,
,将其转换为 C++,然后对代码进行现代化改造和重构。Bionic 中的代码继续存在是为了实现应用兼容性,但系统不再调用它。这些源路径受到重构的影响
bionic/libc/dns
system/netd/client
system/netd/server/dns
system/netd/server/DnsProxyListener
system/netd/server/ResolverController
system/netd/resolv
格式和依赖项
DNS 解析器模块 (`com.android.resolv`) 作为 APEX 文件交付,并由 netd
动态链接;但是,netd
不是依赖项,因为该模块直接为本地套接字 /dev/socket/dnsproxyd
提供服务。解析器配置的 Binder 端点已从 netd
移至解析器,这意味着系统服务可以直接调用解析器模块,而无需通过 netd
。
DNS 解析器模块依赖于 libc
(Bionic) 并静态链接其依赖项;不需要其他库。
mDNS .local 解析
从 2021 年 11 月开始,Android 解析器支持 mDNS .local 解析,它在 RFC 6762 中实现“5.1 单次多播 DNS 查询”,以盲目地将标准 DNS 查询发送到 224.0.0.251:5353 或 [FF02::FB]:5353。通过使用以 *.local
结尾的主机名调用 getaddrinfo()
,可以透明地支持 mDNS 解析。
mDNS .local 解析增强了 getaddrinfo()
的现有功能以获取地址。如果设备支持 mDNS .local 解析,则 getaddrinfo()
API 会将 mDNS 查询发送到 224.0.0.251:5353 或 [FF02::FB]:5353 并返回本地地址。如果设备不支持 mDNS .local 解析,则 getaddrinfo()
API 方法会将 DNS 查询发送到 DNS 服务器。
代码位于 AOSP 中,位于 packages/modules/DnsResolver
中。用户可以保留其当前的 mDNS 设计以获取地址,也可以改用 getaddrinfo()
。此功能的行为类似于发送到 mDNS 多播地址的常规 DNS 查询。此功能对系统运行状况没有影响。
用户可以使用命令 adb shell ping6 HOSTNAME.local
,其中 HOSTNAME 是 LAN 上目标设备的主机名,例如 adb shell ping6 ipad.local
。
VPN 和移动数据连接不包括在 .local 解析中。