ヨセミテでの大きなトラブル
前OS X10.10ヨセミテのリリース初期に、Wi-Fiの接続が不安定になる、というトラブルが散見されたのはご存じでしょうか。この原因となったのは「discoveryd」という、主にホスト名からIPアドレスを調べ出したり、その逆でIPアドレスからホスト名を探すときなどに使用されるバックグラウンドのサービスでした。
こうしたトラブルにより、OS X10.10.4からは、それ以前に使われていた「mDNSResponder」に戻され、OS X10.11エルキャピタンでもそのままです。今回はこうしたIPアドレスとホスト名の相互関係と、それを担っている「名前解決」という仕組みについて、順を追って説明していきます。
その名のとおり「名前で解決」
インターネットの世界では、IPアドレスという番号で通信する相手を指名します。ちょうど、電話をかけるのに電話番号で相手を指定するように、インターネットではIPアドレスを使います。私たちがよく見かけるのはIPv4の32ビットアドレスで、8ビット(1バイト)ずつ区切って「210.154.149.63」などと表記します。
最近の携帯電話なら、アドレス帳で名前を指定すれば自動的にその電話番号に電話をかけてくれます。それと同じように、インターネット上の相手をIPアドレスという番号ではなく、系統立ったホスト名で指定できるようにする仕組みがいくつか考えられてきました。この、ホスト名からIPアドレスを導き出す動作を「名前解決」といいます。
もっとも古くからあり、もっとも単純な名前解決の手段が「/etc/hosts」というファイルです。「hostsファイル」と呼ばれるこのファイルには、IPアドレスとホスト名が1行ずつ列挙されており、プログラムはこれを参照して、ホスト名とIPアドレスを対応させるわけです。とはいえ、インターネット黎明期、せいぜい数十台のコンピュータがつながっているだけの世界ではなんとかなりましたが、台数が増えるにつれ、hostsファイルにすべてを書き、常に最新の状態に保つのは困難になりました。
そこで登場したのが「DNS(Domain Name System)」です。DNSは一定の範囲(ドメイン)ごとに責任者を定め、管理するサーバでその範囲のサーバのIPアドレスとホスト名や、付随する情報を管理するというシステムでした。たとえば、「mynavi.jp」というドメインはマイナビが管理しており、「www.mynavi.jp」が「210.154.149.171」というIPアドレスだと紐付きます。また、「.jp」はJPRSという組織が管理し、mynavi.jpを管理するサーバ(DNSサーバ)が、どのIPアドレスのホストかを管理しています。その仕組みについては図1を参照ください。
世界には13台の「.」、すなわち最上位のDNSサーバがあり、「.jp」や「.com」などのトップレベルドメインのDNSサーバがどこにあるかなどが記されています。インターネットでもっとも重要なサービスが、このDNSだともいえるでしょう。
DNSの仕組み(図1)
実際にDNSの検索を行うときは、まずネットワーク設定で指定されたDNSサーバに問い合わせを行います。このDNSサーバは、以前に検索した結果がキャッシュされているなどでIPを知っていたら即回答し、そうでない場合はDNSの探索を始めます。探索は、まず世界に13台用意されているルートのDNSサーバに問い合わせを行います。ルートサーバもIPを直接は知らないので、.jpのDNSサーバのIPアドレスを教えてそちらに聞けと返答します。そこから、jp.のDNSサーバ、mynavi.jp.のDNSサーバとIPアドレスを教えてもらい、そちらに再度問い合わせが行われます。mynavi.jpのDNSサーバがbookというホストのIPアドレスを管理しているので、最終的にここから正しいIPアドレスを教えてもらうことができます。
名前解決を順番整理
インターネットでの名前解決の仕組みとして「/etc/hosts」とDNSを説明しましたが、OS Xにはそれ以外にも「ボンジュール(Bonjour)」という、身近な機器同士での名前解決を行うサービスもあります。
ボンジュールの利点はDNSサーバのようなあらかじめ準備したサーバが必要ないこと、お互いに相手の名前とIPアドレスの関係を効率よく交換できることです。また、オープンディレクトリ(Open Directory)やアクティブディレクトリ(Active Directory)といったディレクトリサービスも組織内のコンピュータ名とIPアドレスの対応を管理しており、これらを使った名前解決もあります。
さて、どれをどの順番で使うべきでしょうか? 交通整理が重要になります。初期のOS Xでは、NeXT由来の「NetInfo」という仕組みが、この交通整理をしていました。NetInfoのサーバの1つ「lookupd」が適切に名前解決をキャッシュしたり、hostsやDNSをそれぞれ見て回りました。
lookupdはホスト名だけではなく、ユーザ名やグループ名から、UID/GIDやそのほか情報の取得をしたりといった、ホスト名以外の取得の仕組みも担っていました。lookupdはシンプルで十分な機能がありましたが、もともとの設計が1980年代のため、セキュリティ面や今後の拡張性に不安がありました。
統一が図られる名前解決
OS X10.2ジャガーでボンジュール(当時は「ランデブー(Rendezvous)」という名称)が導入されたときに、ボンジュールでの名前解決を行う「mDNSResponder」というサービスが導入されました。しかし、この当時はlookupdからmDNSResponderを呼び出す格好になっていました。
それが、次第に「ディレクトリサービス(Directory Service)」というサービスに置き換えられるようになり、lookupdを含むNetInfoは外されるようになっていきました。
OS X10.6スノーレパードの段階で、名前解決については、mDNSResponderがDNSもボンジュールもまとめて処理することで統一が図られました。それ以外は「opendirectoryd」と名前を変えたディレクトリサービスが担う、といった具合でした。
ここで気になるのがmDNSResponderの拡張性です。そもそも、mDNSResponderはボンジュール専用に作られたサーバで、ボンジュール普及のため、あえてオープンソースで公開されています。ボンジュールのプロトコルであるMulticastDNSとDNS−SDの処理をシンプルにすることで、そのサンプルとなっていました。類似のプロトコルとはいえ、通常のDNSの名前解決も加わることで複雑になってきています。
また、mDNSResponderはlookupdやディレクトリサービスが持っていたプラグインによる機能拡張の仕組みを持っていません。そのため、オープンディレクトリやアクティブディレクトリを使った名前解決などは「opendirectoryd」頼みになります。
この場合、今後の変化に弱く、たとえばウィンドウズで使用されているUPnPに対応しようとしたとき、どう実装し、どちらで処理すべきなのか困ってしまうという、なんとも中途半端な状態でした。
discoverydの問題
ここからは推測ですが、この状態を仕切り直し、次世代の名前解決の中枢となすべく実装したのが冒頭のdiscoverydだったのでしょう。ネットワークの変更をちゃんと検知していたり、ファイヤウォールや「どこでもMyMac」、省電力機能との連携などを用意し、効率化を目指していた節があります。
しかし、名前解決はネットワーク通信の非常に重要な部分です。ここが安定しないと正しい通信ができません。discoverydは意欲的でしたが、リリースするには安定性に欠いており、結果、Wi-Fiのアクセスポイントに正しく接続ができないという状態を引き起こしました。OS X10.10~10.10.3までの惨事、iOS 8での不評を受けて、とりあえず安定して動いていたmDNSResponderに戻した、というのが実態かと思われます。
【リゾルバとnsswitch 】
DNSサーバと通信して名前解決を行うための機能をリゾルバ(resolver)と呼びます。BINDというDNSソフトウェアに付属のリゾルバである「Libresolv」が有名です。これはライブラリで、各ソフトウェアに組み込んで使用します。UNIXやLinuxでは当初、hostsやDNSなどいろいろな情報源へ名前解決を固定的な順番で行っていましたが、やはり順番を設定で変えられたほうが便利となり、「Network Name Switch(NSS)」という仕組みが用意されました。「/etc/nsswitch.conf」という設定ファイルで名前解決を参照する順番を設定できます。
【UPnP 】
UPnP(ユニバーサルプラグアンドプレイ)は、1999年にマイクロソフトが提唱したプロトコルで、LAN内のデバイスを自動的に発見して、自動的に利用できるようにする、という機能です。目的と用途はほぼボンジュールと同一ですが、DNSをベースとしたボンジュールに対しHTTPをベースとしているなど実装には大きな差があります。プリンタの自動認識などはもちろん、ルータに対してポートマッピングを設定するなど、IP電話など一部アプリケーションで有益な機能がある一方、高機能故の攻撃や脆弱性の発覚などに悩まされてもいます。
【UPnP】
discoverydを解析するとUPnP(ユニバーサルプラグアンドプレイ)とみられるテキストが埋もれているのが確認できます。ヨセミテでは、UPnPにも対応しようとしたのかもしれません。
【Winの対応】
ウィンドウズ8はボンジュールに対応しておらず、iTunesをインストールしなければ使えませんでした。しかし、ウィンドウズ10ではひそかにボンジュールに対応しており、ファイアウォールの設定を変えれば相互利用できるようになっています。