【Linux】「再帰的問い合わせ」と「非再帰的問い合わせ」の区別

2022年2月6日

再帰的問い合わせと非再帰的問い合わせってどう違うんだっけ?
キャッシュDNSサーバから権威DNSサーバへの問い合わせが再帰的でしょ?

こんにちは、キクです。

DNSサーバの学習などをしていると「再帰的問い合わせ」とか「非再帰的問い合わせ」とかの概念が出てきますよね。
しかし、これらがどのような動作をするものなのかは「再帰的」という言葉に惑わされて混乱してしまうことが僕自身ありました。
最近また「そういうことか!」と感じる機会があったので、今回は整理の意味でも記事にしていこうと思います。

というわけで今回は『再帰的問い合わせと非再帰的問い合わせの違い』をテーマに書いていきたいと思います!

それでは、見ていきましょう。

そもそも「再帰的」とはどういう意味なのか

今回のテーマでもある「再帰的」とはどういう意味なのでしょうか?

辞書などで調べてみると次のような意味であることが分かります。

「再帰的」の基本的な意味

・自己の行為の結果が自己に戻ってくること
・フィードバック
・(数学などで)定義の中に定義されるものが含まれていること

これですんなりイメージできる人もいるかと思います。
ただ、僕としては「ややこしい」と感じてしまいます。

Linuxなどで言えば、例えばcpコマンドの「-r」オプションは再帰的な処理という位置付けです。
「-r」はrecursiveの「r」です。
なんとなくお察しだと思いますが「recursive =  再帰的」です。
「-r」オプションでディレクトリを指定した場合の動作は、サブディレクトリを含めてコピーが可能です。

これはつまり階層を辿って、以下のような感じでコピーを繰り返していることになります。

cpコマンドの再帰的処理のイメージ

親ディレクトリをコピー
→ サブディレクトリ1をコピー
→ サブディレクトリ2をコピー
→ ・・・

図にすると次のような感じでしょうか。

linux-recursion1

ただ、この「繰り返し」という概念がややこしさの原因でもあるような気がしています・・・(笑)
「ややこしさ」については最後にもう一度触れて払拭していきたいと思います。

キャッシュDNSサーバと権威DNSサーバ

「再帰的問い合わせ」「非再帰的問い合わせ」の内容に入る前に、DNSサーバで利用される「キャッシュDNSサーバ」と「権威DNSサーバ」について簡単に触れていきましょう。
キャッシュDNSサーバは、"利用者"つまり"クライアント"からの名前解決リクエストを受け付けて結果を返す役割を担うサーバです。

このキャッシュDNSサーバはクライアントからのリクエストの答えをキャッシュしていなければ、その答えを持っている他のサーバに問い合わせを繰り返します。
権威DNSサーバはゾーンと呼ばれる「IPアドレスとドメイン名の紐付け」などの情報を保持しており、自身が管理するゾーン情報に関する問い合わせに回答します。

逆に言えば、自分の知らない情報については答えないというスタンスです。
登場人物は出揃いました。

「クライアント」「キャッシュDNSサーバ」、そして「権威DNSサーバ」。

それぞれの関係性は、DNSにつてい調べているとよく目にする以下の構図のようになります。

キャッシュDNSサーバから権威DNSサーバに矢印が行ったり来たりしていますね。
先程のLinuxのcpコマンドでの動作に似ていますよね。
こうなると「キャッシュDNSサーバから権威DNSサーバへの問い合わせが「再帰的問合せ」なのかー」と思ってしまいがちですよね。

少なくとも僕はそう思っていました・・・。

ただ、こんな風に書くということは違うということです。

DNS視点での「再帰的問い合わせ」と「非再帰的問い合わせ」

キャッシュDNSサーバや権威DNSサーバはどのようにして「再帰的問い合わせ」または「非再帰的問い合わせ」ということを判断しているのでしょうか?
今回調査してて知ったのですが、どうやらパケットに含まれるRD(Recursion Desired)というフラグの内容によって区別されているみたいです。

RDフラグが1であれば再帰的問い合わせ。
RDフラグが0であれば非再帰的問い合わせ。

これらのどちらを受け取るかでそれぞれのサーバの動き方が変わってきます。
キャッシュDNSサーバはクライアントから「再帰的問い合わせ」を受け取ります。
この問い合わせは簡単に言えば「答えが分かるまで問い合わせ続けてくれ!」ということです。
そんな問い合わせをクライアントから受け取ったキャッシュDNSサーバは答えを知っている権威DNSサーバ達に繰り返し問い合わせをかけます。

ただ、このキャッシュDNSサーバから権威DNSサーバへの問い合わせ自体は「知ってる情報を教えて下さい」というスタンスです。
少し整理してみましょう。

再帰的問い合わせと非再帰的問い合わせ

再帰的問い合わせ :答えがわかるまで問い合わせを繰り返せ(クライアント→キャッシュDNSサーバ)
非再帰的問い合わせ:知ってる情報を教えて下さい(キャッシュDNSサーバ→権威DNSサーバ)

前者は繰り返しを促す命令ですが、後者はキャッシュサーバと権威DNSサーバとのやりとり単体を見れば単発的な命令であることが分かるかと思います。
矢印を書くとキャッシュDNSサーバから権威DNSサーバへの問い合わせが「再帰的」のように見えてしまいますが、問い合わせの意味を考えると見分けが付きやすいですよね。

では権威DNSサーバでも「再帰的問い合わせ」を受け取ったら他のサーバに聞きに行かなくては行けないのでしょうか?
必ずしもそんなことはなくて、DNSサーバ側の設定で「再帰的問い合わせ」を受け取るか受け取らないかを設定できます。
ここでは詳しくは触れませんが、DNSサーバの設定ファイル「/etc/named.conf」の「recursion」という項目を「no」にしてあげればOKです。
「recursion = 再帰的」ですから分かりやすいですよね。

Linuxの再帰的処理をもう一度考える

Linuxの「cp -r」コマンドも再帰的な処理であることは既に触れました。
先程は、このコマンドを実行すると「階層的にコピーをするから矢印が行ったり来たりする」という図を用いたので、「矢印の往復 = 再帰的」のように紐付いてしまって見えました。

しかし、DNSでは「矢印の往復」はむしろ「非再帰的問い合わせ」の方だったので少しイメージがズレてしまいますよね。
そこで登場するのがLinuxの「シェル」という存在かなと思いました。
コマンドを実行する「自分」がいて、それを受け取る「シェル」がいる。
その「シェル」はコマンドの内容を実行して、繰り返しファイルやサブディレクトリをコピーする。

図にするとこんな感じになります。

linux-recursion3

こうなるとDNSの構図と同じですよね。
それぞれ置き換えてみると、クライアントが「自分」、キャッシュDNSサーバが「シェル」、権威DNSサーバが「対象ファイル/ディレクトリ」と捉えることができます。

つまりは、DNSの「再帰的問い合わせ」にしてもcpコマンドにしても「繰り返しやってきて!」という命令自体は1本の矢印で表現できるという意味で共通していたんですね。
これで「ややこしさ」は解消できたのではないでしょうか。

おわりに

いかがだったでしょうか。

今回は「再帰的」な処理について触れていきました。
その言葉の意味からどの処理が再帰的な処理を指しているのか混乱しがちでしたが、本記事の内容で少しでも混乱が払拭されていれば嬉しいです。
僕自身も混乱してしまうことがあったので、今回記事としてまとめることで改めて理解が深まりました。

良かった。

本記事を最後までお読みいただきありがとうございました。
ではでは!

-Linux
-