牧歌的なテンポで結果を表示するTracerouteをのどかに見つめてる時代は今終わった
既存のTracerouteの設計は、途中で応答が返らないルータがあると、頑なに順番を守ってタイムアウトまで待つ。そんな必要はない。送るだけ送って、結果をまとめて集計すれば瞬時に終わる。ただしこれには問題があって、経由するルータ数がわからないとき、多めにプローブ・パケットを送信する必要があるのでプローブ・パケットの無駄打ちが発生する。
それでも投機的にプローブ・パケットを送信する理由
- 障害対応のとき
数十パケットの無駄より、プローブに数分掛かったほうがよっぽど無駄。 - モニタリングのとき
経路を一定間隔でモニタリングするような用途では、ホップ数を記憶すれば無駄なプローブ・パケットを送信せずに済む。
言い訳は以上。
実際に作ってみた
GitHub: Python Quick Traceroute
インストール
インストール不要。モジュールとしてインポートするだけ。
使い方
権限
スーパーユーザー権限が必要。または、PythonバイナリにCAP_NET_RAWケイパビリティを設定する。
プログラミング・インタフェース
from traceroute import traceroute host = 'example.com' tr = traceroute() results = tr.probe(host, hop_limit=8, count=1, timeout=1.0, ident=None)
host
対象ホスト名の文字列またはIPアドレスの文字列
hop_limit
最大ホップ数。1から64までの整数。到達できる最小の値を設定するべき。
count
各ホップへのプローブ回数。1から4までの整数。
ident
並列実行のための識別子。長さ2のバイトアレイ。デフォルトまたはNoneの場合はPIDが使われる。
結果の構造
入れ子構造
[ [ first_probe, second_probe, ..., nth_probe ], # hop 1 [ first_probe, second_probe, ..., nth_probe ], # hop 2 ... [ first_probe, second_probe, ..., nth_probe ], # hop n ]
各結果アイテム: 応答を得られたとき
(from_addr, delay_sec, is_target)
アイテム例
('192.168.1.1', 0.0011992454528808594, False)
得られなかったとき
None
コード例
モジュールのメインブロックに簡単なtracerouteコードがあり、このようなコマンドとして実効できる。
$ sudo ./traceroute.py example.com traceroute to example.com (93.184.216.34), 32 hops max 1 192.168.1.1 1.146 ms 1.374 ms 1.616 ms 2 * * * 3 * * * 4 * * * 5 * * * 6 111.87.3.234 118.376 ms 118.503 ms 119.928 ms 7 62.115.180.213 123.618 ms 123.894 ms 125.392 ms 8 62.115.155.89 120.319 ms 121.756 ms 122.066 ms 9 152.195.85.133 121.776 ms 123.551 ms 123.544 ms 10 93.184.216.34 127.130 ms 127.199 ms 129.053 ms