Kamailio нужно заблокировать 200 OK из ОТМЕНЕННЫХ веток, как?

У меня есть прокси Kamailio 4.0.4 (K) с регистратором и tm. Для некоторых AOR существует несколько клиентов, и все они автоматически принимают определенные INVITE, которые вызывают состояние гонки и имеют 200 OK из нескольких ветвей, отправляемых вызываемому.

Сценарий: - A отправляет приглашение B

  • K находит 2 контакта в uloc для B, назовем их B1 и B2.
  • INVITE разветвляется и отправляется на B1 и B2. Примечание. B1 имеет задержку канала 100 мс, а задержка B2 — 150 мс.

  • И B1, и B2 автоматически принимают с 200 OK сразу же, как они его получают.

  • Через 200 мс после ветвления INVITE K получает 200 OK от B1 и передает его A

  • K также ОТМЕНЯЕТ ПРИГЛАШЕНИЕ на B2
  • A на самом деле является локальной AS, которая мгновенно отправляет ACK 200 OK обратно B1.

  • Теперь проблема в том, что B2 уже отправил 200 OK 50 мс назад и не получит CANCEL еще 150 мс.

  • Таким образом, 200 OK от B2 приходит к K, но вызов уже установлен между A и B1.

  • Что происходит, так это то, что 200 OK передается на A, который в этот момент совершенно запутался, потому что, если честно, это не очень хорошая AS.

Теперь к самому вопросу: как сделать так, чтобы лишние 200 OK не попали в A?

Я вижу несколько вариантов того, как это должно работать:

  • Бросьте 200 ОК, просто выбросьте его. B2 не должен повторно отправлять его, потому что вскоре появится сообщение CANCEL.
  • ACK + BYE 200 OK изнутри Kamailio, но это приведет к тому, что медиа-сессия будет запущена и немедленно прервана B2.

Я даже не могу найти RFC, охватывающий это состояние гонки.


person Jukka Vaisanen    schedule 23.10.2013    source источник


Ответы (1)


IIRC, согласно rfc, ответы 200ok должны всегда пересылаться, поскольку вызывающий абонент выбирает один и отправляет ACK + BYE для другого.

Простое решение с kamailio — сбросить любые 200ok, как только вы их получите. Вызываемый абонент может не прекратить повторную отправку, даже когда придет CANCEL, будет ждать ACK и, в конце концов, BYE.

Модуль TM всегда будет пересылать 200ok согласно rfc. Если вы хотите закинуть kamailio.cfg, возможное решение:

  • используйте блок answer_route { ... }, чтобы перехватить 200ok для приглашения
  • используйте htable для хранения при получении первых 200ok (ключ может быть call-id)
  • используйте cfgutils, чтобы получить блокировки, которые защитят от гонок для доступа/обновления htable
  • логика обработки: если это 200ok для INVITE, блокировка для htable, проверьте, есть ли ключ для этого callid. Если да, разблокируйте и сбросьте. Если нет, добавьте элемент с call-id в качестве ключа, разблокируйте и дайте ответ продолжаться
person miconda    schedule 31.10.2013