Unboundのtarget_fetch_policy
target-fetch-policyについて
マニュアルを見ても「ターゲット アドレスを日和見的に取ってくる」 となってよくわからなかったのでソースから調べてみた。
結果
設定値
デフォルトは”3 2 1 0 0" 数字の並びは左から深度に対応している 深度は委任レコードを返された時に外部名だった場合外部名をたどる回数となる 外部名探索中にさらに外部名が見つかった場合には深度2となり左から2番目の数値が参照される。
数字はいくつの外部名を同時に探すかに対応する。 Unboundでは複数の外部名があった場合同時に問い合わせを行い、レスポンスが速いものが使用される。
0と1の違い
外部名しか存在しない場合は0と1に違いはない 外部名と内部名が混在していた場合、0では内部名のアドレスに対して問い合わせるのと同時に 外部名に対しても1つ問い合わせを行う
-1
-1が指定されていた場合にはすべての外部名の探索が行われる
深度より多い問い合わせ
深度 -1以上の問い合わせは行わないようになっている 例えば”3 1”と指定された場合始めの外部名では3つに対して問い合わせを行うが さらに外部名に出会った時には処理を終了する。
何故-1なのかはわからなかった。
ソースコード
コンフィグから値の設定
iter_init iter_apply_cfg read_fetch_policy
max_dependency_depthとtarget_fetch_policyに使用している max_dependency_depthには設定した個数-1が入る
使用場所
processQueryTargets query_for_targets
processQueryTargetsの中はだいたい以下のようになっている
// 現在の深度の問い合わせ個数取得 tf_policy = ie->target_fetch_policy[iq->depth]; if(iq->caps_fallback) { // 0x20エンコードの時は強制的に全ての外部名をたどる query_for_targets(qstate, iq, ie, id, -1, &extra) .... } else if(tf_policy != 0) { // それ以外の場合には問い合わせ個数分取得 query_for_targets(qstate, iq, ie, id, tf_policy, &extra); .... } // すでにアドレスが分かっている問い合わせ先を取得(内部名やキャッシュされている場合ここで見つけられる) target = iter_server_selection(...) if ( !target ) { // 問い合わせ先がなければ一つだけ問い合わせる query_for_targets(qstate, iq, ie, id, 1, &extra); }
実験
unboundに付属しているtestboundで試すことができる
server: target-fetch-policy: "2 0" do-ip6: no stub-zone: name: "." stub-addr: 0.0.0.1 CONFIG_END SCENARIO_BEGIN my test RANGE_BEGIN 0 100 ADDRESS 0.0.0.1 ENTRY_BEGIN MATCH opcode qtype qname ADJUST copy_id REPLY QR NOERROR SECTION QUESTION . IN NS SECTION ANSWER . IN NS A.ROOTSERVERS.NET. SECTION ADDITIONAL A.ROOTSERVERS.NET. IN A 0.0.0.1 ENTRY_END ENTRY_BEGIN MATCH opcode qtype qname ADJUST copy_id REPLY QR NOERROR SECTION QUESTION test.jp. IN A SECTION AUTHORITY jp. IN NS b.jp jp. IN NS a.jp jp. IN NS c.jp jp. IN NS d.jp SECTION ADDITIONAL d.jp IN A 1.1.1.1 ENTRY_END RANGE_END STEP 1 QUERY ENTRY_BEGIN REPLY RD SECTION QUESTION test.jp. IN A ENTRY_END STEP 10 NOTHING SCENARIO_END
実行結果の一部
[0] unbound[43053:0] info: pending msg;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0 ;; flags: cd ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; QUESTION SECTION: b.jp. IN A ;; ANSWER SECTION: ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: ; EDNS: version: 0; flags: do ; udp: 4096 ;; MSG SIZE rcvd: 33 [0] unbound[43053:0] debug: pending to 1.1.1.1 port 53 [0] unbound[43053:0] info: pending msg;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0 ;; flags: cd ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; QUESTION SECTION: a.jp. IN A ;; ANSWER SECTION: ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: ; EDNS: version: 0; flags: do ; udp: 4096 ;; MSG SIZE rcvd: 33 [0] unbound[43053:0] debug: pending to 1.1.1.1 port 53 [0] unbound[43053:0] info: pending msg;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0 ;; flags: ; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; QUESTION SECTION: test.jp. IN A ;; ANSWER SECTION: ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: ; EDNS: version: 0; flags: do ; udp: 4096 ;; MSG SIZE rcvd: 36
設定が深度1の設定が2なので2件の外部名問い合わせと内部名のアドレス(1.1.1.1)に問い合わせているのが確認できる。