要約

  • RFC 3605 は、NAT によって RTP と RTCP の隣接ポート規則が崩れる場合に、RTCP のポートと任意のアドレスをメディア単位で明示する a=rtcp を定めた。
  • 属性を理解して受理したことは、ソケット、NAT マッピング、配送、妥当な RTCP パケット、受信レポート、利用者品質の証明ではない。メディアだけ届く部分故障を独立して観測する必要がある。

互換性試験は合格した。新しい SDP を古い端末に渡しても通話は拒否されず、音声も聞こえる。ところが制御トラフィックのカウンターは動かない。試験票が「通話成功」だけなら、この結果は合格になる。RFC 3605 を読むと、むしろそこが検査の出発点だと分かる。

2003 年 10 月に Standards Track として公開された RFC 3605 は、ポート変換後の座標を記述するための小さな拡張である。従来、RTP が偶数のメディアポートを使い、RTCP がその次の奇数ポートを使うという規則が広く利用された。SDP は媒体ごとに一つのポートを書き、制御ポートは計算で得られた。

NAT のポートマッピングは、その計算根拠を失わせる。内部では隣り合う二つの UDP ポートでも、外部では順序も偶奇も維持されないことがある。複数の外部アドレスを使う NAT なら、RTP と RTCP が別々のアドレスに現れることさえある。

RFC 3605 は a=rtcp:<port> と、必要ならネットワーク種別、アドレス種別、接続アドレスを記述できる属性を追加した。この属性はメディアレベルで用い、セッションレベルでは用いない。推測だった座標を明示的な輸送情報へ変えた点が成果である。

しかし、明示された座標は到達記録ではない。生成器が正しい値を書いたこと、パーサーが文法を受理したこと、Offer/Answer が成立したことは、それぞれ別のローカル事実にすぎない。相手プロセスがそのポートを bind したか、途中のフィルターが許可したか、マッピングが維持されたかはまだ分からない。

設計上の重要点は、媒体行そのものを拡張しなかったことにある。未知の媒体行形式なら、古いアプリケーションは媒体全体を拒否しかねない。未知の属性なら無視できる。その結果、古い実装は RTP を受け取りながら、指定された宛先へ RTCP を送らないことがある。互換性の成功と制御経路の失敗が同時に成立する。

この部分故障は、利用者の感覚だけでは見つけにくい。短い通話で音が聞こえれば、メディア経路は機能しているように見える。だが受信品質のフィードバックや同期情報が欠け、長いセッションや劣化時に必要な観測が残らない可能性がある。RTP の着信数を RTCP の健全性へ流用してはいけない。

外部座標の発見にも範囲がある。RFC は STUN を使う四段階を示す。RTP と RTCP の二つの UDP ポートを割り当て、それぞれからサーバーへ送信し、サーバーが見た送信元アドレスとポートを応答で返す。ホストは二つの外部座標を学習できる。

ただし同じ文書は、この手順が「STUN サーバー向けと最終 SDP ピア向けで NAT が同じ変換を使う」ことを仮定すると明記する。すべての NAT にその性質がある保証はない。観測相手が違えばマッピングが違い、時間が経てば状態が消えるかもしれない。

したがって STUN 応答は、観測者と時刻を伴う証拠である。外部 tuple だけを設定表へコピーすると、真だった条件を失う。内部 socket、観測サーバー、外部 tuple、時刻、インターフェース、想定ピア、最初の利用までの時間を一緒に残して初めて、後から適用範囲を検証できる。

送信と受信も別々に証明する。アプリケーションの送信カウンターは、OS にデータを渡したことを示すにとどまる。送信側インターフェースのキャプチャ、受信側エッジのキャプチャ、受信プロセスの RTCP 検証は、それぞれ異なる境界を閉じる。どこにも単独でエンドツーエンドの成功を名乗る権限はない。

妥当な受信レポートにも限界がある。RFC 3550 の RTCP は、受信品質のフィードバック、参加者の識別、同期などを担う。レポートには報告元、対象となる同期送信元、統計期間がある。それだけで人間の本人性、両方向の完全な観測、良好な体感品質、業務目的の達成まで証明するわけではない。

レポートがない場合は、さらに慎重でなければならない。未知属性の無視、誤った隣接ポート、別の多重化モード、期限切れの NAT、フィルター、レポート間隔、送信元状態の不足、収集基盤の故障が同じゼロを作り得る。データベースの空欄を「損失ゼロ」と読むのは、観測不能を好成績へ変換する誤りである。

後続仕様は選択肢を増やした。RFC 5761 は RTP と RTCP を一つのポートで多重化する交渉を定める。RFC 8859 は SDP 多重化の分析で rtcp を TRANSPORT 属性として扱い、IANA の SDP Parameters 登録も媒体レベルの属性として掲載を続けている。履歴を判定するには、実際に選ばれたモードが必要だ。

RFC 5389 が STUN を万能な NAT 通過策ではなく一つの道具として位置づけたことも、運用に効く。道具が返すのは、その道具が観測した事実である。発見は予約ではない。SDP は配送証明ではない。パケット到着は分析への取り込みではない。小さな仕組みに大きな権威を後付けしてはならない。

信号の完全性は、別の問いを閉じる。RFC 3605 は、SDP を改変できる者が RTCP 部分を別宛先へ向けられると指摘する。完全性保護が成功すれば、宣言が途中で変えられていないことを強く言える。だが正真正銘の宣言でも、閉じたポートや期限切れマッピングを指すことはある。

必要なのは証拠の状態機械である。元 SDP とハッシュ、パーサー結果、交渉結果、別ポートまたは多重化の選択、socket bind、NAT 観測、通知 tuple、完全性検証、最初の送信、遠端到着、妥当な RTCP、最初のレポート、対象期間、分析への取り込み、判断と実行を別々に記録する。

この分離があると、部分故障を正しく残せる。音声が届いたという事実を消す必要はない。同時に、制御レポートが確認できなかったという事実も隠さずに済む。成功か失敗かの二択より、どこまで証明できたかの方が、修復と比較に役立つ。

RFC 3605 は、NAT が壊したポート推論を明示的な座標で置き換えた。仕様はそこで役割を果たしている。その座標を実際の経路へ変えるのは実装であり、経路が働いたと証明するのは運用である。未知属性を無視して音声が残ったなら、それは完全成功ではなく、証拠を分けて扱うべき部分成功だ。