您当前的位置是:  首页 > 资讯 > 国内 >
 首页 > 资讯 > 国内 >

SIP拓展协议RFC3262概述和100rel/PRACK详解

2019-10-28 10:11:18   作者:   来源:CTI论坛   评论:0  点击:


  随着基于SIP协议应用场景的增加,目前企业融合通信和语音呼叫中几乎绝大部分的场景中都使用了SIP协议。但是,和传统的PSTN相比,因为一些其他因素的影响,很多人对于基于SIP协议所提供的终端,接入设备和软交换仍然缺乏信心。客户可能仍然对SIP呼叫中出现的问题有着非常大的担心。这些担心也是正常的。事实上,为了进一步提升SIP呼叫的稳定性,SIP协议本身针对传输响应处理方面也做了一些拓展,使用这些拓展用来进一步保证SIP协议传输响应的稳定性。另外,为了保证更新的网络(IMS)正常工作以及和传统PSTN的兼容性,在SIP拓展中,使用了100rel/PRACK的拓展功能,可选标签100rel是SIP响应消息中一个比较常用的拓展功能,这个拓展是通过PRACK method来进行定义的。关于100rel拓展的定义,SIP拓展协议专门针对其属性做了规范说明,此说明在RFC3262中定义。今天,我们针对RFC3262结合相关SIP拓展的相关技术话题做一个完整概述,并且针对实际业务场景中的一些问题进行讨论,希望对读者有所帮助。
  1、背景介绍
  如果熟悉SIP响应的读者都一定知道,请求和响应是信令协商的基本手段。在RFC3261中规定了响应的定义,响应主要分为最终响应和临时响应。根据其概念名称,读者也大致理解了最终响应和临时响应的基本含义。简单来说,最终响应是可靠的,而临时响应是临时的,不可靠的响应。根据RFC3261-7.2的说明,其定义是:
  1xx: Provisional -- request received, continuing to process the request;
  https://tools.ietf.org/html/rfc3261#section-7.2
  在针对临时响应的定义中,读者可以非常明确地知道,对端已经收到请求,对端正在处理其请求。以下示例说明了启用PRACK的和使用最终响应处理的呼叫:
  在当前的呼叫环境中,包括现代的IMS网络中,呼叫需要经过多个网络环境和处理路径,需要更多的协商和资源支持。因此,在实际呼叫流程中可能发生更多的问题,对端需要耗费一定的时间来处理请求,具体需要处理的内容很多,包括:编码协商,对端服务器资源不足,会话时间太长,编码能力匹配问题,QoS,承载服务,和PSTN接续时间太长都会导致响应丢失的问题。因此,为了保证对端有充足的时间处理请求,UAS先返回一个临时响应通知对端本地正在处理这个请求,现在仅发一个临时性的响应。
  2、UAS工作方式说明
  根据RFC3262的说明,只要初始的请求包含了一个Supported,它的可选项是100rel,UAS可以对INVITE发送任何非100的响应。这里的初始请求的响应是一个临时的可靠性响应。此规范除了支持INVITE以外,不支持其他的可靠性临时响应的method。如果初始请求包含了Require头域,其包含了100rel可选项的话,UAS必须发送一个非100临时可靠响应。如果UAS不愿意那样处理的话,它必须拒绝此初始请求,返回一个420响应(Bad Extension),并且在响应消息中包含一个Unsupported 头域,可选项是100rel。具体示例,参考后续介绍。
  根据RFC3262说明,UAS一定不能通过100(Trying)发送可靠的响应。UAS只能通过101到109中间的响应码发送临时可靠响应。如果请求中既不包含Supported 头域也不包含Require头来表示临时可靠响应功能的话,UAS一定不能发送临时可靠响应。
  100(Trying)响应只能支持hop-by-hop之间的响应。因为此原因,这里讨论的可靠性机制是介于end-to-end的响应,因此不能使用100(Trying)。这里,关于end-to-end 和hop-by-hop的使用方式,读者一定要小心理解,因为各种method涉及了代理之间的通信和用户身份安全的问题。例如,BYE method是end-to-end之间的处理,而CANCEL是hop-by-hop的请求处理。
  在一些场景中,一个网络要素可以当作proxy来使用,此proxy也可以可靠临时响应。其工作方式类似于一个UAS,它的作用就是作为一个事务功能。但是,它不能尝试发送携带To头标签的请求。这里,一个proxy不能对已经在一个dialog内容中发送过的请求生成可靠临时响应。简单来说,就是已在一个dialog中发送过请求内容的,就不能对其请求生成临时可靠响应。当然,不像UAS一样,当proxy的一个网络要素收到一个PRACK时,这个PRACK不能匹配任何未处理的可靠临时响应,此PRACK必须经过代理格式化处理。
  很多读者可能有疑问,为什么UAS可能会发送可靠临时响应?我们在此文章中也讨论了关于响应之前的准备工作的问题,读者可参考。这里,其中的一个原因就是,如果INVITE事务需要耗费一定的时间生成最终响应,UAS响应经过一定的流程来做出最终响应,为了保证有足够的时间来回复最终响应,并且能够保持事务的正常状态,因此,在回复最终响应前,需要一个周期性的临时响应消息返回到请求对象端。因此,拓展功能100rel是一个必要的选择,也是规范推荐的使用方式。
  在UAS的核心构件中,针对UAS的临时可靠响应处理流程是根据RFC3261的8.2.6章节处理。读者可查阅读者历史文章了解处理流程。除了遵守其处理流程以外,临时可靠响应必须包含一个Require 头,支持100rel可选项和一个RSeq头域。在事务中的第一次可靠临时响应中的这个RSeq头的取值必须介于1到2**31-1之间。此规范推荐此值取值范围一律在此范围之内。不同请求的临时响应可以使用同样的RSeq数值。
  响应管理也需要定时器来处理。在规范说明中,可靠临时响应会周期性的定期传输到事务层。通过T1定时器来实现定时传输,如果重新传输的话,则对T1定时器翻倍设置。关于T1定时器的规范说明,读者可以参考RFC3261的17章节。一旦可靠临时响应被传输到了服务器的事务层后,可靠临时响应就会被添加到一个内部未确认的可靠临时响应列表中,等待处理。事务层会把重传的响应数据发送到UAS core中。
  当UA core收到一个匹配的PRACK后,可靠临时响应的重传就退出处理机制。收到PRACK后,UAS对对PRACK进行处理,处理流程和其他的method一样。关于PRACK的处理,读者可查阅RFC3261的第八章节和第十二章节。
  在RFC3262中,匹配PRACK是这样定义的。在同一dialog中,响应和其请求的所携带的参数匹配。具体包括,响应中RAck头中的method,CSeq-num和response-num需要匹配请求中的CSeq,RSeq的临时响应消息。
  如果UA core收到的PRACK请求,这个请求不能匹配列表中任何一个的未确认可靠临时响应数值。UAS必须回复一个PRACK,返回481错误响应码。如果这个PRACK请求不能匹配任何未确认可靠临时响应,对端必须对它返回一个2xx响应。这里,UAS可以确认,已经收到临时响应,这些响应正在被按序处理。PRACK应该退出可靠临时响应的重传流程,并且必须从未确认的可靠临时响应列表中移除。
  如果在一定时间内没有收到重传响应怎么办呢?在RFC3262中说明,如果在64×T1秒内,重新传输的可靠临时响应没有收到相应的PRACK反馈,UAS必须拒绝此初始请求,并且返回一个5xx响应消息。
  对于发送可靠临时响应的方式,本规范也做了进一步的说明。在第一个可靠临时响应被确认接收以后,UAS可以发送其他的可靠临时响应。这里一定要注意,直到第一个可靠临时响应确认以后,UAS才能发送第二个可靠临时响应。本规范推荐前一个可靠临时响应没有被确认之前,一定不能发送接下来的可靠临时响应。如果第一个可靠临时响应还没有被确认,紧接着发送后续的可靠临时响应的话,UAS不能确认这些可靠临时响应的接收顺序。
  对于同样一个请求,在后续的可靠临时响应中的RSeq值必须是大于1。简单来说,就是后一个可靠临时响应比前一个大1。
  对于UAS来说,其实,在发送临时响应过程中可能也存在一些特别的情况,例如何时发送最终响应。规范中有明确的说明,除非最终响应是2xx,并且未确认的可靠临时响应的其中一个响应中包含了会话描述,否则,在收到所有对未确认可靠临时响应的PRACK之前,UAS可以发送对初始请求发送一个最终响应。那种情况下,在它们的临时响应完全被确认之前,UAS一定不能发送最终响应,需要等到那些临时响应被完全确认以后才能发送最终响应。如果可靠响应仍然是未确认状态时,如果UAS不能发送最终响应的话,UAS不应该继续重传这些未确认的可靠临时响应。这时,UAS必须准备处理剩下的PRACK的响应。对UAS来说,它对请求发送了一个最终响应以后,一定不能发送一个新的可靠临时响应。
  3、UAC工作方式说明
  在上个章节我们讨论了UAS使用100rel的工作方式。现在,我们讨论100rel在UAC端的工作方式。根据rfc3262的说明,当UAC创建一个新的请求时,它可以插入一个可靠临时响应。具体的做法是,在请求中添加一个头域Require,携带100rel可选项标签。注意,这个Require头和100rel可选标签只能出现在INVITE method中,不能出现在其他的method中。具体的头域查看RFC3262的table1和table2,那两个table中有完整介绍。
  如果UAC不希望一直使用可靠临时响应的话,它仅表示支持临时响应,而且UAS又需要UAC发送一个可靠临时响应的话,UAC必须在请求中添加一个Supported 头域,携带一个100rel可选标签。UAC应该包括这个头域在所有的INVITE中。
  关于此处理方式具体的示例,读者可查阅PJSIP中100rel的代码说明。
  If the UAC wants to mandate 100rel support, it can specify PJSIP_INV_REQUIRE_100REL in the options argument when calling pjsip_inv_create_uac(). In this case, PJSIP will add 100rel tag in the Require header of the outgoing INVITE request.
  https://www.pjsip.org/pjsip/docs/html/group__PJSIP__100REL.htm
  如果收到一个针对初始请求的临时响应,响应中包含了一个Require头和100rel可选标签项,这个响应是一个可靠临时响应。如果这个响应是100(Trying)的话,必须忽略它的可选标签,也不能使用下面的处理流程。
  这里,我们开始讨论具体的处理流程。如果没有创建dialog的话,临时响应一定要创建一个dialog。这里,假设传输可靠响应,UAC必须创建一个新的PRACK请求。这个请求通过dialog关联的临时响应被发送出去,PRACK可以包含一个自己的消息体,继续其消息体是按照其格式来解析。
  注意,在一个dialog中,处理重传时,PRACK请求和其他的非INVITE请求一样。具体来说,当收到一个临时响应重传,并且这个重传正在被确认时,UAC不应该重传PRACK请求。提醒读者,尽管UAC那样做,但是也不会导致协议错误。
  一旦收到一个可靠临时响应,那个响应重传必须马上丢弃。那么,我们如何判断是一个重传响应呢?规范规定,当响应的dialog ID,CSeq和RSeq匹配了原始的响应中的这些参数时,这个响应就是重传响应。UAC中必须包含一个序列号,这个序列号可以表示针对初始请求所收到的最新的可靠临时响应。这个序列号必须一直包含在响应中,直到收到针对初始请求的最终响应。这个值必须是在初始请求的第一个可靠临时响应的RSeq中定义。
  处理后续的可靠临时响应和初始请求处理的规则是一样的。但是,还有一些不同,其原则是:可靠临时需要保证其传输顺序。因此,针对同样的请求,如果UAC收到其他的可靠临时响应,而且它的RSeq值不大于序列号值的话,这个响应一定不是在PRACK中被确认的,并且UAC一定不要继续处理这个响应。使用这个响应的部署环境可以丢弃这个响应,或者对其做一个缓冲处理,用来支持可能丢失的响应。
  UAC可以在最终响应以后确认收到的可靠临时响应,也可以丢弃这些可靠临时响应。
  4、Offer/Answer模式和PRACK的处理方式讨论
  Offer/Answer模式是SIP协议的一个非常重要的概念。在RFC3261中有具体的规范说明。笔者也曾经发布了很多关于这个概念的介绍,读者可以查阅历史文档做进一步的理解。同样,在SIP的拓展协议中-PRACK也支持同样的处理方式。接下来,我们具体讨论一下如何在PRACK中使用Offer/Answer的模式。
  如果在请求中提供了一个offer,UAC可以在可靠临时响应中生成一个answer(这里假设,UAC支持它们)。这样的话,它们之间就会创建一个会话。同样的道理,如果一个可靠临时响应是第一个可靠消息,这个消息返回到UAC,并且此INVITE没有包含一个offer的话,必须在那个可靠临时响应中添加一个offer。
  这里,我们讨论关于UAC收到offer或者answer的处理方式。如果UAC收到了一个可靠临时响应,携带一个offer,它必须在PRACK中生成一个answer。如果UAC收到一个可靠临时响应,携带一个answer,它可以在PRACK中生成其他offer。如果UAS收到一个PRACK,携带了一个offer,UAS必须对此PRACK在2xx中包含一个answer。
  一旦answer被发送或接收,即使原始INVITE自己本身还没有收到回复,UA应该创建基于offer/answer的参数来会话。
  当INVITE被接受时,如果UAS已经在可靠临时响应中包含了会话描述,这个可靠临时响应未被确认,UAS必须推迟发送2xx,一直到这个临时需要被确认。否则,1xx的可靠性不能被保证,并且可靠性操作需要offer/answer交互的适当操作才能完成。
  规范明确说明,所有支持此SIP拓展可靠性响应协议的代理必须支持offer/answer交互模式,此模式工作方式是基于rfc3261中13章节的规则来处理。基于目前INVITE和PRACK存在的请求,2xx和可靠性1xx作为非失败可靠响应。
  在rfc3262中定义了PRACK,具体语法,读者可以参考rfc3262的tabel 1,table 2和RFC3261中的table3。
  在本规范中定义了两个新的头域,包括RAck和RSeq。在临时响应中,RSeq是用来支持参数的可靠性。RAck头是通过PRACK请求定义的,用来支持临时响应的可靠性。RAck包含两个号码和一个method标签。第一个号码数值是被确认的临时响应中的RSeq头的值,第二个号码值和method是从被确认响应中的CSeq中拷贝出来的数值和method。在RAck头中的method名称是对大小写敏感的名称。例如:
  RAck: 776656 1 INVITE
  5、其他相关问题讨论
  很多情况下,关于PRACK的请求处理涉及了很多具体的环境。笔者归纳了几个检测时容易出现的问题进行讨论。
  在某些环境下,我们经常可能遇到终端或者服务器端是否支持PRACK请求的问题。很多时候,我们可能需要及时调整设备或者服务器端的设置就可以解决问题。现在我们给读者一个示例,让读者理解开启或者关闭PRACK的处理流程:
  通过以上流程,结合我们前面讨论的rfc3262,读者可以非常清楚了解PRACK的处理过程。一些用户仍然对100rel的协商非常迷惑,笔者这里耗费一点时间专门针对具体的业务场景做一个简单总结。具体到实际的UAS/UAC环境中,100rel可选项的处理完全取决于哪一侧的请求状态和是否开启关闭(Supported/Require头)。例如以下几个不同场景最终协商的结果:
  注意,这是一般的协商过程。在其他终端设备的处理可能有一些不同,这结果完全取决于接入网关和服务器端的兼容性设置。
  有时,用户可能在SIP消息中看到一个和PRACK相关的头域-precondition。Precondition是另外一个比较大的讨论话题,此头值在RFC3312/RFC4031中做了非常详细的定义,其中也包括了Precondition和Offer/Answer模式交互的关系,示例如下:
  • SIP/2.0 183 Session Progress
  • Max-Forwards: 70
  • Via: SIP/2.0/TCP [2001:0:0:2::1]:5060;branch=z9hG4bK932432170smg;transport=TCP
  • From: <sip:310410123456789@one.att.net>;tag=2763466811
  • To: <sip:0123456789;phone-context=one.att.net@one.att.net;user=phone>;tag=1111111111
  • Call-ID: 2270680280
  • CSeq: 1 INVITE
  • Contact: <sip:0123456789@[2001:0:0:2::2]:65094;transport=tcp>
  • Record-Route: <sip:[2001:0:0:2::2];lr>
  • Content-Type: application/sdp
  • Require: precondition // Indicate "precondition" is required
  • Require: 100rel // Indicate "PRACK" is Required
  • RSeq: 1
  • Content-Length: 763
  • Privacy: none
  很多呼叫在3GPP和非3GPP网络呼叫中,Preconditon协商中仍然有失败的可能:
  图片来自于3GPP规范
  当前,我们的手机呼叫已经在移动网络IMS中广泛使用。手机呼叫的流程需要经过更多节点的处理。在每个节点都需要耗费一定的时间。其协商过程也非常复杂。为了为读者提供一个比较全面的呼叫流程设置情况,读者可以参考相对完整的示例来进一步学习。以下是一个LTE网络中手机呼叫的协商流程(包括了100 trying,183, 180的基本使用场景):
  图片来自于:https://telecomtutorial.info/volte-call-flow/
  因为文章篇幅的关系,笔者这里不再做过多介绍。读者可以查阅以上图片链接,针对LTE呼叫的流程做具体了解。当然,在3GPP中,关于IMS中的SIP呼叫协商流程涉及了大概54个请求响应消息内容(如果没有记错的话),这里不能一一介绍。
  另外,在3GPP网络中有针对UAS/AUC关于PRACK头中的Supported和Require的一些调整,并且3GPP组织对其给出了一些建议(查阅3GPP T Release 6 37 R 29.962 V6.1.1或者更新版本)。用户需要根据具体的网络环境和3GPP的说明做进一步的了解。笔者没有查阅中国的IMS网络中关于和RFC3262的兼容性说明,中国在3GPP网络的规范也有一些调整。这些调整可能会影响实际SIP呼叫的使用,所以,读者一定要注意。
  如果我们把应用场景缩小到一般的企业业务场景中,看看接入网关和服务器端的使用状态。有时,一些网关产品和服务器端存在兼容性问题。很多时候,可能是服务器端或者终端没有开启PRACK选项支持。一些网关产品和服务器都可能包含三种设置方式:默认关闭PRACK,Supported和Require PRACK。因此用户可以检查双方关于PRACK的设置来解决这些问题。当然,如果出现了三种设置的话,事实上,根据双方配置的平台,经过协商以后,终端和服务器端就会产生多种响应结果。这完全取决于UAC和UAS的协商结果:
  具体的呼叫跟踪记录示例,网关侧成功的呼叫(183/200 ):
  • 16:32:35.762 CALL(SIP) (00:0004:00) SENT 183 Session Progress Reliable (100rel) to 10.129.45.102:8000 UDP
  • 16:32:35.782 CALL(SIP) (00:0004:00) RCVD PRACK from 10.129.45.102:8000 Cseq:2 with Via sent-by: 10.129.45.102 UDP
  • 16:32:35.782 CALL(SIP) (00:0004:00) SENT 200 OK PRACK to 10.129.45.102:8000 UDP
  网关测失败呼叫示例(420 错误码):
  • 21:16:47.845 CALL(SIP) (01:00004:00) SENT 421 Extension Required [PRACK support is required] to 10.129.45.104:5060 Cseq:1
  • 21:18:09.286 CALL(SIP) (01:00005:00) SENT 420 Bad Extension [Unsupported SIP request arrived at L3UA-TUC] to 10.129.45.104:5060 Cseq:1
  6、总结
  笔者通过5个篇幅的内容,具体介绍关于SIP拓展协议RFC3262和100rel拓展,PRACKmethod的使用协商方式。首先,我们介绍了临时响应的具体内容,为什么使用临时响应,以及涉及的相关协议RFC3262。然后,我们介绍了如何在UAS和UAC端处理100rel/PRACK。当然,UAS/UAC的协商过程是非常复杂的,很多细节需要读者根据实际的配置才能决定。接下来,我们介绍了关于RFC3262中几个主要的定义和Offer/Answer模式下的配合PRACK交互的流程。最后,我们针对一些在业务场景中具体的使用方式和终端/服务器端配置所产生的响应做了比较详细地分析。
  另外,笔者这里提醒读者,关于SIP拓展协议RFC3262的100rel处理涉及了3GPP中非常复杂的流程。在实际部署环境中还要配合运营商的网络来调整终端和SIP服务器端的配置,包括具体的呼叫业务流程操作都可能出现问题。笔者水平有限,这里仅是抛砖引玉,读者仍然需要对照具体的规范来排查。
  笔者再次提醒,如果读者使用开源的媒体服务器,例如Asterisk(建议使用PJSIP)或者FreeSWITCH,用户一定要开启100rel的相关选项,包括Supported和Require选项。
  参考资料:
  https://tools.ietf.org/html/rfc3262
  https://tools.ietf.org/html/rfc4032
  https://www.ietf.org/rfc/rfc3312.txt
  https://www.3gpp.org/technologies/keywords-acronyms/97-lte-advanced
  https://telecomtutorial.info/volte-call-flow/
  https://wiki.freepbx.org/
  https://tools.ietf.org/html/rfc3960
  https://github.com/alticelabs/asterisk-i/blob/master/p019_prack_support/asterisk-i-p019-prack-support.patch
  关注微信公众号:asterisk-cn,获得有价值的Asterisk/SIP技术和行业分享
  权威Asterisk freepbx FreeSBC技术文档: www.freepbx.org.cn
  完整企业融合通信商业解决方案:www.hiastar.com
  如何使用FreeSBC+FreeSWITCH/Asterisk,qq技术分享群:334023047
【免责声明】本文仅代表作者本人观点,与CTI论坛无关。CTI论坛对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。请读者仅作参考,并请自行承担全部责任。

专题

CTI论坛会员企业