Kamailio需要从CANCELed分支机构阻止200 OK,怎么样?

时间:2013-10-23 08:33:55

标签: sip sip-server kamailio

我有一个运行注册商和tm的Kamailio 4.0.4代理(K)。某些AOR有多个客户端,它们都会自动接受某些INVITE,这些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
  • A实际上是一个本地AS,它会立即向200确认回到B1

  • 现在的问题是,B2已经发送了200 OK 50ms,而且还没有接收到另外150ms的CANCEL

  • 所以来自B2的200 OK来到K但是已经在A和B1之间设置了呼叫

  • 发生的事情是,200 OK被转发给A,在这一点上完全混淆了,因为说实话并不是一个很好的AS。

现在对于实际问题,如何阻止额外的200 OK进入A?

我可以看到它应该如何运作的一些选项:

  • 放下200 OK,扔掉它。 B2不应重新发送,因为CANCEL很快就会发布
  • 从Kamailio内部确认200 OK,但这将导致媒体会话被B2提起并立即拆除

我甚至找不到覆盖这种竞争条件的RFC。

1 个答案:

答案 0 :(得分:1)

根据rfc的说法,IIRC必须始终转发200ok响应,这是调用者选择一个并为另一个发送ACK + BYE的决定。

使用kamailio的简单解决方案是在获得任何200k后放弃。即使CANCEL到达,被叫方也可能不会停止重新发送,等待ACK并最终等待BYE。

根据rfc,TM模块将始终转发200ok。如果你想放入kamailio.cfg,可能的解决方案是:

  • 使用reply_route {...}阻止拦截200ok进行邀请
  • 在收到第一个200ok时使用htable存储(密钥可以是call-id)
  • 使用cfgutils来获取防止比赛访问/更新htable的锁
  • 处理逻辑:如果它是INVOP的200ok,锁定htable,检查该callid是否有密钥。如果是,请解锁并放弃。如果没有,请添加一个带有call-id作为密钥的项目,解锁并让响应继续进行