Linux
CentOS

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

More than 3 years have passed since last update.

/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秒

となる。

以下、nameserverに存在しないIPアドレスを記載し、

実際にタイムアウトするまでの時間を計測した結果。

試したコマンドは、routeコマンドを使用(内部で名前解決の処理があるので)

[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 ~]#

以下、routeコマンドをstraceで見た結果の、名前解決部分の抜粋。

pollの部分がDNSに問い合わせをして、結果を待っている箇所。

このpollに渡している引数を見ると、

何秒タイムアウト秒を待つように渡しているのかが分かる。


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)