要約
- SIP の登録処理と、登録した端末への到達可能性は同じではない。Outbound は端末自身が作った通信の関連付けを、後から届く要求にも利用する。
- 同じ利用者の同じ端末に複数の経路があっても、代理サーバーはそれらを同時に別々の呼び出し先として扱ってはならない。
430 Flow Failedは一つの経路の故障を示す。端末から最終応答を受け取った場合とは、次に許される処理が異なる。
成功応答の中に、もう一つ確認すべきものがあった
電話が登録要求を送り、サーバーが成功を返す。そこで設定作業を終えたくなる。しかし、2009 年 10 月の RFC 5626 は、成功応答に Require: outbound があるかを確認するよう求めた。単に登録が通ったことと、Outbound の規則に従って登録されたことを区別するためだ。
サーバーが拡張機能を使わなかった場合、端末は外部から到達できない Contact を登録してしまっている可能性がある。登録された文字列が存在することは、その文字列を使って電話に戻れる証拠ではない。
途中の第一ホップにも条件がある。登録サーバーだけが Outbound を理解していても、端末のすぐ先の代理が必要な処理をしなければ、戻り道は成立しない。規定の条件では、登録サーバーは 439 First Hop Lacks Outbound Support を返す。これは後で使っていた経路が壊れたことを示す 430 とは別の話である。
機能の名前を付けた成功と、必要な経路がそろった成功。その違いから、この仕組みの設計を読むことができる。
戻ってくる応答と、新しく届く要求
SIP の基本仕様である RFC 3261 は、2002 年に登録を位置サービスの対応付けとして説明していた。利用者の Address of Record、つまり AOR に、一つ以上の Contact を結び付ける。要求を受けた代理は、その情報から転送先を選ぶ。
ここで登録サーバーと代理は役割の名前であり、必ず別の機械である必要はない。また REGISTER は、それ自体で通話の dialog を作らない。
問題は、端末が Contact に書けるアドレスと、サーバーが実際に到達できる場所が一致しない環境だった。NAT やファイアウォールの内側から外へ接続することはできても、外から新しい接続を始められない場合がある。端末には、サーバーとして使う安定した名前や証明書がないこともある。
既存の接続で応答を返すだけなら、基本仕様にも規則があった。信頼性のあるトランスポートでは、要求が来た接続がまだ開いていれば、それで応答する。だが、後から来る INVITE は REGISTER に対する応答ではない。新しい要求をどの経路へ乗せるかという問題は残る。
Outbound は、端末が先に作った flow をそのために利用する。TCP なら一つの接続に相当する。UDP なら両端のアドレス、ポート、トランスポートで表す双方向の関連付けであり、TCP 接続ではない。方式の違いを保ったまま、既存の関連付けを戻り道として扱う。
登録の途中にあった代理を覚える
端末が直接登録サーバーへ接続しているとは限らない。エッジの代理を経由して登録する場合、登録サーバーには、次の要求もその代理を通る必要があると伝えなければならない。
2002 年 12 月の RFC 3327 が定義した Path は、登録の途中で通る代理の情報を集め、対応付けと一緒に保存する仕組みだった。ホーム側の代理は後の要求にその経路を入れて、端末へ向かわせる。
Path と Record-Route は用途が違う。REGISTER に Record-Route があっても、そこから新しい dialog の経路を作るわけではない。Path は将来の要求を登録済みの端末へ戻すための情報であり、個々の dialog の後続要求には別途適切な経路が必要になる。
Outbound の第一ホップ代理は、Path に flow を識別するトークンを含める。これにより「この代理を経由する」から「この代理が持つ、どの関連付けを使うか」へ情報が細かくなる。トークンは改変から守られ、対応する flow を特定できなければならない。仕様に載る暗号処理の例を、唯一の実装方法と読む必要はない。
経路情報の保護も飾りではない。Path に不正な代理を差し込まれると、その後の要求が攻撃者を経由するおそれがある。接続があることと、その利用者への要求を運んでよいことは、別々に確かめる必要がある。
二つの Contact を、二台と数えない
一つの flow が故障してから端末が気付くまでには時間がかかる。別のエッジへも flow を用意しておけば、その間に届く要求を別経路で届けられる可能性がある。
ただし、登録が二つになったからといって、電話が二台になったわけではない。RFC 5626 は、同じ AOR と instance-id を持つ Contact を、同時に複数、転送先の集合へ入れることを禁じた。同一利用者が別々の端末を持つことや、SIP のあらゆる分岐を禁止する規則ではない。同じ端末への代替経路を重複した相手として選ばないための規則だ。
その判断には、三つの区別が必要だった。AOR は登録対象の利用者側の住所、instance-id は一つのユーザーエージェントの継続した識別、reg-id はそのインスタンスが同時に登録する経路の区別に使う。
端末を再起動しても instance-id は変えない。reg-id も同じ並びを再使用し、以前の登録と意図的に一致させる。新しい flow の情報で古い対応付けを置き換えるためである。毎回新しい相手として追加してしまうと、使えない道が登録表に残り続ける。
Contact は不要にならない。要求の転送先を組み立てるために保存される。変わるのは、それだけを比較して「同じ登録か」を決めないことである。
端末より先に、代理が故障を知る
仕様の例では、二つのエッジを通して登録した後、一方のエッジが停止し、再起動する。端末が flow の喪失をまだ検知していないうちに、新しい着信が届く。
最初に選ばれたエッジには、古い flow がもうない。そこで 430 を返す。上流の代理は、同じ AOR と instance-id で、別の reg-id を持つ登録を使って要求をやり直す。例のもう一方のエッジは、届いた INVITE の dialog に必要な経路も残す。その後で端末が故障した登録を修復する。
これは規格中の仮想的な時系列であり、特定事業者の障害記録ではない。新しい着信の経路選択を説明しているのであって、既に成立しているあらゆる通話が無停止で移動できると保証するものでもない。
430 は、一つの flow が失われたという局所的な情報である。アカウントが消えた、端末が拒否した、音声が届かない、といった別の結論を一度に含ませてはならない。仕様上はエッジと転送側の代理の間で扱う応答で、端末に届くことは想定していない。
もう答えた相手を、別の道から呼び直さない
経路の選び直しには明確な終了条件がある。ある分岐から最終応答を受けた場合、408 と 430 を除き、同じ要求を同じ AOR と instance-id の別の転送先へ送ってはならない。既にそのインスタンスが応答したからだ。
障害で要求が届かなかったのなら、代替経路を試す理由がある。相手が答えたのに、その答えが期待と違ったから別経路を試すのは、同じ回復処理ではない。
冗長化はここで、単なる接続数の問題ではなくなる。経路を増やすことは、同じ端末に何度でも答えを求める権利を増やすことではない。別の機会に新しい呼を起こすことまで禁じる規則ではないが、今処理している要求の意味を守るためには、この狭い境界が必要だった。
生存確認にも、確認できないことがある
登録の更新が一時的なエラーになっても、保活に応答している接続を直ちに閉じる必要はない。一方、UDP の STUN 応答が返ってきても、そこに示された外側のアドレスとポートが変われば、元の flow は故障したものとして扱う。
応答を受け取った事実と、以前登録した関連付けが維持されている事実は違う。NAT が再起動した後など、その差が表面に出る。
2011 年の RFC 6223 は、隣接する SIP ノード間で保活を協議する keep パラメーターを定めた。送信方向ごとの取り決めであり、接続の逆向き利用そのものを定義しないと明記している。
2010 年の RFC 5923 にある TLS 接続の alias も、別の範囲を扱う。どちらからでも接続を開始できる隣接ノードが、認証した接続を逆向きの要求に再利用する方式だ。端末側からしか経路を開けない環境は Outbound の領分であり、二つの方式の前提を混同できない。
届ける道と、呼びたい端末の名前
通話転送では、利用者の代表アドレスだけでは足りない場合がある。その人の別の端末や留守番電話ではなく、いま通話している端末へ要求を届けたいからだ。
RFC 5627 の GRUU は、そのための、特定インスタンスへ到達する URI を提供する。ドメインの代理を経て登録済みの Contact に対応付けるのであり、エッジの flow トークンと同じものではない。名前が特定の端末を指すことと、その端末への現在の経路が生きていることは、やはり分けて考える。
2014 年の RFC 7118 は、この考え方をブラウザーの SIP 実装例でも示した。必要な Outbound 対応を要求し、受け入れられた場合、Contact にランダムな .invalid の名前を使うことができる。スクリプトからローカルの通信アドレスを知れなくても、要求は WebSocket の代理と既存の flow を通って戻る。任意の無効アドレスで通話できるという一般則ではなく、音声メディアの転送まで解決したという説明でもない。
IANA の SIP パラメーター登録簿 には、これらの応答コードとパラメーター、参照する仕様が残る。登録簿から分かるのは共通の名前であり、各製品の普及率や実装の正しさではない。二つの登録を一台の端末の道として扱えるかどうかは、実際の結び付けと転送処理にかかっている。
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
Strategic Circle 限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加
