同じドメインに A レコードが複数あるときのクライアントの挙動 (Chrome, Safari, curl)
おことわり: TCP/IP スタックの設定値などを深追いしておらず、「こう動いたが、根拠は調べていない」というレベルのものです。
いきなりまとめ
- Google Chrome (Windows 10, macOS Mojave), curl (WSL2 Ubuntu, macOS Mojave) は、一定間隔 (21~75秒) で順番に接続を試行する
- Safari (macOS Mojave) は、 0.25 秒間隔で同時に接続を試行する
前提条件
同一ドメインに複数の A レコードを設定する。なお、 IP アドレスは RFC5737 で規定されている仕様書やドキュメント向けの IPv4 アドレスであり、接続はできない。
$ dig roundrobin.nyamikan.net A ; <<>> DiG 9.16.1-Ubuntu <<>> roundrobin.nyamikan.net A ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49795 ;; flags: qr rd ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;roundrobin.nyamikan.net. IN A ;; ANSWER SECTION: roundrobin.nyamikan.net. 0 IN A 203.0.113.1 roundrobin.nyamikan.net. 0 IN A 203.0.113.3 roundrobin.nyamikan.net. 0 IN A 203.0.113.4 roundrobin.nyamikan.net. 0 IN A 203.0.113.2
確認方法
HTTP アクセスを試み、 Wireshark でパケットキャプチャして挙動を観測する。
確認結果
OS | ツール | 挙動 |
---|---|---|
Windows 10 バージョン 20H2 OS ビルド 19042.630 |
Google Chrome 87.0.4280.66 アドレスバー入力 |
約 21 秒間隔で順番に接続試行 その後 ERR_CONNECTION_TIMED_OUT 表示 さらに自動的にリトライ |
Windows 10 バージョン 20H2 OS ビルド 19042.630 |
Google Chrome 87.0.4280.66 Fetch API |
約 21 秒間隔で順番に接続試行 その後エラー |
Ubuntu 20.04.1 LTS Windows Subsystem for Linux 2 |
curl | 約 32 秒間隔で順番に接続試行 その後エラー |
macOS Mojave (バージョン 10.14.6) |
Google Chrome 86.0.4240.198 アドレスバー入力 |
約 75 秒間隔で順番に接続試行 4 分経過時点で ERR_CONNECTION_TIMED_OUT 表示 さらに自動的にリトライ |
macOS Mojave (バージョン 10.14.6) |
Google Chrome 86.0.4240.198 Fetch API |
約 75 秒間隔で順番に接続試行 4 分経過時点でエラー |
macOS Mojave (バージョン 10.14.6) |
Safari 13.1.2 (14609.3.5.1.5) アドレスバー入力 |
0.25 秒間隔で同時に接続試行 約 70 秒でエラー |
macOS Mojave (バージョン 10.14.6) |
Safari 13.1.2 (14609.3.5.1.5) Fetch API |
0.25 秒間隔で同時に接続試行 約 70 秒でエラー |
macOS Mojave (バージョン 10.14.6) |
curl | 約 75 秒間隔で順番に接続試行 その後エラー |
- いずれのツールも複数の IPv4 アドレスに接続試行していた。
- 順番に接続試行するものが多く、 また試行間隔が長いものが多い。
- macOS Safari が 0.25 秒間隔で同時に接続試行している点は興味深い。
不正確な推測、憶測
- Windows 10 の試行間隔 21 秒: Hotfix enables the configuration of the TCP maximum SYN retransmission amount in Windows 7 or Windows Server 2008 R2 を見る限り TCP/IP スタックによると思われる
- Ubuntu 20.04.1 LTS curl の試行間隔 32 秒: SYN を計 5 回しか送っておらず
net.ipv4.tcp_syn_retries = 6
と整合性が取れない。ツールのデフォルトタイムアウトは 300 秒 のようだが Ubuntu のビルドでは違うのだろうか? - macOS の 70~75 秒タイムアウト: すべてのツールで時間が概ね揃っており TCP/IP スタックのタイムアウトの可能性が高そう?
詳細な確認結果
Windows 10 (バージョン 20H2, OS ビルド 19042.630)
Google Chrome (87.0.4280.66) アドレスバー入力
Google Chrome (87.0.4280.66) Fetch API
Ubuntu 20.04.1 LTS, Windows Subsystem for Linux 2, curl
$ uname -a Linux <Machine Name> 4.19.128-microsoft-standard #1 SMP Tue Jun 23 12:58:10 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux $ curl --version curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3 Release-Date: 2020-01-08 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets $ curl http://roundrobin.nyamikan.net/ -v * Trying 203.0.113.1:80... * TCP_NODELAY set * connect to 203.0.113.1 port 80 failed: Connection timed out * Trying 203.0.113.3:80... * TCP_NODELAY set * connect to 203.0.113.3 port 80 failed: Connection timed out * Trying 203.0.113.2:80... * TCP_NODELAY set * connect to 203.0.113.2 port 80 failed: Connection timed out * Trying 203.0.113.4:80... * TCP_NODELAY set * connect to 203.0.113.4 port 80 failed: Connection timed out * Failed to connect to roundrobin.nyamikan.net port 80: Connection timed out * Closing connection 0 curl: (28) Failed to connect to roundrobin.nyamikan.net port 80: Connection timed out
macOS Mojave (バージョン 10.14.6)
Google Chrome (86.0.4240.198) アドレスバー入力
Google Chrome (86.0.4240.198) Fetch API
Safari (13.1.2 (14609.3.5.1.5)) アドレスバー入力
Safari (13.1.2 (14609.3.5.1.5)) Fetch API
curl
$ uname -a Darwin <Machine Name> 18.7.0 Darwin Kernel Version 18.7.0: Tue Aug 20 16:57:14 PDT 2019; root:xnu-4903.271.2~2/RELEASE_X86_64 x86_64 $ curl --version curl 7.54.0 (x86_64-apple-darwin18.0) libcurl/7.54.0 LibreSSL/2.6.5 zlib/1.2.11 nghttp2/1.24.1 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets HTTPS-proxy $ curl http://roundrobin.nyamikan.net/ -v * Trying 203.0.113.3... * TCP_NODELAY set * Connection failed * connect to 203.0.113.3 port 80 failed: Operation timed out * Trying 203.0.113.1... * TCP_NODELAY set * Connection failed * connect to 203.0.113.1 port 80 failed: Operation timed out * Trying 203.0.113.4... * TCP_NODELAY set * After 74518ms connect time, move on! * connect to 203.0.113.4 port 80 failed: Operation timed out * Trying 203.0.113.2... * TCP_NODELAY set * After 37258ms connect time, move on! * connect to 203.0.113.2 port 80 failed: Operation timed out * Failed to connect to roundrobin.nyamikan.net port 80: Operation timed out * Closing connection 0 curl: (7) Failed to connect to roundrobin.nyamikan.net port 80: Operation timed out