メインコンテンツまでスキップ

5. リゾルバー (RESOLVERS)

5.1. はじめに (Introduction)

リゾルバーは、ユーザープログラムとドメイン名サーバーをインターフェースするプログラムです。最も単純なケースでは、リゾルバーはユーザープログラム(例: メールプログラム、TELNET、FTP)からサブルーチンコール、システムコールなどの形式でリクエストを受け取り、ローカルホストのデータ形式と互換性のある形式で目的の情報を返します。

リゾルバーは、リゾルバーのサービスを要求するプログラムと同じマシン上に配置されていますが、他のホスト上の名前サーバーに相談する必要がある場合があります。リゾルバーは複数の名前サーバーに相談する必要がある場合や、要求された情報をローカルキャッシュに持っている場合があるため、リゾルバーが完了するのにかかる時間は、ミリ秒から数秒まで、かなり変動する可能性があります。

リゾルバーの非常に重要な目標は、以前の結果のキャッシュから応答することにより、ほとんどのリクエストからネットワーク遅延と名前サーバーの負荷を排除することです。複数のプロセス、ユーザー、マシンなどによって共有されるキャッシュは、共有されていないキャッシュよりも効率的であることが続きます。

5.2. クライアント-リゾルバーインターフェース (Client-resolver interface)

5.2.1. 典型的な機能 (Typical functions)

リゾルバーへのクライアントインターフェースは、ローカルホストの規約の影響を受けますが、典型的なリゾルバー-クライアントインターフェースには3つの機能があります:

1. ホスト名からホストアドレスへの変換 (Host name to host address translation)

この機能は、以前のHOSTS.TXTベースの機能を模倣するように定義されることがよくあります。文字列が与えられると、呼び出し側は1つ以上の32ビットIPアドレスを必要とします。DNSの下では、これはタイプA RRのリクエストに変換されます。DNSはRRの順序を保持しないため、この機能は返されたアドレスをソートするか、サービスがクライアントに1つの選択肢のみを返す場合は「最良の」アドレスを選択することができます。複数のアドレス返却が推奨されますが、単一のアドレスは以前のHOSTS.TXTサービスをエミュレートする唯一の方法である可能性があることに注意してください。

2. ホストアドレスからホスト名への変換 (Host address to host name translation)

この機能は、多くの場合、以前の機能の形式に従います。32ビットIPアドレスが与えられると、呼び出し側は文字列を必要とします。IPアドレスのオクテットは逆にされ、名前コンポーネントとして使用され、"IN-ADDR.ARPA" が接尾辞として付けられます。タイプPTRクエリは、ホストの主要名を持つRRを取得するために使用されます。たとえば、IPアドレス1.2.3.4に対応するホスト名のリクエストは、ドメイン名 "4.3.2.1.IN-ADDR.ARPA" のPTR RRを探します。

3. 汎用ルックアップ機能 (General lookup function)

この機能は、DNSから任意の情報を取得し、以前のシステムには対応するものがありません。呼び出し側は、QNAME、QTYPE、およびQCLASSを提供し、一致するすべてのRRを必要とします。この機能は、ローカルホストの代わりにすべてのRRデータにDNS形式を使用することが多く、ローカルの引用規則で処理された形式ではなく、すべてのRRコンテンツ(例: TTL)を返します。

結果タイプ (Result types)

リゾルバーが指定された機能を実行すると、通常、クライアントに返す次のいずれかの結果があります:

  • 要求されたデータを提供する1つ以上のRR (One or more RRs giving the requested data): この場合、リゾルバーは適切な形式で回答を返します。

  • 名前エラー (NE) (A name error): これは、参照された名前が存在しない場合に発生します。たとえば、ユーザーがホスト名を誤って入力した可能性があります。

  • データが見つからないエラー (A data not found error): これは、参照された名前は存在するが、適切なタイプのデータが存在しない場合に発生します。たとえば、メールボックス名に適用されたホストアドレス機能は、名前は存在するがアドレスRRが存在しないため、このエラーを返します。

ホスト名とアドレス間の変換機能は、「名前エラー」と「データが見つからない」エラー条件を単一のタイプのエラー返却に組み合わせる場合がありますが、汎用機能はそうすべきではないことに注意することが重要です。これの理由の1つは、アプリケーションが名前に関する1つのタイプの情報を最初に要求し、その後同じ名前に対して他のタイプの情報の2番目のリクエストを行う場合があるためです。2つのエラーが組み合わされている場合、無駄なクエリがアプリケーションを遅くする可能性があります。

5.2.2. エイリアス (Aliases)

特定のリクエストを解決しようとする際、リゾルバーは問題の名前がエイリアスであることを発見する場合があります。たとえば、リゾルバーは、CNAME RRを見つけたときに、ホスト名からアドレスへの変換のために与えられた名前がエイリアスであることを発見する場合があります。可能であれば、エイリアス条件はリゾルバーからクライアントに通知される必要があります。

ほとんどの場合、リゾルバーはCNAMEに遭遇したときに新しい名前でクエリを再開するだけです。ただし、汎用機能を実行する場合、リゾルバーは、CNAME RRがクエリタイプと一致する場合、エイリアスを追跡すべきではありません。これにより、エイリアスが存在するかどうかを尋ねるクエリが可能になります。たとえば、クエリタイプがCNAMEの場合、ユーザーはCNAME RR自体に関心があり、それが指す名前のRRには関心がありません。

エイリアスではいくつかの特別な条件が発生する可能性があります。複数レベルのエイリアスは、効率の欠如のために避けるべきですが、エラーとして通知すべきではありません。エイリアスループと存在しない名前を指すエイリアスはキャッチされ、エラー条件がクライアントに返される必要があります。

5.2.3. 一時的な障害 (Temporary failures)

完璧ではない世界では、すべてのリゾルバーは時折特定のリクエストを解決できなくなります。この状態は、リンク障害やゲートウェイの問題によりネットワークの残りの部分から分離されたリゾルバー、または特定のドメインのすべてのサーバーの同時障害または利用不可によって引き起こされる可能性があります。

この種の状態を、名前またはデータが存在しないエラーとしてアプリケーションに通知すべきではないことが不可欠です。この種の動作は人間にとって迷惑であり、メールシステムがDNSを使用する場合に大混乱を引き起こす可能性があります。

場合によっては、リクエストを無期限にブロックすることでこのような一時的な問題に対処することが可能ですが、これは通常、特にクライアントが他のタスクに移動できるサーバープロセスである場合には、良い選択ではありません。推奨される解決策は、既存のHOSTS.TXT機能のエミュレーションがより困難になる可能性がありますが、リゾルバー機能の可能な結果の1つとして常に一時的な障害を持つことです。

5.3. リゾルバーの内部構造 (Resolver internals)

すべてのリゾルバー実装は、わずかに異なるアルゴリズムを使用し、通常、典型的な発生よりもさまざまな種類のエラーの処理にはるかに多くのロジックを費やします。このセクションでは、リゾルバー操作の推奨される基本戦略の概要を示しますが、詳細は [RFC-1035] に残します。

5.3.1. スタブリゾルバー (Stub resolvers)

リゾルバーを実装するための1つのオプションは、解決機能をローカルマシンから移動し、再帰クエリをサポートする名前サーバーに移動することです。これにより、リゾルバー機能を実行するリソースが不足しているPCでドメインサービスを提供する簡単な方法を提供したり、ローカルネットワークまたは組織全体のキャッシュを集中化したりできます。

残りのスタブに必要なのは、再帰リクエストを実行する名前サーバーアドレスのリストだけです。このタイプのリゾルバーは、ドメインデータベースでそれを見つける洗練さが欠けている可能性があるため、構成ファイルに情報が必要であると推定されます。ユーザーは、リストされているサーバーが再帰サービスを実行することを確認する必要もあります。名前サーバーは、任意のまたはすべてのクライアントに対して再帰サービスの実行を拒否することができます。ユーザーは、サービスを実行する意思のある名前サーバーを見つけるために、ローカルシステム管理者に相談する必要があります。

このタイプのサービスにはいくつかの欠点があります。再帰リクエストは実行に任意の時間がかかる可能性があるため、スタブは、失われたUDPパケットとデッドサーバーの両方に対処するために再送信間隔を最適化するのが難しい場合があります。スタブが再送信を新しいリクエストとして解釈する場合、あまりに熱心なスタブによって名前サーバーは簡単に過負荷になる可能性があります。TCPの使用は答えかもしれませんが、TCPはホストの能力に、実際のリゾルバーのそれと同様の負担をかける可能性があります。

5.3.2. リソース (Resources)

リゾルバーは、独自のリソースに加えて、ローカル名前サーバーによって維持されているゾーンへの共有アクセスも持っている場合があります。これにより、リゾルバーはより迅速なアクセスの利点を得ますが、リゾルバーは、キャッシュされた情報がゾーンデータを上書きしないように注意する必要があります。この議論では、「ローカル情報」という用語は、キャッシュとそのような共有ゾーンの和集合を意味することを意図しており、両方が存在する場合、権威データは常にキャッシュされたデータよりも優先して使用されることを理解しています。

次のリゾルバーアルゴリズムは、すべての機能が汎用ルックアップ機能に変換されていることを前提とし、リゾルバーで進行中のリクエストの状態を表すために次のデータ構造を使用します:

SNAME

検索しているドメイン名。

STYPE

検索リクエストのQTYPE。

SCLASS

検索リクエストのQCLASS。

SLIST

リゾルバーが現在クエリしようとしている名前サーバーとゾーンを記述する構造。この構造は、目的の情報を保持している名前サーバーに関するリゾルバーの現在の最良の推測を追跡します。到着した情報が推測を変更すると更新されます。この構造には、ゾーン名の同等物、ゾーンの既知の名前サーバー、名前サーバーの既知のアドレス、および次に試すのに最適なサーバーを提案するために使用できる履歴情報が含まれます。ゾーン名の同等物は、SNAMEがクエリされているゾーンと共通してルートから下に持っているラベルの数の一致カウントです。これは、リゾルバーがSNAMEにどれだけ「近い」かの尺度として使用されます。

SBELT

SLISTと同じ形式の「セーフティベルト」構造で、構成ファイルから初期化され、リゾルバーが名前サーバー選択をガイドするローカル情報を持っていないときに使用すべきサーバーをリストします。一致カウントは、ラベルが一致することが知られていないことを示すために-1になります。

CACHE

以前の応答からの結果を格納する構造。リゾルバーは、TTLが期限切れになった古いRRを破棄する責任があるため、ほとんどの実装は、RRがキャッシュに格納されるときに、到着したRRで指定された間隔を何らかの絶対時間に変換します。TTLを個別にカウントダウンする代わりに、リゾルバーは、検索の過程でそれらに遭遇したときに古いRRを無視または破棄するか、古いRRによって消費されるメモリを回収するために定期的なスイープ中にそれらを破棄します。

5.3.3. アルゴリズム (Algorithm)

トップレベルアルゴリズムには4つのステップがあります:

  1. 回答がローカル情報にあるかどうかを確認 し、ある場合はクライアントに返します。

  2. 尋ねるのに最適なサーバーを見つけます

  3. 1つが応答を返すまでクエリを送信します

  4. 応答を分析 し、次のいずれかを行います:

    a. 応答が質問に答えるか、名前エラーを含む場合、データをキャッシュし、クライアントに返します。

    b. 応答に他のサーバーへのより良い委任が含まれている場合、委任情報をキャッシュし、ステップ2に進みます。

    c. 応答がCNAMEを示し、それが回答自体ではない場合、CNAMEをキャッシュし、SNAMEをCNAME RRの正規名に変更し、ステップ1に進みます。

    d. 応答がサーバー障害またはその他の奇妙な内容を示している場合、SLISTからサーバーを削除し、ステップ3に戻ります。

ステップ1: ローカル情報を検索 (Step 1: Search local information)

ステップ1は、目的のデータのキャッシュを検索します。データがキャッシュにある場合、通常の使用には十分であると想定されます。一部のリゾルバーには、リゾルバーにキャッシュされたデータを無視し、権威サーバーに相談するように強制するユーザーインターフェースのオプションがあります。これはデフォルトとして推奨されません。リゾルバーが名前サーバーのゾーンに直接アクセスできる場合、目的のデータが権威形式で存在するかどうかを確認し、存在する場合は、キャッシュされたデータよりも権威データを優先して使用する必要があります。

ステップ2: 最適なサーバーを見つける (Step 2: Find best servers)

ステップ2は、必要なデータを尋ねる名前サーバーを探します。一般的な戦略は、SNAMEから開始して、SNAMEの親ドメイン名、祖父母、そしてルートに向かってローカルで利用可能な名前サーバーRRを探すことです。したがって、SNAMEがMockapetris.ISI.EDUの場合、このステップはMockapetris.ISI.EDUのNS RRを探し、次にISI.EDU、次にEDU、次に . (ルート) を探します。名前サーバーのリストが見つかったら、リゾルバーは優先順位と予想されるパフォーマンスに応じてそれらをソートする必要があります。リゾルバーは、最も優先されるものから順に、その順序でサーバーに連絡しようとする必要があります。

ステップ3: クエリを送信 (Step 3: Send queries)

ステップ3は、応答が受信されるまでクエリを送信します。基本的なアルゴリズムは、各送信間にタイムアウトを持ってすべてのサーバーのすべてのアドレスを循環することです。リゾルバーは、可能な場合はクエリにUDPを使用し、応答が切り詰められている場合またはリゾルバーがTCP接続の確立と切断のオーバーヘッドを支払う意思がある場合にのみTCPを使用する必要があります。

ステップ4: 応答を分析 (Step 4: Analyze response)

ステップ4は応答を分析します。リゾルバーは、応答の解析において非常にパラノイア的である必要があります。また、応答のIDフィールドを使用して、応答が送信したクエリと一致することを確認する必要があります。