OpenSIPS的无状态及有状态路由

您所在的位置:网站首页 tm模块 OpenSIPS的无状态及有状态路由

OpenSIPS的无状态及有状态路由

2024-01-16 10:10| 来源: 网络整理| 查看: 265

        从SIP消息路由的角度看,OpenSIPS既可以作为无状态代理,也可以作为有状态代理。区别仅仅是处理SIP信令的脚本中调用了什么函数而已。

        在有状态模式下,OpenSIPS在内存中记录了SIP事务的状态。事务是由一个SIP请求及与之相关的所有应答消息所组成的。因此,在有状态模式下,OpenSIPS知道应答消息是属于哪个请求的(它有记录,能匹配);它记得请求被送往何方、最后收到的应答是什么;还知道事务当前处理什么状态。

        在无状态模式下,OpenSIPS处理消息时,不会留存任何信息。当消息处理完毕并被转发之后,它立马忘记所有相关信息。因为没有事务状态信息,所以,OpenSIPS独立处理每条SIP请求或应答消息,它们之间没有任何关联。

        无状态处理所需要的资源较少,由于不需要做SIP消息匹配,所以性能较高。但是,无状态处理的能够胜任的功能却非常有限。

        很多特性只能在有状态模式下实现,因为它们依赖事务状态实现功能逻辑,比如说:

重传监测:监测事务的重传消息,需要事务的关联(知道这个消息已经处理过),而在无状态模式下,重传消息只能处理为新的消息。实现重传:根据事务信息OpenSIPS可以实现SIP消息的重传。超时:OpenSIPS可以为特定的事务指定一个等待时间(以处理最终应答)。如果超时,OpenSIPS会结束事务,并向上游返回一个408 timeout应答。TM模块提供了$T_fr_timeout    和$T_fr_inv_timeout两个变量,可用于控制超时时长。串行或并行分支处理:事务实现会存储每个分支的状态。如果没有这些信息,OpenSIPS将对此无能为力。那么,记录每个分支的消息状态,就成唯一选项了。注意:在无状态模式下,即使你建立新的branch,在消息发出之后,它也是会消失的。脚本路由:有几种路由脚本只能在有状态模式下工作。因为它们的实现依赖于事务所存储的信息。其中包括: branch route、failure route、onreply route,以及local route,它们的实现都依赖事务的上下文信息,因此只能用于有状态模式。

        无状态处理由OpenSIPS core和StateLess模块(SL)直接提供;而有状态处理则由Transaction模块(TM)提供。处理有状态SIP,需要在脚本中加载TM模块。下表是无状态和有状态对应的不同调用对照:

OperationStatelessStatefulSIP    forwardforward()t_relay()SIP    replyingsl_send_reply()t_reply()Create    transactionn/at_newtran()Match    transactionn/at_check_trans()

注意:可以按每个请求选择无状态或有状态模式。你可以决定每条请求使用哪种处理方式。

        在有状态模式下,事务的生命周期由创建、匹配和监测组成。可以在脚本中调用 t_newtran()直接创建事务,也可以调用事务相关的函数隐式创建事务(t_relay() 或t_reply())。

        OpenSIPS对SIP请求的处理始于无状态模式,也就是说,它不会主动创建事务,除非你的脚本中触发创建事务的动作。

        一旦建立事务,那么后面的SIP消息就可以做事务匹配,具体有:

原始请求的重传消息:一旦发现,自动结束脚本的执行对错误应答消息的ACK(INVITE 事务):如果事务匹配成功,不需要脚本干预,自动更新事务状态CANCEL请求(匹配INVITE事务)

        所有有状态函数在自执行实质动作前都要先做事务匹配。TM模块提供了t_check_trans()函数用于显式事务匹配。它只执行事务匹配,不做其它动作,匹配成功就退出脚本。如果要监测并消除重传消息,尽早地在你的脚本逻辑中调用t_check_tran()或t_newtran()。

        CANCEL请求是一个特殊的应用场景。根据RFC3261的定义,CANCEL请求必须路由到INVITE相同的目的地,并且与待取消的INVITE请求保持相同的Via和RURI。你不必关心事务层的实现细节,OpenSIPS已经实现了。一旦CANCEL与INVITE请求匹配,OpenSIPS会按保存的事务信息处理,其过程遵循RFC3261的定义。在脚本层面,你只需要调用t_relay(),OpenSIPS就会把其它事务事项办理妥帖。

if (is_method("CANCEL")) { #see if this CANCEL matches an INVITE,     #if not, simply drop it     if (!t_check_tran())      exit;     #if an INVITE transaction was matched,     #let TM to do the job for us     t_relay(); }

        至于应答消息的事务匹配,OpenSIPS会自动执行,你不需要在脚本层面做什么。所有接收到的应答消息,都会先做事务匹配。如果匹配失败,那就按无状态模式的规则处理并转发消息。

小贴士:如果脚本里没有调用无状态转发函数(forward()),那么OpenSIPS会把不匹配事务的应答消息丢弃,不会做无状态转发。这背后的设计逻辑很简单:没有无状态发送请求,哪来的无状态应答消息。

        在事务结束时,OpenSIPS 会自动删除内存里的记录。根据SIP协议,事务结束于收到最终应答或超时。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3