要約
- RFC 3581 は、要求が実際に来た IP アドレスと UDP ポートへ応答を返すよう、空の
rportでクライアントが求める仕組みである。成立したのは当該 transaction の戻り道であって、将来の着信経路ではない。 - 観測 tuple、NAT mapping、flow、registration、dialog、利用者の結果は寿命も権限者も異なる。一度の応答成功を「到達可能」にまとめると、どの約束が切れたのか再現できなくなる。
端末の Via は 10.1.1.1:4540 と言い、受信 proxy のパケット記録は 192.0.2.1:9988 と言う。どちらかが単純に偽なのではない。前者は端末の内側、後者は NAT を越えた観測であり、用途と時間軸が違う。
RFC 3581 は、この差を一つの応答について解く。2003年8月に Standards Track として公開された文書は、最上位 Via に rport を追加した。クライアントは値なしで機能を求め、サーバーは観測した port を記録する。そして応答をその観測 tuple へ、要求を受けたのと同じサーバー側 socket から返す。
ここで証明されたのは狭い。いま届いた要求から得た新鮮な証拠を、いまの応答に使ったということだ。この狭さを守ると障害は説明できる。広げると、応答が届いたのに次の INVITE が消えるという現象を「矛盾」と誤認する。
混成ルールを線上の観測で補う
元の SIP/UDP 応答先は混成だった。IP アドレスは受信 packet の source から取り、port は Via の sent-by から取る。サーバーが単一の公開 socket で要求と応答を扱いやすい一方、NAT が address と source port の両方を変えると、公開 address と私的 port が組み合わされる。
空の rport は、クライアントが公開 port を自己申告しているのではないことを示す。受信者の観測を使ってほしいという flag である。サーバーは数値 rport と received を埋める。received は観測 address が sent-by と同じでも必要になる。
unreliable unicast で maddr がなく、両 parameter がある場合、応答先は received:rport となる。さらに応答元も要求を受けた同じ address と port でなければならない。symmetric NAT にとって remote 側 tuple も mapping の一部だからだ。
したがって、数値だけでは証拠が不足する。要求時の top Via、wire source、受信 interface、server instance、応答 source、branch、Call-ID、CSeq、送受信時刻を同じ receipt に閉じ込める必要がある。
Stateful と stateless は証拠の置き場所が違う
複数 interface や port で待ち受ける server は、どこで要求を受けたかを覚えなければならない。stateful proxy なら transaction 中の memory に置ける。stateless proxy は response まで memory を保持しないため、自分が追加する Via に宛先情報を符号化し、戻ってきたときに復元できる。
これは重要な設計判断である。stateless は provenance 不要という意味ではない。provenance が message と一緒に移動するという意味だ。論理的な service 名だけを記録しても、NAT が見た具体的 socket は復元できない。
cluster の一台が要求を受け、別の一台が後の要求を送ると、application 上は同じ service でも wire 上の peer は異なる。load balancer の健全性は、この transaction が同じ socket から戻った証拠を代替しない。
応答成功に有効期限は刻まれていない
RFC 3581 は NAT binding が transaction の間存続する必要があると書く。短い non-INVITE は当時一般的と考えられた UDP timeout 内に収まりやすい。INVITE は最終応答まで任意に長くなり得るため、provisional response の後も再送して mapping を更新するよう勧めた。
この運用は、tuple が lease ではないことを示す。最後の packet から時間がたつ、NAT が再起動する、policy が変わる、edge が failover する。それだけで経路はなくなる。SIP のユーザー名や登録 expiry が残っていても関係ない。
文書は RFC 3489 の binding lifetime discovery に触れつつ、その測定が不確実だと認める。RFC 3489 は RFC 5389 に、さらに RFC 5389 は RFC 8489 に置き換えられた。2003年の timeout 見積りを現在の事実として使ってはならない。保存すべきなのは測定値、最後の成功、再送条件と不確実性である。
Contact に書けば route になるわけではない
received と rport を見れば、端末は server から見た public tuple を知る。その値を Contact に入れて再登録すれば着信にも使える、と考えたくなる。RFC 3581 はこれを本来の response routing と区別し、UNSAF として脆弱性を列挙した。
mapping を保つための再登録は通常よりはるかに頻繁になり得る。symmetric NAT では、観測した server からの packet だけが通ることがある。cluster の別 node は同じ Contact を読めても着信を届けられない。REGISTER を registrar ではなく proxy が受けたなら、将来の要求はその proxy を通る必要があり、RFC 3327 Path がその事実を表す。
rport には有効 remote peer、期限、edge proxy、cluster affinity が入っていない。つまり観測値を address book に移すと、必要条件が不可視になる。
RFC 3581 が求めた長期解は、address を推測して公開するのではなく、client が自分の開始した connection/flow を着信にも使うよう明示できること、server cluster を扱えること、過剰 refresh を要求しないことだった。RFC 5626 SIP Outbound は registration binding と client-initiated flow を結び、複数 flow、keepalive、failure detection を定義した。RFC 6314 は NAT traversal practice として Outbound を推奨する。
それでも claim は分かれる。RFC 6223 は keepalive negotiation が connection reuse を定義しないとする。RFC 5923 は connection-oriented transport の reverse request を扱う。RFC 5627 の GRUU は UA instance に安定した routable URI を与える。pong は registration 選択ではなく、flow token は authorization ではなく、URI は通話結果ではない。
暗号化しても観測の寿命は延びない
source address と port は機微情報になり得るため、RFC 3581 は SIP over TLS による保護を挙げる。TLS は Via の改変を防ぎ得る。だが TCP/TLS では rport の response-routing 機能より、server が見た port の通知という意味が中心になる。
中間者が rport を除けば NAT 内の client は応答を失い得る。integrity はその妨害を防ぐが、public tuple の所有者を証明せず、mapping の将来を保証しない。IANA registry の登録も syntax の調整を示すだけで、実装、稼働、到達性の証拠ではない。
完全な record は、identity authentication、transaction tuple、proxy socket、Path/flow、registrar selection、dialog route、alert/answer/media/application outcome を別々に結ぶ。前段の成功を後段の代わりにしてはならない。
証拠の境界
本稿は carrier、PBX、SIP provider、UA、proxy、registrar、NAT 製品、cluster、利用者、call、incident、media result を特定しない。Standards Track は deployment share を示さない。
RFC 3261 は SIP transaction と Via の基礎、RFC 3327 は Path、RFC 3424 は UNSAF の評価枠を与える。RFC 3489 は歴史的参照に限定し、RFC 5389 と RFC 8489 が後続 STUN を示す。RFC 5626、RFC 6314、RFC 5923、RFC 6223、RFC 5627 はそれぞれ Outbound、practice、connection reuse、keepalive、安定 UA routing の境界を示す。IANA 登録は running proof ではない。
Heng Lu の Running-Code Primacy と Minimum Initial Specification は、公開した編集上の lens である。宣言ではなく走った経路を確認し、共通仕様を相互運用に必要な範囲に抑えるために使う。RFC 著者の意図や導入実績の証拠には使わない。
結論は小さいから強い。一つの応答が一つの時点で一つの port に届いた。その receipt を守る。同時に、それを次の要求の保証にはしない。
出典
- https://www.rfc-editor.org/rfc/rfc3581.html
- https://www.rfc-editor.org/info/rfc3581
- https://datatracker.ietf.org/doc/rfc3581/
- https://www.rfc-editor.org/rfc/rfc3261.html
- https://www.rfc-editor.org/rfc/rfc3327.html
- https://www.rfc-editor.org/rfc/rfc3424.html
- https://www.rfc-editor.org/rfc/rfc3489.html
- https://www.rfc-editor.org/rfc/rfc5389.html
- https://www.rfc-editor.org/rfc/rfc8489.html
- https://www.rfc-editor.org/rfc/rfc5626.html
- https://www.rfc-editor.org/rfc/rfc6314.html
- https://www.rfc-editor.org/rfc/rfc5923.html
- https://www.rfc-editor.org/rfc/rfc6223.html
- https://www.rfc-editor.org/rfc/rfc5627.html
- https://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml
- https://heng.lu/running-code-primary-the-patch-needed-to-preserve-the-internet-original-design/
- https://heng.lu/minimum-initial-specification-localized-future-decision-voluntary-adoption-internet-coordination-system/
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
