/etc/resolv.confとタイムアウト秒


<pre>

/etc/resolv.confに記述したnameserverに対して、
それぞれ何秒間、タイムアウトを待つのか、について。

環境はCentOS 5系、CentOS 6系で確認。

このタイムアウト秒は、
options timeout:n
options attempts:n
によって指定する。

デフォルトでは、
options timeout:5
options attempts:2
となっている。

1回目の問い合わせ時は、options timeout:nの秒数をセットして問い合わせる。
2回目の問い合わせ時は、1回目のタイムアウト秒を2倍した値を、登録してあるnameserverの数で割った値で問い合わせる。
3回目以降の問い合わせ時は、2回目の問い合わせ時の2倍の値を使う。

これを1セットとし、options attempts:nの回数分繰り返す。

※ここで言う1回目や2回目というのは、nameserverで記述した内容の、上から順に1番目、2番目、という意味。
※/etc/resolv.confが認識するnameserverは、現状3台まで。それ以上記述しても無視される。

options timeout:2のとき。

nameserverが3台、かつ全部タイムアウトする場合

1回目：2秒
2回目：2 * 2 / 3 = 1秒（小数点以下切捨て）
3回目：1 * 2 = 2秒

options timeout:6のとき。

1回目：6秒
2回目：6 * 2 / 3 = 4秒
3回目：4 * 2 = 8秒

options timeout:30のとき。
1回目：30秒
2回目：30 * 2 / 3 = 20秒
3回目：20 * 2 = 40秒


デフォルトの
options timeout:5
options attempts:2
の場合は、

1回目：5秒
2回目：5 * 2 / 3 = 3秒（小数点以下切捨て）
3回目：3 * 2 = 6秒

上記を2セットなので、
( 5 + 3 + 6 ) * 2 = 28秒

となる。

</pre>


以下、nameserverに存在しないIPアドレスを記載し、
実際にタイムアウトするまでの時間を計測した結果。
試したコマンドは、routeコマンドを使用（内部で名前解決の処理があるので）

<pre>

[root@localhost ~]#
[root@localhost ~]# cat /etc/resolv.conf
nameserver 192.168.0.1
nameserver 192.168.0.2
nameserver 192.168.0.3

[root@localhost ~]#
[root@localhost ~]# time route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.0.0    *               255.255.255.0   U     0      0        0 eth0
169.254.0.0     *               255.255.0.0     U     0      0        0 eth0
default         192.168.0.254  0.0.0.0         UG    0      0        0 eth0

real    0m28.004s
user    0m0.001s
sys     0m0.001s
[root@localhost ~]#
[root@localhost ~]#

</pre>

以下、routeコマンドをstraceで見た結果の、名前解決部分の抜粋。
pollの部分がDNSに問い合わせをして、結果を待っている箇所。
このpollに渡している引数を見ると、
何秒タイムアウト秒を待つように渡しているのかが分かる。

<pre>
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.0.1")}, 28) = 0
fcntl(4, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
poll([{fd=4, events=POLLOUT}], 1, 0)    = 1 ([{fd=4, revents=POLLOUT}])
sendto(4, "\22Q\1\0\0\1\0\0\0\0\0\0\003254\0010\003168\003192\7in-a"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
poll([{fd=4, events=POLLIN}], 1, 5000)  = 0 (Timeout)
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.0.2")}, 28) = 0
fcntl(5, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
poll([{fd=5, events=POLLOUT}], 1, 0)    = 1 ([{fd=5, revents=POLLOUT}])
sendto(5, "\22Q\1\0\0\1\0\0\0\0\0\0\003254\0010\003168\003192\7in-a"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
poll([{fd=5, events=POLLIN}], 1, 3000)  = 0 (Timeout)
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 6
connect(6, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.0.3")}, 28) = 0
fcntl(6, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(6, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
poll([{fd=6, events=POLLOUT}], 1, 0)    = 1 ([{fd=6, revents=POLLOUT}])
sendto(6, "\22Q\1\0\0\1\0\0\0\0\0\0\003254\0010\003168\003192\7in-a"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
poll([{fd=6, events=POLLIN}], 1, 6000)  = 0 (Timeout)
poll([{fd=4, events=POLLOUT}], 1, 0)    = 1 ([{fd=4, revents=POLLOUT}])
sendto(4, "\22Q\1\0\0\1\0\0\0\0\0\0\003254\0010\003168\003192\7in-a"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
poll([{fd=4, events=POLLIN}], 1, 5000)  = 0 (Timeout)
poll([{fd=5, events=POLLOUT}], 1, 0)    = 1 ([{fd=5, revents=POLLOUT}])
sendto(5, "\22Q\1\0\0\1\0\0\0\0\0\0\003254\0010\003168\003192\7in-a"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
poll([{fd=5, events=POLLIN}], 1, 3000)  = 0 (Timeout)
poll([{fd=6, events=POLLOUT}], 1, 0)    = 1 ([{fd=6, revents=POLLOUT}])
sendto(6, "\22Q\1\0\0\1\0\0\0\0\0\0\003254\0010\003168\003192\7in-a"..., 44, MSG_NOSIGNAL, NULL, 0) = 44
poll([{fd=6, events=POLLIN}], 1, 6000)  = 0 (Timeout)
close(4)                                = 0
close(5)                                = 0
close(6)
</pre>