DNS リゾルバ

DNS リゾルバ モジュールは、DNS 傍受や設定の更新攻撃からユーザーを保護し、DNS 解決のネットワーク パフォーマンスを改善します。このモジュールには、名前(www.google.com など)を IP アドレス(2001:db8::1 など)に変換する DNS スタブリゾルバを実装するためのコードが含まれています。DNS スタブリゾルバは、InetAddress#getAllByNameNetwork#getAllByName などの Java API 要素、およびネイティブ ネットワーク機能をサポートし、DNS クエリを送受信して結果をキャッシュします。

Android 10 の変更点

Android 9 以下を搭載するデバイスでは、DNS リゾルバコードは Bionic と netd で配布されます。DNS ルックアップは、システムレベルのキャッシュのために netd デーモンに集中化され、アプリは Bionic の関数(getaddrinfo など)を呼び出します。クエリは /dev/socket/dnsproxyd の UNIX ソケットを介して 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 によって動的にリンクされます。しかし、モジュールがローカル ソケット /dev/socket/dnsproxyd を直接提供するため、netd には依存関係はありません。リゾルバ構成の Binder エンドポイントは、netd からリゾルバに移動されました。つまり、システム サービスは netd を経由せずにリゾルバ モジュールを直接呼び出すことができます。

DNS リゾルバ モジュールは 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 に送信します。mDNS の解決は、ホスト名の末尾を *.local にして getaddrinfo() を呼び出すことで、透過的にサポートされます。

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() を使用することも可能です。この機能の動作は、おおまかには、通常の DNS クエリを mDNS のマルチキャスト アドレスに送信するというものです。この機能がシステムの健全性に影響することはありません。

ユーザーは「adb shell ping6 HOSTNAME.local」というコマンドを使用できます。ここでの HOSTNAME は、LAN 上のターゲット デバイスのホスト名です(例: adb shell ping6 ipad.local)。

VPN 接続とモバイルデータ接続は .local 解決の対象とはなりません。