The DNS Resolver module provides user protection for DNS interception and configuration update attacks and improved network performance for DNS resolutions. The module contains the code that implements the DNS stub resolver, which translates names such as www.google.com to IP addresses such as 2001:db8::1. The DNS stub resolver backs Java API elements such as InetAddress#getAllByName and Network#getAllByName, as well as native networking functions, and implements sending and receiving DNS queries and caching the results.
Changes in Android 10
On devices running Android 9 and lower, the DNS resolver code is spread across
Bionic and netd
. DNS lookups are centralized in the
netd
daemon to allow for system-wide caching, while apps
call functions (such as getaddrinfo
) in Bionic. The query is sent
over a UNIX socket to /dev/socket/dnsproxyd
to the
netd
daemon, which parses the request and calls
getaddrinfo
again to issue DNS lookups, then caches the results
so that other apps can use them. The DNS resolver implementation was mostly
contained in bionic/libc/dns/
and partly in
system/netd/server/dns
.
Android 10 moves the DNS resolver code to
system/netd/resolv,
converts it to C++, then modernizes and
refactors the code. The code in Bionic continues to exist for app
compatibility reasons, but is no longer called by the system. These source
paths are affected by the refactoring:
bionic/libc/dns
system/netd/client
system/netd/server/dns
system/netd/server/DnsProxyListener
system/netd/server/ResolverController
system/netd/resolv
Format and dependencies
The DNS Resolver module (`com.android.resolv`) is delivered as an
APEX file and is dynamically linked by
netd
; however, netd
is not a
dependency as the module serves the local socket
/dev/socket/dnsproxyd
directly. The Binder endpoint for the
resolver configuration was moved from netd
to the resolver,
meaning that the system service can call directly into the resolver module
without going through netd
.
The DNS Resolver module depends on libc
(Bionic) and
statically links its dependencies; no other libraries are required.
mDNS .local resolution
Starting from November 2021, Android resolver supports mDNS .local resolution, which implements
"5.1 One-Shot multicast DNS Queries" in RFC 6762 to send standard DNS queries blindly to
224.0.0.251:5353 or [FF02::FB]:5353. mDNS resolution is transparently supported
by calling getaddrinfo()
with a hostname ending in *.local
.
mDNS .local resolution augments the existing functionality of getaddrinfo()
to get the addresses. If a device supports mDNS .local resolution, then the
getaddrinfo()
API sends mDNS queries to 224.0.0.251:5353 or [FF02::FB]:5353
and returns the local addresses. If a device doesn't support mDNS .local
resolution, then the getaddrinfo()
API method sends a DNS query to the DNS
server.
The code is in AOSP, located in packages/modules/DnsResolver
. Users can keep their
current mDNS design to get the addresses, or use getaddrinfo()
instead. The behavior of
this feature is like a regular DNS query sent to the mDNS multicast addresses. This feature has no
impact on system health.
Users can use the command adb shell ping6 HOSTNAME.local
,
where HOSTNAME is the hostname of a target device on the LAN, for example,
adb shell ping6 ipad.local
.
VPN and mobile data connections are excluded from .local resolution.