onseok

DNS-over-HTTP/3 on Android

In July 2022, Google announced a significant security update for Android: support for DNS-over-HTTP/3 (DoH3). This is a groundbreaking technology that enhances network performance while simultaneously protecting user privacy.

The DNS Privacy Problem

Most network connections begin with a DNS Lookup. When we visit a website, our content is delivered securely over HTTPS, yet the DNS query that finds the website’s address has traditionally been sent over unencrypted UDP.

This is analogous to sealing a letter in an envelope for protection while leaving the recipient’s address visible for anyone to see. In other words, someone could observe which websites we are trying to visit.

Android’s Solution

The Private DNS feature introduced in Android 9.0 (Pie) attempted to address this issue through DNS-over-TLS (DoT). However, DoT had several performance limitations.

For reference, DoT is defined in RFC 8310.

The first issue is Head-of-Line (HOL) Blocking, a chronic problem with TCP. When processing multiple DNS queries over a single connection, if one request is delayed, all subsequent requests must wait in order. This is similar to being at a bank where one customer’s lengthy transaction holds up everyone else in line.

The second issue is something I have frequently encountered firsthand when testing on older Android devices at work. Due to the nature of mobile environments, network transitions happen frequently. Every time the device switches from WiFi to cellular, or from 4G to 5G, the TCP connection must be renegotiated from scratch. This is a process that consumes significant time and resources.

Because of these issues, DoT connections in real-world environments tended to be very short-lived, and the overhead from connection restarts was substantial. Ultimately, this prevented encrypted DNS from delivering its full benefits.

HTTP/3 and QUIC

To overcome these limitations, Google introduced a new approach called DNS-over-HTTP/3 (DoH3). The key technology behind this is the QUIC protocol used by HTTP/3.

QUIC is built on top of UDP. If you have studied networking, you likely know that UDP is considered unreliable. While that was true of traditional UDP, QUIC does not simply ride on top of UDP. Instead, it uses UDP as a canvas to design an entirely new transport protocol.

The most significant innovation is the redesign of multiplexing. In QUIC, multiple data streams exist independently. Returning to the bank analogy, each counter now has its own separate line, so a problem at one counter has no effect on the others. In other words, if one DNS query is delayed, other DNS queries continue to proceed unaffected.

QUIC also introduces the concept of a Connection ID, which allows the existing connection state to be maintained even when the IP address or port number changes. When a mobile device switches from WiFi to LTE, connections previously had to be torn down and re-established. With QUIC, the connection persists seamlessly, much like maintaining a phone call while moving from home to the office.

RTT (Round Trip Time) optimization is another important feature. While TCP + TLS requires at least two round trips for connection establishment, QUIC needs only one round trip for the initial connection. For reconnections, it supports 0-RTT, enabling immediate data transmission. If a previous connection has been established, authentication and data transfer can proceed simultaneously, making it extremely fast.

For more details on QUIC, see RFC 9000.

Real-World Performance of DoH3

In Google’s real-world testing, DoH3 reduced DNS query response times by approximately 24%. The performance improvement was particularly notable under poor network conditions, with a 44% improvement in response times at the 95th percentile. This is thanks to QUIC’s improved flow control and packet loss detection mechanisms.

In terms of reliability, DoH3 also demonstrated stable performance, maintaining a 97% success rate nearly identical to DoT. (The traditional UDP approach had an 83% success rate under the tested network conditions.)

A Safe Implementation in Rust

Google chose Rust for the DNS-over-HTTP/3 implementation. When analyzing Android crash logs, you can occasionally find Rust code in AOSP. Notably, the DNS-over-HTTP/3 implementation was the first use of Rust in a Mainline module on the Android platform.

The DNS resolver is a core component that directly handles external input, making security particularly critical. Rust’s memory safety guarantees and strict ownership model are well-suited to meeting these requirements, which I believe is why Google chose Rust for this implementation.

In practice, the DoH3 implementation was completed in just 1,640 lines of code and uses only a single thread. Compared to the existing DoT implementation, it provides a more concise yet safer codebase. It also leverages a single-threaded Tokio runtime (Tokio itself supports multi-threaded execution, but this module uses a single-threaded configuration) for efficient asynchronous I/O processing.

An important detail is the use of quiche, an HTTP/3 library developed by Cloudflare. This library guarantees memory safety while integrating smoothly with C++, making it well-suited for incorporation into the existing Android codebase.

These technical choices collectively gave rise to the first Rust-implemented Mainline module on the Android platform. Through Mainline (Google Play system update mechanism), these improvements can be delivered more quickly to a wider base of Android users.

For more details on Mainline, introduced starting with Android 10, see the AOSP - Mainline documentation.

Closing Thoughts

As Rust is gradually being adopted across the Android platform, I have personally been studying Rust in my spare time as well. (though I haven’t had as much time with it as I’d like.)

Although I have not yet reached the level of fully understanding Rust code implementations, I believe DNS-over-HTTP/3 is a technology that successfully achieves both privacy protection and performance improvement simultaneously.

Above all, I learned that security and performance do not necessarily have to be a trade-off. While reading through the RFC documents, I also gained insight into the design philosophy of modern network protocols. What impressed me most was that these protocols do not simply patch the shortcomings of their predecessors but represent a fundamental redesign that accounts for the characteristics of mobile environments, such as network transitions and packet loss.

Additionally, the modular update system through Mainline works around the Android platform’s fragmentation problem while enabling the rapid adoption of new technologies. As an Android developer, I also discovered that the compatibility issues I always had to consider during development and QA are gradually being resolved through this approach.

References

  1. Google Security Blog: DNS-over-HTTP/3 in Android
  2. Android Developer Guide: Private DNS
  3. HTTP/3 & QUIC RFC 9000
  4. Cloudflare quiche GitHub Repository

#android #http3 #network #rust #aosp