您当前的位置是:  首页 > 资讯 > 文章精选 >
 首页 > 资讯 > 文章精选 >

OpenSIPS学习笔记-无状态模式下的呼叫确认方式和关闭record_routing()处理讨论

2021-01-11 10:06:01   作者:james.zhu    来源:Asterisk开源派   评论:0  点击:


  SIP协议的应用场景非常广泛,但是同时又非常灵活,SIP的呼叫场景同时需要集成和兼容不同场景,不同的应用。很多用户为了满足一个简单的用户需求,做一个配置实现了某一个用户的需求,但是这样的处理方式会在未来的实现中造成很多的难题。一个比较重要的原则是,在集成和兼容性的支持中,除了实现某些业务的需求,同时一定要尽量满足SIP协议规范。一些用户经常在这个问题上犯错误。单方面满足了用户的需求,但是处理流程却违反了SIP协议的规范,这样可能就会带来未来和其他用户兼容的难题。在实际实现中经常会遇到类似的问题。今天,笔者专门针对以上困惑,通过两个示例(无状态示例和关闭record_routing())来说明其细节。
  笔者在前面的文章中已经说明,opensips环境下的无状态模式基本上没有任何可支持的场景,一些用户为了实现某个需求或者节省系统资源,提高处理能力,就使用了无状态模式处理方式。但是,因为它不保存事务状态,所以不能对任何返回的响应做处理。如果要进行更多的SIP响应处理,必须切换到有状态模式进行更多处理。
  opensips学习笔记-关于stateless和stateful 模式讨论和retransmissions演示
  继续接历史文章的介绍,笔者这里通过使用无状态的前转函数来替换有状态的转发处理给大家演示为什么无状态模式下没有任何响应处理。
  在介绍无状态跟踪的示例之前,读者首先需要了解几个比较重要的功能和工具。
  首先是“P-Hint“的工具使用,在opensips中,运维人员可以使用“P-Hint”来对呼叫流程进行跟踪。可以在任何流程中打印自己的log来跟踪呼叫。通过插入必要的定义log,可以判断呼叫流程是否是按照自己的定义来进行。
  跟踪完整的dialog流程
  读者需要了解无状态模式和有状态模式的使用的函数。这里,测试环境从前面测试的有状态呼叫模式切换为一个无状态的模式环境中。如果使用无状态环境的话,用户需要修改配置文件的设置。在route[relay]中使用forward()替换t_relay()。
  route[relay] {
  if (is_method("INVITE")) {
  t_on_branch("per_branch_ops");
  t_on_reply("handle_nat");
  t_on_failure("missed_call");
  }
  #   t_relay();
  forward(); // 修改到了无状态模式,直接前转到目的地。
  exit;
  }
  因为需要跟踪无状态的响应消息传来流程,所以需要在onreply_route[]打印输出的跟踪log:
  onreply_route[handle_nat] {
  append_hf("P-hint: (3)reply through onreply_route[handle_nat]\r\n");
  xlog("incoming reply\n");
  }
  重新启动openisps,重新注册SIP账号,sip 账号呼叫另外一个SIP账号,这里,基于无状态模式的呼叫流程表面上和有状态的模式的没有什么不同。但是通过抓包工具可以看到,在onreply_route[]中没有任何的 append_hf()log。因为无状态模式的呼叫没有任何返回响应。通过这样的设置就可以确认其无状态模式的工作方式。
  笔者今天讨论的另外一个话题是关于opensips环境下关闭Record-Route的处理。Record-Route的概念和非常详解笔者在历史文档从多个层面做过详细说明,笔者可以参考以下文章,这里不再讨论起概念。
  前面链接的几篇文章非常详细说明了其重要性。这里,为了快速了解一点Record-Route的用途,笔者简单说明一下Record-Route的必要性:
  • 需要处理网络的地址转换的处理业务(NAT,拓扑远程,防火墙等)SBC业务的要求。
  • 呼叫计费CDR的作用
  • 媒体处理的需要
  • 管理和检测dialog流程的必要
  • 可能需要举例呼叫链接的所有hops(有的hop也可以忽略)
  今天,笔者通过opensips的示例来说明如何实现关闭Record-Route的处理。注意,在讨论Record-Route关闭之前,读者首先需要明确另外一个OpenSIPS中比较重要的一个变量概念-sequential requests(SR)。sequential requests(SR)是针对initinital request(SR)来说的。initinital request(SR)是一个比较乏的概念。简单来说,initinital request,To header中没有任何的tag参数。SR请求处理是基于每个record来进行处理的。因为SR是基于某个record处理的,相比IR处理,因为SR不会重新经过其他的路由逻辑,SR处理的速度更加快捷。
  如果通过opensips开启了Record-Route记录的话,SIP呼叫会通过opensips返回另外一端。如果关闭了Record-Route的话,SIP的呼叫会通过contact头直接呼叫到被呼叫方侧终端。为了测试关闭Record-Route的示例场景,我们需要关闭Record-Route()。
  ## record routing
  if (!is_method("REGISTER|MESSAGE"))
  ##  record_route();  关闭Record-Route
  if (!is_myself("$rd")) {
  append_hf("P-hint: outbound\r\n");
  route(relay);
  }
  重新启动opensips,重新注册SIP账号进行测试。通过呼叫流程的示例,抓包工具的检查,读者会发现关闭了Record-Route就看不到任何的BYE请求。当然,此流程中也没有可能看到其他的SR处理的消息。
  笔者通过无状态示例和关闭record_routing()两个示例和读者分享了在opensips的呼叫流程中的一些细节处理。通过以上两个示例可以看出,用户在某些环境中如果为了满足一个需求简单修改cfg文件可以实现某个功能,但是失去了其他功能和业务流程的支持。opensips切换为无状态模式,响应处理没有办法做进一步处理,包括其他的挂机状态的处理。如果关闭record_routing,呼叫路径上的终端就不会通过opensips或者其他代理进行呼叫,当然其他相关dialog,事务就发生了改变,CDR,BYE请求都都会失去完整的记录。因此,读者在实现某个功能时一定要首先满足SIP协议规范的处理流程,然后考虑通过灵活的方式实现不同场景的要求。
  参考资料:
  https://opensips.org/html/docs/modules/1.8.x/tm.html
  www.freesbc.cn
  www.asterisk.org.cn
【免责声明】本文仅代表作者本人观点,与CTI论坛无关。CTI论坛对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。请读者仅作参考,并请自行承担全部责任。

相关阅读:

专题

CTI论坛会员企业