While I was browsing through Reddit earlier this week, I stumbled upon this post over on the DataIsBeautiful subreddit. The post compares the “supported lifespan” of Apple and Google smartphones, specifically how many years of major OS updates each phone receives. If you know even a little about Android versus iOS updates, then you can probably guess without opening the post that Google doesn’t come out looking too good in the comparison.
It’s fair to say that Apple is ahead of the competition when it comes to software support length, but if you know more than the average person does about Android versus iOS updates, then you know that it’s not an apples-to-apples (no pun intended) comparison. While iOS updates are still monolithic, ie. many system apps and libraries can’t be updated outside of full OS updates, Android updates aren’t.
Because of the way Android is distributed, Google had to modularize it to make it more easily updatable so it wouldn’t take forever for new features and security fixes to make their way to users. With Android 10 in 2019, Google introduced Project Mainline, an initiative that modularized multiple system components so they could be updated in a manner similar to standard app updates. There are nearly two dozen modular system components as part of Project Mainline, with more to come as part of the upcoming Android 13 update.
While it’s great that Mainline makes it easier to release out-of-band updates to core system components, Google has struggled to communicate to users what each “Google Play System Update” actually brings. An online support page lists some of the changes introduced in each Mainline update, but it doesn’t list everything nor does it go into any kind of detail. That brings me to the crux of this post: support for a very basic but handy networking feature finally made its way into Android, years after it was made available on all other major platforms, but hardly anyone knows about it. The feature actually rolled out as part of the Google Play System Update for November 2021, but it was never mentioned in any blog post, changelog, or other medium, which is why I’m doing this post.
Through an update to the DNS Resolver Mainline module, Android finally added support for mDNS .local resolution, solving a long-standing feature request from IoT and home networking enthusiasts.
If you aren’t familiar, mDNS is a protocol defined by the Internet Engineering Task Force (IETF), the organization that oversees the technical standards that comprise the Internet. It stands for multicast domain name system, and it’s how hostnames are resolved on local networks without their own DNS server. The mDNS protocol is defined in full in the IETF’s RFC 6762 document, but the most relevant part is Section 5.1 - One-Shot Multicast DNS Queries, as it’s what Android’s DNS resolver implements.
Without getting too technical, mDNS basically makes it possible to connect to devices on a local network using human readable names, similar to how DNS makes it possible to connect to servers over the Internet using a human readable name.
For example, when you want to access Google search on the web, you just type google.com into your browser and hit enter. Your device will then query a DNS server — usually your ISP’s default one — which then translates the name into an IP address. That IP address identifies a unique device connected to the Internet, which in this case is one of many servers owned by Google that handle its search engine website.
When you want to access the web interface of, say, a 3D printer, a Synology NAS, or Raspberry Pi on your local home network, your device will similarly need an IP address to actually connect to it. However, most home networks typically don’t have a DNS server. If you know the IP address off hand (maybe you assigned it a static IP address), then you’re good to go. If you don’t know the IP, then you may have to grab it from your router or the device itself. Alternatively, if the device you’re connecting to supports mDNS and you remember its hostname, then you may be able to connect to it by simply entering its hostname and the .local suffix in any web browser.
For example, if you configure a Raspberry Pi with Raspberry Pi OS, then by default it can be reached by pinging raspberrypi.local. When you enter this hostname into the address bar of a web browser, what basically happens is that a message is sent to all devices connected to the same network. This message prompts the host that has the name in question to broadcast (also to all devices on the network) its local IP address. Here’s a very, very simplified graphic representation of mDNS .local resolution:
In order for this to work, however, both the client (your device) and the server (presumably your other device) have to support mDNS. The mDNS protocol was turned into an IETF standard in 2013, though it was initially proposed all the way back in the year 2000. After so many years, it’s no surprise that an implementation can be found in most major platforms. Microsoft brought native support for it to Windows with Windows 10 1703 in 2016, but prior to that, users could install Apple’s Bonjour Print Services tool to use the feature. Many Linux distros implement mDNS through the Avahi daemon. Apple, as the author of the protocol, of course has a native implementation in iOS and macOS.
Android, meanwhile, has offered support for mDNS service discovery since Android 4.1 Jelly Bean … but only for apps that implement the network service discovery (NSD) API. This means that Android users, for years now, haven’t been able to simply enter a hostname followed by .local into a web browser and have it be resolved to the IP address of a local device. They’d have to hope that whatever company made the product they’re using offers an app to connect to it, create their own app if the service is something they set up, or find the IP address of the service themselves.
Power users have definitely noticed Android’s lack of native mDNS .local resolution support. The earliest Issue Tracker post I can find on the matter dates back to mid-2011. Another, more active Issue Tracker post (and the first result on Google when you search “mDNS Android”) can be found here. After the issue was acknowledged in late 2019, merely a day after the report was made, it was never followed up on with an acknowledgment of the feature being implemented, let alone that it was actually being worked on. Well, earlier this year, a few users finally did notice that mDNS .local resolution was working for them on Android 12, so all the people who starred the issue must be aware of the change.
What they likely don’t know is how the change is being distributed, which as I mentioned earlier is via an update to the DNS Resolver Mainline module. According to Google, the Android DNS resolver supports mDNS .local resolution starting from November 2021. mDNS resolution is “transparently supported” by Android, according to the documentation. The getaddrinfo() API method sends mDNS queries to the fixed mDNS IPv4 link-local multicast address or its IPv6 equivalent if the device supports mDNS .local resolution, otherwise, the API sends a unicast DNS query to the DNS server. The code for this feature is available in AOSP under the packages/modules/DnsResolver, and the patch implementing it can be found here. Although the DNS Resolver module was introduced in Android 10, it doesn’t look like the patch implementing mDNS .local resolution was backported to either Android 10 or Android 11, which is a shame.
Still, it’s always good to see new features make their way into Android, especially highly requested ones, even if it took way too long for this one to make it in. It’s also interesting to see new features be added to the platform via Project Mainline updates, which is not something we hear about all that often. Hopefully Google starts to better communicate what changes are actually included in each Google Play System Update, but if not, then you can always follow the Esper blog or my Twitter to keep up to date.