■ラウンドトリップ時間をpingのワンライナーで計測してみる。 公式は以下を使用する。パケットの往復時間。 スループット (Kbps) = ( TCP ウィンドウサイズ (Bytes) * 8(Bit)) / RTT (sec) ■以下を参考に公式に問題が無いか確認する。 下記の本文の通り、64Kbytesは64000bytesとして計算。 第2回 ネットワーク遅延と高速化 http://gihyo.jp/admin/serial/01/net_prac_tech/0002 $ for RTT in 1 5 10 15 20 50 100 200;do \ echo "$RTT" | awk '{printf "RTTが%3dmsのとき、帯域 ≒ "((64000)*8)/($1*1000)"Mbps\n",$1}'; \ done RTTが 1msのとき、帯域 ≒ 512Mbps RTTが 5msのとき、帯域 ≒ 102.4Mbps RTTが 10msのとき、帯域 ≒ 51.2Mbps RTTが 15msのとき、帯域 ≒ 34.1333Mbps RTTが 20msのとき、帯域 ≒ 25.6Mbps RTTが 50msのとき、帯域 ≒ 10.24Mbps RTTが100msのとき、帯域 ≒ 5.12Mbps RTTが200msのとき、帯域 ≒ 2.56Mbps ■pingはIPヘッダとICMPヘッダで構成され、 ICMPヘッダは8で、オプション無しのIPヘッダは20バイトという説明がmanマニュアルにある。 $ man ping | grep -A 1 "IP.*ICMP ヘッダ" (``pings'') は IP と ICMP ヘッダを持ち、それに “struct timeval” が続 き、そして、パケットの残りを埋めるために任意個の ``pad'' バイトがある。 $ man ping | grep -A 3 " *\-s packetsize" -s packetsize 何バイトのデータが送られるかを指定する。デフォルトは 56 で、 ICMP ヘッダの 8 バイトを加えて、 64 バイトの ICMP データになる。 スー パーユーザーだけがこのオプションを使用できる。 $ man ping | grep オプションなし オプションなしの IP ヘッダは 20 バイトである。 ICMP ECHO_REQUEST パケット ■ウインドウサイズは16bitなので65535が最大。 ※16ビットの値は「0を含めて」65536個 $ /sbin/ifconfig lo | awk '/MTU/ {print $4}' MTU:65536 ■TCPヘッダは20byte、IPヘッダも20byte、MTUサイズが1500byteだとすると、 フラグメントしないTCPウインドウサイズの理論的な最大値は以下となる。 64 (Kbytes) * 1024 (bytes) / MTU 1500 (bytes) - IPヘッダサイズ 20 (bytes) - TCPヘッダサイズ 20 (bytes) $ echo "$((64 * 1024 / (1500 - 20 - 20 )))" | awk '{print (1500-20-20)*$1}' 64240 $ for RTT in 1 5 10 15 20 50 100 200;do \ echo "$RTT" | awk '{printf "RTTが%3dmsのとき、帯域 ≒ "((64240)*8)/($1*1000)"Mbps\n",$1}'; \ done RTTが 1msのとき、帯域 ≒ 513.92Mbps RTTが 5msのとき、帯域 ≒ 102.784Mbps RTTが 10msのとき、帯域 ≒ 51.392Mbps RTTが 15msのとき、帯域 ≒ 34.2613Mbps RTTが 20msのとき、帯域 ≒ 25.696Mbps RTTが 50msのとき、帯域 ≒ 10.2784Mbps RTTが100msのとき、帯域 ≒ 5.1392Mbps RTTが200msのとき、帯域 ≒ 2.5696Mbps ■これから確認するツールはping。 ICMPなので、TCPヘッダではなくICMPヘッダの8バイトの方を採用する。 なお、0.1ms,0.2msの値も追加。 $ for RTT in 0.1 0.2 1 5 10 15 20 50 100 200;do \ echo "$RTT" | awk '{printf "RTTが%4.1fmsのとき、帯域 ≒ "((65535-20-8)*8)/($1*1000)"Mbps\n",$1}'; \ done RTTが 0.1msのとき、帯域 ≒ 5240.56Mbps RTTが 0.2msのとき、帯域 ≒ 2620.28Mbps RTTが 1.0msのとき、帯域 ≒ 524.056Mbps RTTが 5.0msのとき、帯域 ≒ 104.811Mbps RTTが10.0msのとき、帯域 ≒ 52.4056Mbps RTTが15.0msのとき、帯域 ≒ 34.9371Mbps RTTが20.0msのとき、帯域 ≒ 26.2028Mbps RTTが50.0msのとき、帯域 ≒ 10.4811Mbps RTTが100.0msのとき、帯域 ≒ 5.24056Mbps RTTが200.0msのとき、帯域 ≒ 2.62028Mbps ■実際のコマンド実行結果を確認してみる。 $ TCPWINDOW_SIZE=65535; \ COUNT=10; \ TARGETIP=127.0.0.1; \ ping -c $COUNT -s $(($TCPWINDOW_SIZE-20-8)) $TARGETIP | \ awk -F\/ '{print}/^rtt/ {print "帯域 ≒ "(('${TCPWINDOW_SIZE}'-20-8)*8)/($5*1000)"Mbps"}' PING 127.0.0.1 (127.0.0.1) 65507(65535) bytes of data. 65515 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.137 ms 65515 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.113 ms 65515 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.207 ms 65515 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.162 ms 65515 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.161 ms 65515 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.180 ms 65515 bytes from 127.0.0.1: icmp_seq=7 ttl=64 time=0.167 ms 65515 bytes from 127.0.0.1: icmp_seq=8 ttl=64 time=0.156 ms 65515 bytes from 127.0.0.1: icmp_seq=9 ttl=64 time=0.121 ms 65515 bytes from 127.0.0.1: icmp_seq=10 ttl=64 time=0.164 ms --- 127.0.0.1 ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time 8998ms rtt min/avg/max/mdev = 0.113/0.156/0.207/0.030 ms 帯域 ≒ 3359.33Mbps $ echo "0.156" | awk '{printf "RTTが%4.3fms のとき、帯域 ≒ "((65535-20-8)*8)/($1*1000)"Mbps\n",$1}' RTTが0.156msのとき、帯域 ≒ 3359.33Mbps ■MTU、パケットサイズを超えるフラグメントを許可しない環境でも行えるテストは以下。 $ /sbin/ifconfig eth0 | awk '/MTU/ {print $5}' MTU:1500 $ TCPWINDOW_SIZE=1499; \ COUNT=10; \ TARGETIP=172.31.31.252; \ ping -c $COUNT -s $(($TCPWINDOW_SIZE-20-8)) $TARGETIP | \ awk -F\/ '{print}/^rtt/ {print "帯域 ≒ "(('${TCPWINDOW_SIZE}'-20-8)*8)/($5*1000)"Mbps"}' PING 172.31.31.252 (172.31.31.252) 1471(1499) bytes of data. 1479 bytes from 172.31.31.252: icmp_seq=1 ttl=254 time=1.54 ms 1479 bytes from 172.31.31.252: icmp_seq=2 ttl=254 time=1.34 ms 1479 bytes from 172.31.31.252: icmp_seq=3 ttl=254 time=1.31 ms 1479 bytes from 172.31.31.252: icmp_seq=4 ttl=254 time=1.28 ms 1479 bytes from 172.31.31.252: icmp_seq=5 ttl=254 time=1.24 ms 1479 bytes from 172.31.31.252: icmp_seq=6 ttl=254 time=1.26 ms 1479 bytes from 172.31.31.252: icmp_seq=7 ttl=254 time=1.32 ms 1479 bytes from 172.31.31.252: icmp_seq=8 ttl=254 time=1.27 ms 1479 bytes from 172.31.31.252: icmp_seq=9 ttl=254 time=1.27 ms 1479 bytes from 172.31.31.252: icmp_seq=10 ttl=254 time=1.34 ms --- 172.31.31.252 ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time 9013ms rtt min/avg/max/mdev = 1.246/1.321/1.546/0.084 ms 帯域 ≒ 8.9084Mbps $ echo "1.321" | awk '{printf "RTTが%4.3fms のとき、帯域 ≒ "((1499-20-8)*8)/($1*1000)"Mbps\n",$1}' RTTが1.321ms のとき、帯域 ≒ 8.9084Mbps ■フラグメントしても問題ない環境でのテストは以下。 $ TCPWINDOW_SIZE=65535; \ COUNT=10; \ TARGETIP=172.31.31.252; \ ping -c $COUNT -s $(($TCPWINDOW_SIZE-20-8)) $TARGETIP | \ awk -F\/ '{print}/^rtt/ {print "帯域 ≒ "(('${TCPWINDOW_SIZE}'-20-8)*8)/($5*1000)"Mbps"}' PING 172.31.31.252 (172.31.31.252) 65507(65535) bytes of data. 65515 bytes from 172.31.31.252: icmp_seq=1 ttl=254 time=19.9 ms 65515 bytes from 172.31.31.252: icmp_seq=2 ttl=254 time=19.8 ms 65515 bytes from 172.31.31.252: icmp_seq=3 ttl=254 time=19.8 ms 65515 bytes from 172.31.31.252: icmp_seq=4 ttl=254 time=20.1 ms 65515 bytes from 172.31.31.252: icmp_seq=5 ttl=254 time=19.8 ms 65515 bytes from 172.31.31.252: icmp_seq=6 ttl=254 time=19.7 ms 65515 bytes from 172.31.31.252: icmp_seq=7 ttl=254 time=19.8 ms 65515 bytes from 172.31.31.252: icmp_seq=8 ttl=254 time=19.8 ms 65515 bytes from 172.31.31.252: icmp_seq=9 ttl=254 time=19.7 ms 65515 bytes from 172.31.31.252: icmp_seq=10 ttl=254 time=19.8 ms --- 172.31.31.252 ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time 9010ms rtt min/avg/max/mdev = 19.781/19.870/20.120/0.192 ms 帯域 ≒ 26.3742Mbps $ echo "19.870" | awk '{printf "RTTが%4.3fms のとき、帯域 ≒ "((65535-20-8)*8)/($1*1000)"Mbps\n",$1}' RTTが19.870ms のとき、帯域 ≒ 26.3742Mbps ■pingの経路を記録するには、更に40byte必要となる。 ただし、オプションをセットしても無視される可能性もある。 $ man ping | grep -A2 "\-R" -R 経路を記録。 ECHO_REQUEST パケットに RECORD_ROUTE オプションを設定し、返ってきたパケットの経路バッファ (route buffer) を表示する。 IP ヘッダは 9 つの経路分の大きさしかないことに注意せよ。 また、多くのホストはこのオプションを無視する か、破棄してしまう。 $ TCPWINDOW_SIZE=65535; \ COUNT=10; \ TARGETIP=172.31.31.252; \ ping -R -c $COUNT -s $(($TCPWINDOW_SIZE-20-8-40)) $TARGETIP | \ awk -F\/ '{print}/^rtt/ {print "帯域 ≒ "(('${TCPWINDOW_SIZE}'-20-8)*8)/($5*1000)"Mbps"}' PING 172.31.31.252 (172.31.31.252) 65467(65535) bytes of data. 65475 bytes from 172.31.31.252: icmp_seq=1 ttl=254 time=20.3 ms 65475 bytes from 172.31.31.252: icmp_seq=2 ttl=254 time=20.0 ms 65475 bytes from 172.31.31.252: icmp_seq=3 ttl=254 time=20.1 ms 65475 bytes from 172.31.31.252: icmp_seq=4 ttl=254 time=20.2 ms 65475 bytes from 172.31.31.252: icmp_seq=5 ttl=254 time=20.0 ms 65475 bytes from 172.31.31.252: icmp_seq=6 ttl=254 time=20.0 ms 65475 bytes from 172.31.31.252: icmp_seq=7 ttl=254 time=20.0 ms 65475 bytes from 172.31.31.252: icmp_seq=8 ttl=254 time=20.1 ms 65475 bytes from 172.31.31.252: icmp_seq=9 ttl=254 time=20.1 ms 65475 bytes from 172.31.31.252: icmp_seq=10 ttl=254 time=20.1 ms --- 172.31.31.252 ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time 9012ms rtt min/avg/max/mdev = 20.042/20.127/20.323/0.187 ms 帯域 ≒ 26.0375Mbps