0

レジストラと tm を実行している Kamailio 4.0.4 プロキシ (K) があります。一部の AOR には複数のクライアントがあり、すべてのクライアントが特定の INVITE を自動的に受け入れるため、競合状態が発生し、複数のブランチから 200 個の OK が呼び出し先に送信されます。

シナリオ: - A が B に招待を送信

  • K は、B の uloc で 2 つの連絡先を見つけました。それらを B1 と B2 と呼びましょう。
  • INVITE は分岐され、B1 と B2 に送信されます 注: B1 のリンク遅延は 100 ミリ秒、B2 の遅延は 150 ミリ秒です

  • B1 と B2 の両方が、200 OK を受け取るとすぐに自動承認します。

  • INVITE 分岐から 200ms 後、K は B1 から 200 OK を取得し、それを A に中継します。

  • K も B2 への INVITE をキャンセルします。
  • A は実際には 200 OK を即座に B1 に返すローカル AS です。

  • ここでの問題は、B2 が 50 ミリ秒前に 200 OK をすでに送信しており、さらに 150 ミリ秒の間 CANCEL を受信しないことです。

  • したがって、B2 からの 200 OK が K に到達しますが、コールは A と B1 の間ですでにセットアップされています

  • 何が起こるかというと、200 OK が A に中継され、この時点で A は完全に混乱します。正直なところ、あまり良い AS ではないからです。

実際の質問ですが、余分な 200 OK が A に行かないようにするにはどうすればよいですか?

それがどのように機能するかのいくつかのオプションを見ることができます:

  • 200 OK を落として、捨てるだけです。B2 は、CANCEL がすぐにヒットするため、再送信しないでください。
  • ACK + BYE カマイリオ内部からの 200 OK ですが、これにより、メディア セッションが開始され、B2 によってすぐに破棄されます。

この競合状態をカバーする RFC を見つけることさえできません..

4

1 に答える 1

1

IIRC の rfc によると、200ok 応答は常に転送する必要があり、一方を選択して他方に対して ACK+BYE を送信するかどうかは発信者が決定します。

kamailio を使用した簡単な解決策は、200ok を取得したらドロップすることです。呼び出し先は、CANCEL が到着しても再送信を停止せず、ACK を待ち、最終的に BYE を待つ場合があります。

TM モジュールは、rfc に従って常に 200ok を転送します。kamailio.cfg をドロップする場合の解決策:

  • reply_route { ... } ブロックを使用して、招待のために 200ok をインターセプトします
  • 最初の 200ok が受信されたときに格納するために htable を使用します (キーは call-id である可能性があります)。
  • cfgutils を使用して、競合から保護するロックを取得し、htable にアクセス/更新します
  • 処理ロジック: INVITE の 200ok の場合、htable のロック、その callid のキーがあるかどうかを確認します。はいの場合は、ロックを解除してドロップします。そうでない場合は、call-id をキーとして項目を追加し、ロックを解除して応答を続けます
于 2013-10-31T13:45:28.807 に答える