メインコンテンツへスキップ

超高速Tracerouteを実装した

NOTE
この記事は最終更新日から1年以上が経過しています。内容が古くなっている可能性があります。

牧歌的なテンポで結果を表示するTracerouteをのどかに見つめてる時代は今終わった
#

既存のTracerouteの設計は、途中で応答が返らないルータがあると、頑なに順番を守ってタイムアウトまで待つ。そんな必要はない。送るだけ送って、結果をまとめて集計すれば瞬時に終わる。ただしこれには問題があって、経由するルータ数がわからないとき、多めにプローブ・パケットを送信する必要があるのでプローブ・パケットの無駄打ちが発生する。

それでも投機的にプローブ・パケットを送信する理由
#

  1. 障害対応のとき
    数十パケットの無駄より、プローブに数分掛かったほうがよっぽど無駄。
  2. モニタリングのとき
    経路を一定間隔でモニタリングするような用途では、ホップ数を記憶すれば無駄なプローブ・パケットを送信せずに済む。

言い訳は以上。

実際に作ってみた
#

インストール
#

インストール不要。モジュールとしてインポートするだけ。

使い方
#

権限

スーパーユーザー権限が必要。または、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

関連記事

Tracerouteについて知っておくべきこと

Tracerouteの仕組みについて解説してるページは数あれど、障害箇所特定のノウハウはあまり見かけないので、今回は「Tracerouteは有用だけど、これを知らないと結果が読めないぞ」という話を。

WOL Configuration on Linux

Wake On LANの設定のメモ。netplanが入っているUbuntu前提だけど、ほかのディストリビューションでも参考になるかもしれない。