unboundのCNAME処理
処理内容
権威からCNAMEが返ってきた場合、 キャッシュサーバーでは別名を引きに行かなくてはいけない。
仮に下記のような登録があった場合、キャッシュサーバーにて cname.jp.への問い合わせとanswer.jpへの問い合わせを行い、 それらのレコードを合成して結果を返す必要がある
[cname.jp] cname.jp. CNAME IN answer.jp.
[answer.jp] answer.jp. A IN 1.1.1.1
[クライアントに返す必要があるレスポンス] cname.jp. CNAME IN answer.jp. answer.jp. A IN 1.1.1.1
権威からのCNAME受信
process_response(権威サーバーからのメッセージをparse) processQueryResponse(レスポンス処理) iter_handle iter_dns_store(rrsetのみをキャッシュ) handle_name_response iter_add_prepend_answer(クライアントへのレスポンスで必要なのでストアしておく) iter_qstateのqchase入れ替えしてqstateを初期化 next_state(iq, INIT_REQUEST_STATE)
CNAMEで返ってきたrrsetを iter_qstateのan_prepend_listに追加しておき、 qchaseをCNAMEから取り出した内容で置き換えて (元の問い合わせはmodule_qstateのqinfoに入っている) 再度リクエスト処理を行う。
INIT_REQUEST_STATEからリクエストを開始するので、 キャッシュがあれば通常通りキャッシュが使用される。
クライアントへのレスポンス
iter_handle processFinishded iter_prepend(an_prepend_listにストアしていたものを取り出し、dns_msgを作り直す) iter_dns_store(msgとrrset両方キャッシュする)
CNAME先の問い合わせとan_prepend_listにストアしていたものを 合成してレスポンスを作成する
合成したものをキャッシュにストアしておく。
まとめ
CNAMEでのリクエストがあった場合には Aレコードをストアしておき問い合わせ名を変えて再度リクエスト。 クライアントに返せる状態になってからAレコードを取り出し合成する。 合成した情報をキャッシュに入れて次回のリクエストに備えている。
おまけ
CNAMEの無限ループを抑えるため、MAX_RESTART_COUNT以上CNAMEを辿らないようになっている MAX_RESTART_COUNTは8となっている。