パソコン実習室
アドレス検索 - DNSの話
≪ previous next ≫

X.DNSメッセージ

 リゾルバとネームサーバー、あるいはネームサーバー間で交わされる名前解決の問い合わせや応答は、DNSメッセージとしてフォーマットが決められています。

 DNSメッセージは次の5つのセクションで構成されます。

ヘッダ部 (Header Section)
問い合わせ部 (Query Section)
回答部 (Answer Section)
権威部 (Authority Section)
付加情報部 (Additional information Section)

 セクションは5種類ありますが、1つのDNSメッセージにすべてのセクションが含まれている訳ではありません。問い合わせや応答を行うプログラム(リゾルバ&ネームサーバー)が、必要なセクションを組み合わせてDNSメッセージを構成します。

 ヘッダ部は必須(1つのメッセージに1つのヘッダ)ですが、ヘッダ以外のセクションは状況によってその数が変化します。またヘッダ部のサイズは12バイト固定長ですが、他のセクションは可変長になっています。

各セクションのフォーマットは以下の通りです。


X.1.ヘッダ部 (Header Section)

 ヘッダ部のサイズは12バイト固定長で、次の項目で構成されています。下の表は1行が2バイト(16ビット)に相当します。

ID
QROPCodeAATCRDRAZRCode
QDCount
ANCount
NSCount
ARCount

  • ID (IDentification) [size : 16bit]
    メッセージ識別用のID。
    問い合わせ送出側が設定する数値で、応答メッセージにコピーされます。
    問い合わせ側はIDをチェックすることで、問い合わせと応答の対応を確認します。

  • QR (Query/Response) [size : 1bit]
    メッセージが[問い合わせ]なのか[応答]なのかを示すフラグ。
    0 : 問い合わせ。
    1 : 応答。

  • OPCode (OPeration Code) [size : 4bit]
    問い合わせのタイプを数値で示します。値は次の意味を持ちます。
    0 : 標準問い合わせ (Standard Query)
    通常(正引き、逆引き)の問い合わせ。
    1 : 逆問い合わせ (Inverse Query)
     例えば、Aレコードはホスト名からIPアドレスを検索する目的で記述されますが、このAレコードを対象にして、IPアドレスからホスト名を検索することを逆問い合わせといいます。この機能は、あまりサポートされてないようです。
    2 : サーバーの状態 (STATUS)

  • AA (Authoritative Answer) [size : 1bit]
    問い合わされたドメイン(ホスト)名に、権威を持っているネームサーバーの応答か否かを示すフラグ。(応答メッセージでのみ有効)
    0 : 権威を持っていないネームサーバーの応答。
    ※ 反復的問い合わせで得た回答をスタブリゾルバへ返す時、ローカルネームサーバーは
      この値を 0 にセットします。
    1 : 権威を持っているネームサーバーの応答。

  • TC (TrunCation) [size : 1bit]
    応答メッセージのサイズが既定値(512バイト)を超えたことを示すフラグ。
     ネームサーバーは応答メッセージが512バイトを超えてしまう時、512バイト以降のメッセージを切り捨て TC=1 にセットします。
     TC=1 の応答メッセージを受けた問い合わせ元は、通信方式をTCP(Transmission Control Protocol)に変更して問い合わせをやり直します。
    ※ DNSメッセージの通信方式はUDP(User Datagram Protocol)が採用されていて、IPv4の仕様で
      はメッセージサイズは512バイトに制限されています。
    ※ 機能を拡張したEDNS(Extension Mechanisms for DNS)が1999年に標準化されて、こうした
      制限は実用上無くなりましたが、EDNSに未対応の機器も混在しています。

  • RD (Recursion Desired) [size : 1bit]
    再帰要求のフラグ。
    RD=1 のセットは、問い合わせ先のネームサーバーに再帰的な処理を要求します。
    0 : 反復的処理を要求。
    1 : 再帰的処理を要求。
    ※ スタブリゾルバはフラグをセット(RD=1)して、問い合わせのメッセージをローカルネーム
      サーバーに送ります。この値は応答メッセージにコピーされます。

  • RA (Recursion Available) [size : 1bit]
    再帰可能のフラグ。(応答メッセージでのみ有効)
    ネームサーバーが再帰的な問い合わせをサポートしているか否かを表します。
    0 : 再帰的問い合わせをサポートしていない。
    1 : 再帰的問い合わせをサポートしている。

  • Z (Zero) [size : 3bit]
    将来の拡張用です。常に 0 にしておきます。

  • RCode (Reply Code) [size : 4bit]
    応答コード。問い合わせの処理状況を表します。
    0 : エラーなし。
    1 : フォーマットエラー。解釈できない問い合わせ。
    2 : サーバー障害。
    3 : ドメイン(ホスト)名エラー。
    問い合わせで指定されたドメイン(ホスト)名が存在しない。
    4 : 未実装。要求された種類の問い合わせをサポートしていない。
    5 : 拒否。ネームサーバーに設定されたアクセス制御等により、要求や問い合わせが拒否された。

  • QDCount(Query Count) [size : 16bit]
    問い合わせ部のエントリ数。(問い合わせの数)

  • ANCount(ANswer Count) [size : 16bit]
    回答部の資源レコード数。

  • NSCount(Authority Count) [size : 16bit]
    権威部の資源レコード数

  • ARCount(Additional information Count) [size : 16bit]
    付加情報部の資源レコード数。

X.2.問い合わせ部 (Query Section)

 問い合わせ内容を定義する以下の項目で構成されます。各項目のサイズは固定長の部分と可変長の部分があります。
問い合わせ部のエントリ数はヘッダ部のQDCountにセットされますが、通常は1つです。

QNAME
QTYPE
QCLASS

  • QNAME (Query NAME) [size : 可変長]
    問い合わせのドメイン(ホスト)名を、下記要領で変換して格納します。
    • 各ラベルの先頭に、そのラベルの文字数を6ビットの数値で付加します。
      ※ 後述の[メッセージ圧縮]との関係で6ビットになっています。
    • ラベルを連結しているドット(.)は省略します。
    • ルートドメインの部分は文字数 0x00 が入ります。
      0x00(いわゆるNULL)は、QNAMEの末尾(終了部)を表すことになります。

    例えば www.project.ed.jp. は次のように変換されます。
    変換前の文字www.project.ed.jp.
    ASCIIコード037777770770726F6A656374026564026A7000

  • QTYPE (Query TYPE) [size : 16bit]
    問い合わせる資源レコードのタイプを2バイト(16ビット)の数値で指定します。
    代表的なタイプは以下の通りです。
    数値125612131415
    レコードタイプANSCNAMESOAPTRHINFOMINFOMX

  • QCLASS (Query CLASS) [size : 16bit]
    問い合わせる資源レコードのクラスを2バイト(16ビット)の数値で指定します。
    現在は IN(internet) 用を表す 1 のみが使われています。

X.3.回答部 (Answer Section)

 ネームサーバーは、問い合わせ部のQNAME(ドメイン/ホスト名), QTYPE(資源レコードタイプ)に一致する資源レコードを検索し、一致した資源レコードのデータを下記フォーマットで記述します。回答部の数はヘッダ部のANCountにセットされます。


NAME
TYPE
CLASS
TTL
RDLENGTH
RDATA

  • NAME [size : 可変長]
     資源レコードを定義しているドメイン(ホスト)名。資源レコードのowner欄と同じ名称になります。
     名称の記述は問い合わせ部のQNAMEと同じ要領で変換されますが、応答メッセージ内にすでに同じような名称がある場合、それを利用してメッセージの圧縮を行います。

  • TYPE [size : 16bit]
     資源レコードのタイプを2バイト(16ビット)の数値で表します。タイプと数値の対応は問い合わせ部のQTYPEを参照して下さい。

  • CLASS [size : 16bit]
     資源レコードのクラス。問い合わせ部のQCLASSと同じになります。


  • TTL [size : 32bit]
     資源レコードの有効期間(キャッシュ用)。資源レコードのttl欄と同じ値になります。

  • RDLENGTH [size : 16bit]
     RDATAの長さをバイト(8ビット)単位で示します。長さにはラベルを表している文字列の外に、ラベルの文字数、メッセージ圧縮の記号も含みます。

  • RDATA [size : 可変長]
     資源レコードの資源の部分(name-server-dname, address, canonical-name等)が入ります。SOAレコードの場合はsource-dname, mbox, serial〜minimumまで入ります。
     このフィールドに記述されるドメイン(ホスト)名も問い合わせ部のQNAMEと同じ要領で変換され、メッセージ圧縮の対象になります。
※ QTYPEがA(IPアドレス検索)で検出した資源レコードがCNAMEの場合、回答部にはCNAMEレコード
  と、それに対応するAレコードの2つが入ります。
※ 参照先としてネームサーバー名(NSレコード)とIPアドレス(Aレコード)を返す時は、回答部ではなく
  権威部と付加情報部にセットします。


X.4.権威部 (Authority Section)

 回答部と同じフォーマットで、権威部の数はヘッダ部のNSCountにセットされます。
 回答部の資源レコードに対して権威を持っているNSレコードのデータが入ります(省略されることもあるようです)。参照先ネームサーバーのNSレコードも権威部に記述されます。
※ NSレコードに付随するAレコード(グルーレコード)は、付加情報部に記述します。

 問い合わせの内容が存在しないホスト(サブドメイン)や資源レコードの時には、権威部にはSOAレコードが記述されます。


X.5.付加情報部 (Additional information Section)

 回答部と同じフォーマットで、付加情報部の数はヘッダ部のARCountにセットされます。
 回答部や権威部に対応した資源レコード(Aレコード)がある時、そのデータは付加情報部に記述されます(省略されることもあるようです)。


X.6.メッセージ圧縮

 DNSメッセージは資源レコードを扱っているため、同じドメイン(ホスト)名が多数含まれていることがあります。同じ名称をいくつも記述する代わりに、すでに記述してある位置の情報(ポインタ)を示して同じ内容であるということにすれば、メッセージサイズを抑えることができます。DNSメッセージのこうした操作をメッセージの圧縮といいます。

 記述位置を示すポインタは、2ビットのフラグと14ビットのoffset(合計16ビット:2バイト)で構成されます。
flag
(2bit)
offset (14bit)
  • flag
    先頭2ビットのフラグによって、ポインタ前半(1バイト:8ビット)の残り6ビットは次のように判断されます。
    フラグフラグの意味
    11ポインタ。残り6ビットと、後続の8ビット(計14ビット)はoffset。
    10ポインタ拡張用に予約。
    01ポインタ拡張用に予約。
    00ラベル文字数。残り6ビットはラベル文字数。

  • offset
    記述済みドメイン(ホスト)名の位置が、DNSメッセージの先頭から何バイト離れているかを示す情報で、DNSメッセージの先頭を 0 (ゼロ)として算出します。
 ポインタはドメイン(ホスト)名の代わりに記述されます。DNSメッセージのドメイン名欄のデータは、ラベル文字なのかポインタなのか、ラベル文字数(ポインタ前半)欄の先頭2ビットを見ないと判断できません。
 先頭の2ビットが"11"であれば、続く14ビットはポインタのoffset、"00"なら続く6ビットはラベル文字数と解釈されます。
※ 結果として文字数用に使えるビット数は6となり、ラベルの長さは最大63文字に制限されます。



メッセージの圧縮はどのようなものか、以下にその例を示します。

【 例1. Aレコード検出時の応答 】
 下表は、IPアドレスの問い合わせ [QNAME=www.project.ed.jp.、QTYPE=A (ホスト名 → IPアドレス検索)] に対する応答メッセージで、該当ホスト名のAレコードが検出された結果のイメージです。
 分かり易くするためラベル名以外の項目は省略し、ラベル名もASCIIコードではなくアルファベットで表現しています。
※ 応答メッセージの先頭にはコピーされた問い合わせ部があります。

addr0123456789ABCDEF
0000ヘッダ部03www
001007project02ed02jp00Q-
0020-TYPEQCLASSC00CTYPECLASSTTLRDLENGTH
0030IP-address権威部
0040以下省略

 ヘッダ部に続く 0x000C 〜 0x0023 がコピーされた問い合わせ部、0x0024 〜 0x0033 が回答部になります。
 回答部(0x0024〜)の先頭には NAME欄 があります。この位置(赤で表示)を見ると、0xC0(ビット表示:1100 0000) となっていてポインタであることが分かります。 ポインタのoffsetは直後のデータ 0x0C を連結した値 0x000C になるので、ここを参照先(青で表示)として組み立てた文字列が NAME と解釈されます。
参照先addressdata摘要
0x000C03文字数 = 3
0x000D 〜 0x000F文字コードwww (3文字)
0x001007文字数 = 7
0x0011 〜 0x0017文字コードproject (7文字)
0x001802文字数 = 2
0x0019 〜 0x001A文字コードed (2文字)
0x001B02文字数 = 2
0x001C 〜 0x001D文字コードjp (2文字)
0x001E00文字数 = 0
 文字数 = 0 となったところ(ルート)で文字列の組み立ては終了し、今回の場合は www.project.ed.jp.が得られます。

※ 回答部の末尾には可変長の RDATA フィールドがあります。
  今回の回答部はAレコードなので IP-address と表示しています。
  IPv4のIPアドレスは4バイトで表現できるので、RDLENGTHには"4"が入っていることになります。



【 例2. CNAMEレコード検出時の応答 】
 上記はホスト名全体が一致した場合の例ですが、後半部分が一致した時にもメッセージの圧縮は行われます。例えば該当ホスト名のレコードがCNAMEだった時の応答メッセージは以下のようになります。
 例として www.project.ed.jp. の正規名は nsw.project.ed.jp. であると仮定します。
※ CNAMEの資源レコードは V.3.4.CNAMEレコード を参照して下さい。

addr0123456789ABCDEF
0000ヘッダ部03www
001007project02ed02jp00Q-
0020-TYPEQCLASSC00CTYPECLASSTTLRDLENGTH
003003nswC010C030TYPECLASSTTL
0040RDLENGTHIP-address権威部
0050以下省略

 ヘッダ部とコピーされた問い合わせ部は前回と同じですが、その後には2つの回答部が続きます。それぞれのメッセージ圧縮の部分を見てみましょう。
  • 1つ目の回答部 [CNAMEレコード] 0x0024 〜 0x0035
    • NAME欄には[Aレコード検出時の応答]と同じポインタフラグとoffsetがあります。同じ処理が行われて、NAMEは www.project.ed.jp.と解釈されます。
    • CNAMEレコードのRDATA欄にはホストの正規名が入ります。今回のRDATA欄は 0x0030 〜 0x0035 に割り当てられていて次のように解釈されます。
      RDATAdata摘要
      0x003003文字数 = 3
      0x0031 〜 0x0033文字コードnsw (3文字)
      0x0034C0ポインタフラグ ON
      0x003510offsetは 0x0010
      nsw 以降はポインタの指示する参照先をルートまで連結して完成します。
      参照先addressdata摘要
      0x001007文字数 = 7
      0x0011 〜 0x0017文字コードproject (7文字)
      以下省略 (【例1. Aレコード検出時の応答】を参照)

      正規ホスト名は nsw.project.ed.jp. と解釈されます。

    ※ この時、RDLENGTHには"6"がセットされているので、次のメッセージとの境界が判別できます。

  • 2つ目の回答部 [Aレコード] 0x0036 〜 0x0045
    NAME欄(0x0036〜)はポインタになっています。offsetは 0x0030 になっていて、1つ目回答部 [CNAMEレコード]のRDATA欄の先頭を指しています。
    参照先にもポインタがありますが、CNAMEレコードの正規ホスト名の時と同じ処理が行われて、NAME=nsw.project.ed.jp. と解釈されます。



≪ previous [[ アドレス検索 - DNSの話 ]] next ≫