DNS Resolver 模块为 DNS 拦截和配置更新攻击提供用户保护,并提高了 DNS 解析的网络性能。该模块包含实现 DNS 存根解析器的代码,它将诸如www.google.com之类的名称转换为诸如2001:db8::1之类的 IP 地址。 DNS 存根解析器支持InetAddress#getAllByName和Network#getAllByName等 Java API 元素以及本机网络功能,并实现发送和接收 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/libc/dns
-
system/netd/client
-
system/netd/server/dns
-
system/netd/server/DnsProxyListener
-
system/netd/server/ResolverController
-
system/netd/resolv
格式和依赖
DNS Resolver 模块 (`com.android.resolv`) 作为APEX文件交付,并由netd
动态链接;但是, netd
不是依赖项,因为该模块直接为本地套接字/dev/socket/dnsproxyd
提供服务。解析器配置的 Binder 端点已从netd
移至解析器,这意味着系统服务可以直接调用解析器模块,而无需通过netd
。
DNS Resolver 模块依赖于libc
(Bionic) 并静态链接其依赖关系;不需要其他库。
mDNS .local 解析
从 2021 年 11 月开始,Android 解析器支持 mDNS .local 解析,实现 RFC 6762 中的“5.1 One-Shot multicast DNS Queries”,将标准 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是局域网中目标设备的主机名,例如adb shell ping6 ipad.local
。
VPN 和移动数据连接不包括在 .local 解析中。