要約

  • 対象コードの is_success は、入力リストの最後のホップに、真と評価される RTT を持つエラー扱いではないパケットがあるかを調べる。応答元と宛先アドレスの一致は要求しない。
  • Sagan は destination_ip_responded と last_hop_responded を別々に提供している。区別が隠されているわけではなく、特定の利用製品が混同していることも今回の調査では確認していない。
  • last_median_rtt は末尾が無応答でも、先行する応答ホップの値を保持し得る。既存の21テストと5つの合成例はネットワークを使わないローカル確認で通過したが、現場の障害やサービス可用性を測ったものではない。

宛先からの応答はない。しかし、is_success は true になる。

Sagan に与えた合成入力の一つでは、最後のホップにルーターからの10ミリ秒の応答を置いた。そのアドレスは指定した宛先とは異なる。生成された結果オブジェクトで、last_hop_responded と is_success は true、destination_ip_responded は false だった。

実際のルーターへ測定用のパケットを送ったのではない。文書用のアドレスで作った入力を解釈し、条件が何を要求するかを確かめた。顧客の障害事例として読むべき結果ではない。

Sagan は RIPE NCC が提供する RIPE Atlas 測定結果の解析ライブラリである。形式の変更やエラーの例外処理をまとめ、利用者が同じ JSON 解釈を繰り返さずに済むようにする。それは有用な役割だ。今回固定したのは、2026-06-03 のコミット 45d01f754896ad648e5b306c4209153bab774af9 である。参照先は検査したソースを識別するのであって、利用者のインストール済みバージョンを一覧にしたものではない。プロジェクトの目的。

最後のホップへの三つの質問

関連するメソッドは、渡されたホップリストの末尾を対象に、別々の質問をする。

set_destination_ip_responded は、パケットの応答元が結果の宛先アドレスに一致するかを調べる。set_last_hop_responded は、Python が真として評価する RTT のあるパケットを探す。set_is_success は、そのような RTT があり、パケットがエラーとして扱われていないかを調べる。三つ目の判定に宛先とのアドレス比較は加わらない。traceroute の判定処理。

普通の宛先応答なら、三条件すべてを満たす場合がある。そのような入力ばかり見ていると、三つのフラグを同義語として扱いたくなる。だが、別のアドレスからのエラーではない応答なら、末尾ホップの応答と成功は成立しても、宛先応答は成立しない。

コードがルーターを宛先と取り違えたわけではない。アドレス一致を要求する条件と、要求しない条件を分けている。問題になるのは、後者の結果を受け取った人が前者の意味を付け足す場合である。

逆の組み合わせも起こる。宛先アドレスからの10ミリ秒の応答に、合成入力で p エラーを付けると、宛先応答と末尾ホップ応答は true、is_success は false になる。末尾エラーの一覧には「Port unreachable」が入った。エラー状態は、記録された応答元や数値を消すものではない。基本クラスのエラー処理。

したがって、アドレスが応答したことと、パケットがエラーではないことは、どちらの方向にも分かれる。どちらも、利用者が必要とするアプリケーションの取引が完了した証明ではない。ここで行われるのは、入力にあるアドレスの比較とパケットの分類であり、送信元の認証や業務処理の実行ではない。

区別はすでに公開されている

この発見を、Sagan が宛先応答を調べる手段を欠いているという話にしてはいけない。専用の destination_ip_responded がある。型の文書も、末尾ホップの応答、成功、末尾エラーと並べて説明している。公開されたプロパティ。

これは重要な反証である。ライブラリはすべてを一つの解体できない判断に押し込めているわけではない。利用者が必要な問いを選べるように、別々の構成要素を渡している。既存のコード、文書、テストを読むことには実際の意味がある。

想定されるリスクは、その後の利用側にある。is_success だけを残し、列名を「宛先に到達」や「サービス利用可能」にするなら、判定の意味を置き換えてしまう。ただし、今回の調査は、そのような使い方をする特定の製品を確認していない。可能な作用機序を、確認済みの誤用や広がりとして語ることはできない。

親しみやすい名前はインターフェースを使いやすくする。しかし、名前だけで他のフラグが不要になるわけではない。三つが揃うときに目立たなかった差は、揃わないときこそ次の検査を決める材料になる。

末尾の無応答と10ミリ秒は両立する

RTT の選択規則は、終端のフラグとはさらに異なる。各 Hop は、保持したパケット RTT から中央値を計算する。結果の解析はホップリストを逆順にたどり、真として評価される最初のホップ中央値を last_median_rtt に置く。対応する応答元が宛先かどうかは、その選択条件に含まれない。

別の合成入力では、三つのホップを置いた。最初のルーターが5ミリ秒、次のルーターが10ミリ秒で応答し、末尾には無応答を表すマーカーだけがある。宛先応答、末尾ホップ応答、成功の三フラグは false になったが、last_median_rtt は10ミリ秒だった。

これは「宛先は応答していないが宛先の遅延は10ミリ秒」と発表した結果ではない。三フラグは末尾ホップを調べ、数値は先行する応答ホップから選ばれた。後で「宛先までの遅延」と書けば、コードが要求しなかった到着点を報告側で追加することになる。

同じ10ミリ秒は、普通の宛先応答、別のルーターの応答、宛先のエラー応答にも現れた。大きさが同じでも、アドレスや終端状態は同じではない。平均や中央値を取り直せば、その意味の差まで解消されるわけではない。集計前に、どの観測を同じ対象の数値として扱うかを決める必要がある。

合成例のリストは通常の順序で作った。逆順の走査は入力リストに対する規則であり、物理的な転送経路を独立に復元する手続きではない。任意の並べ替え、壊れた形式、すべての異常な結果を調べたわけでもない。「最後」はアルゴリズムでの参照先を保つべきで、無条件に「宛先」と読み替えるべきではない。

また、結果オブジェクトを作れたことと、そのオブジェクト内の成功条件が成立したことも違う。五つの入力はいずれも解析でき、末尾が無応答の例もオブジェクトになった。結果が存在するという理由だけで、終端やサービスを成功と数えれば、別の問いを飛ばしてしまう。これらの合成入力から実利用の成功率を求めることはできない。

オブジェクトを減らしても入力は残る

parse_all_hops=False は、すべての Hop オブジェクトを作らない選択肢である。少数の派生プロパティだけを使う利用者にとって、不要な処理を避ける合理的な方法だ。文書では hops が最後の Hop だけになる場合を説明している。

三ホップで末尾が無応答の例にこの選択を適用すると、保持される Hop はインデックス3だけになった。しかし、派生した中央値は前の応答ホップからの10ミリ秒を保持する。完全な入力は raw_data に残る。元データを削除したという意味ではなく、便宜的なオブジェクト群と派生値が異なる範囲を見せているのである。

hops と中央値だけを出力する利用側では、その値を与えた解析済みオブジェクトが出力に含まれないかもしれない。後で説明する必要があるなら、原入力を保存するか、選ばれたホップの文脈を明示しておく必要がある。すべての Python オブジェクトを永久に保持するという話ではない。受取人が何を検査できるようにするかという選択だ。

同じ入力でも、利用者の選択によって保持されるオブジェクト群は違い得る。出力の比較には、その解析オプションも関係する。便宜的なリストにホップがないことと、入力にそのホップがなかったことを混同してはならない。

テストの範囲を広げて読まない

プロジェクトにある既存の traceroute テスト21件を、ローカルで実行した。基本クラス、互換性コード、traceroute クラスは固定コミットの原ソースをそのままメモリ内で読み込み、変更しなかった。21件はすべて通過した。続いて、非宛先の末尾応答、普通の宛先応答、先行 RTT を伴う末尾無応答、宛先のエラー応答、最小解析での末尾無応答という5つの合成入力も、予定した条件を満たした。ネットワーク操作は禁止し、その試みはなかった。既存の回帰テスト。

確認したのは、選択したクラスと入力例である。パッケージ全体のインストール、コントローラーによる受入れ、すべての配布版や生成側形式の適合性を認定したものではない。実際の測定で各状態がどれだけ起こるかも測っていない。顧客被害や実運用の障害件数をこの結果から算出することはできない。

既存テストは、応答の違いをプロジェクトが以前から扱っていることも示す。有用なライブラリを不注意だと決めつけるための検査ではない。限定された判定を、その判定が行っていない業務上の結論に広げないための検査である。

パケットの応答からサービスまでは別の証拠が要る

Atlas の一般的な結果文書も、アドレスの役割を分けている。上位の from は測定システムが付け、src はプローブに由来する。両者が違うことはある。traceroute のパケット内の from は、そのパケットの応答元として扱われる。上位のアドレス、応答パケットのアドレス、宛先は、似た名前だけで同じ識別情報になるわけではない。Atlas のアドレス区分。

宛先とのアドレス一致も、解析上の条件である。それだけで応答元を認証し、利用者が必要とするアプリケーションを試したことにはならない。調べていない仕事を一つの比較結果に任せれば、証拠ではなく期待を追加することになる。

RFC 792 は TTL が尽きた場合の ICMP Time Exceeded と、ゲートウェイが送信元へ通知し得る状況を説明する。転送装置からの応答は有益だが、宛先アプリケーションで取引が完了した証拠ではない。逆に、無応答だけで送信経路が壊れたと特定することもできない。応答が生じたか、戻ったか、どう処理されたかは別に調べる対象になる。ICMP の仕様。

RFC 2330 は、単独の観測、観測を集めた標本、標本からの統計を分ける。Type-P の考え方は測定する通信の種類を明示するためのものだ。一つのホップの RTT、ある traceroute の分類、一定期間のサービス可用性は、同じ報告書に載せられるとしても同じ測定ではない。性能指標の枠組み。

数値を使うことをやめる必要はない。どのホップから選び、どの終端条件と並べたかを数値とともに残せばよい。より大きなサービスの主張には、そのアプリケーション、観測期間、観測地点に適した追加の証拠が要る。プロパティは判定結果を簡潔に示せても、証拠の範囲を広げることはできない。

資料