2009年5月23日土曜日

RFC3261を読み解こう: 再送のまとめ

Timerについて前回まとめたので、今回は再送のロジックについてまとめます。再送の動作もRFC3261読んだだけでは全くイメージできませんからね。状態機械だけ見てイメージできる人がいるんでしょうか。うらやましい。

INVITEの再送動作(300~699応答の場合)

  • INVITEの再送はUDPでのみ行います。
  • INVITEを受信したUAは200ms以内に最終応答が返却できる保証がなければ100を返送しなければなりません(MUST)。普通そんな保証はないのでよほどの理由がない限り100を返送します。
  • INVITEを受信したUAはINVITEの再送を受信する度に直前の暫定応答を再送します。が、100は再送されません。なぜなら100はサーバトランザクションがProceeding状態のときに扱う暫定応答に含まれていないからです(RFC3261 17.2.1 Figure.2参照)。
  • INVITEを受信したUAはProceedingにいる間なら任意のタイミングで何度でも暫定応答を送信できます。
  • 暫定応答を受信したUAはINVITEEの再送を停止し、最終応答を待ちます。
  • 300~699の最終応答の再送はUDPでのみ行います。
  • 300~699の最終応答に対するACKは1つのINVITEトランザクションの中のものとして扱われます。
  • 300~699の最終応答を受信したUAはその度にACKを再送します。
  • ACKを受信したUAはConfirmedになり、再送されてくるACKを待ち受けて破棄します。
  • どのUAもTerminatedになったらトランザクションを直ちに解放します。
  • Terminatedになった後に受信した信号は全て新規のものとして扱います。

INVITEの再送動作(200応答の場合)

  • INVTEの最終応答が200の場合、UASは最終応答送信時に、UACは最終応答受信時にTerminatedに移行します。ただし、これだとINVITEがフォークされていた場合に後から来た応答に対応できないため、Timer LとTimer Mが新しく定義されています。がまだ正式な仕様になっていないため説明は割愛します。
  • 200は300~699と違い、UAS→UACのエンドエンドで流通するため、UASのみが生成できます(プロキシは200を生成してはいけません)。
  • 200は300~699と違い、トランザクションの外で再送されます。その再送のタイミングはTimer Gと同じなのですが、なぜか再送用のタイマや再送T.Oのタイマは定義されていません(RFC3261 13.3.1.4参照)。
  • UACのみがACKを生成でき、200を受信する度にACKを再送します。

非INVITEの動作

  • 非INVITEのサーバトランザクションもINVITEサーバトランザクションと同じような動作をしますが、非INVITEサーバトランザクションにはなぜかTryingステートがあります
  • 非INVITEサーバトランザクションはRFC3261上、暫定応答を送信してもいいことになっていますが、RFC4320(和訳)で色々な条件付きで禁止されています。この記事はRFC3261に関する説明と言うことで割愛します。
  • 非INVITEトランザクションでは200とそれ以外の応答とで動作の違いはありません。
  • 非INVITEクライアントトランザクションでは、暫定応答や最終応答を受信しても、リクエストの再送を継続します(UDPに限り)。
  • 最終応答の再送はリクエストの再送契機で行われます。だから暫定応答を受信してもリクエストの再送を止めないのです。

1 件のコメント:

  1. Timer L/Mについて。

    フォークする場合、プロキシーコアが複数の異なるトランザクションを生成するのではないでしょうか?
    従って、トランザクションとしては常に1つの最終応答しか受け取ることはないと思います。

    書籍等で「フォークした場合、複数の最終応答を受け取ることがある」というような記述を見て、頭がパニックになりました。
    ・CTは、UAだけでなく、プロキシにも存在するレイヤーであり、
    ・CTは、それぞれのトランザクションを表すオブジェクトでなく、個々のトランザクションを管理する層というオブジェクトである
    なので、1つのINVITEに対して、CTが複数の最終応答を受け取ることがある。

    よって、Timer L/Mは不要だと思っています。

    ご意見お待ちしております。

    返信削除