リゾルバからネームサーバーへの問い合わせ
このサンプルは、一番最初に端末Aから、同じネットワークに所属するServerAへ、名前を指定してデータを送信しようとしています。しかし、 TCP/IPではIPアドレスが分からないと通信ができませんので、リゾルバがネームサーバへIPアドレスを問い合わせるメッセージを送ります。
ここで重要なのはリゾルバです。リゾルバの動きを分かりやすくするために、プログラムで動作を表現しました。サンプルプログラムの「VirtualLanToCSharp/アプリケーション層」内にある「Resolver.cs」または「Resolver.vb」を確認してください。
宛先のIPアドレスが分からない場合、リゾルバはGetHostByAddress(実装により名前は異なる)メソッドを実行します。GetHostByAddressは、あらかじめ指定されているネームサーバに、照会タイプがAのDNS照会メッセージを送ることによりIPアドレスの取得を試みます。 DNS照会メッセージを受信した、ネームサーバは自分が管理しているホストならば、DNS応答メッセージ内にIPアドレスを埋め込み返します。
DNSサーバー内の具体的な処理については、サンプルプログラムの「VirtualLanToCSharp/アプリケーション層」内にある「DnsServer.cs」または「DnsServer.vb」を確認してください。
ネームサーバでのIPアドレス照会
先ほどのサンプルプロジェクトQueryTestで端末Aとネームサーバがデータを送信した後、再び端末AがServerAへデータを送信している理由はこのリゾルバとネームサーバ間のIPアドレス照会処理にあります。
サンプルで表示される、送信データ{1+ A?}は、「メッセージID=1」「再帰要求を指定」「IPアドレスを要求している」の3点を指定するDNS要求メッセージであることを表しています。
一方DNS応答メッセージ{1* 1/0/0 A }は、「メッセージID=1」「回答が権威あるものかどうか」「回答数=1」「権威数=0」「追加情報数=0」「IPアドレスを回答」を表しています。
※これらの表現方法は「詳解TCP/IP Vol.1 プロトコル」に倣っています。
権威ある回答とは、要求されたIPアドレスを持つホストが管理下にあるかどうかを示しています。つまり、情報が正しいものであると保証できる場合に、権威ある回答と表現されます。
このように、ネームサーバが自ら管理しているIPアドレスならば処理は簡単ですが、管理外のIPアドレスを問い合わせられた場合、処理は複雑化します。
管理外のIPアドレスの照会
ネームサーバはルートネームサーバに「指定されたホストを管理しているサーバのIPアドレス」を問い合わせます。今回のサンプルは分かりやすくするために、ルートネームサーバが直接IPアドレスを返していますが、実際はルートネームサーバに教えてもらったアドレスのサーバに、アドレスを照会するためのメッセージを送り、何度か問い合わせを繰り返して、ようやく目的のIPアドレスを取得します。
例えば、「foo.co.jp」というアドレスを問い合わせた場合、ネームサーバはルートネームサーバに「jp」のIPアドレスを問い合わせ、次に「jp」のサーバに「co.jp」のIPアドレスを問い合わせ、最後に「foo.co.jp」のネームサーバへ問い合わせることによりIPアドレスを取得します。これを表しているのが2つ目の図です(再掲)。
ここでは、ルートネームサーバがデータを送信していることと、ネームサーバの回答が権威あるものだと指定されていない点に注目してください。
アドレスのキャッシュ
このように、ネームサーバが管理していないIPアドレスを取得するのは負荷がかかる作業ですので、普通は問い合わせ結果をキャッシュしておきます。そうすることにより、再度同じホストのIPアドレスの問い合わせを受けた時に、素早く応答できます。 これを示しているのが最後の画像です(再掲)。
ルートネームサーバがデータを送信していない点に注目してください。 先ほど掲載したサンプルではQueryOfAメソッドがこれらの処理に当たります。
しかし、問い合わせ結果をキャッシュをしておくことは、メリットばかりではなくデメリットもあります。それは変更に対応できない場合があることです。問い合わせた直後に、目的とするホストのIPアドレスが変更された場合、クライアントは接続できません。DNSのキャッシュによるトラブルは結構起こりますので注意してください。
なお、このサンプルでは、サーバが管理しているホストのIPアドレスは、キャッシュしていませんが、実際はキャッシュすることの方が多いので注意してください。これでDNSの基礎事項の解説は終わりです。
おわり
今回はアプリケーション層の代表的プロトコルであるDNSの基礎を解説しました。DNSは複雑なプロトコルであり、他にもいろいろな資源を問い合わせたりすることができますが、紙面の都合上紹介できませんでした。
また、他のアプリケーション層のプロトコルも紹介できませんでしたので、機会があれば解説したいと考えております。
DNSはプログラマにとっても重要なプロトコルですので、この記事をスタート地点にして、読者自身が調べられることをお勧めします。手始めにRFC1034とRFC1035を読むとよいでしょう。 次回は今までの総決算として、仮想的なネットワークを実装します。お楽しみに。
参考資料
書籍
- 『詳解TCP/IP Vol.1 プロトコル』 W.Richard Stevens著、橘康雄・井上尚司 訳、ピアソンエデュケーション、2000年12月
- 『マスタリングTCP/IP 入門編 第4版』 竹下隆史・村山公保・荒井透・苅田幸雄 著、オーム社、2007年2月
- 『インターネットRFC事典』 笠野英松 著、マルチメディア通信研究会 編、アスキー、1998年10月
ウェブサイト
- @IT 『Master of IP Network』