- SIP/2.0200 OK
- Via: SIP/2.0/UDPserver10.biloxi.com ;branch=z9hG4bKnashds8;received=192.0.2.3
- Via: SIP/2.0/UDPbigbox3.site3.atlanta.com ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2
- Via: SIP/2.0/UDPpc33.atlanta.com ;branch=z9hG4bK776asdhds ;received=192.0.2.1
- To:Bob <sip:bob@biloxi.com>;tag=a6c85cf
- From:Alice <sip:alice@atlanta.com>;tag=1928301774
- Call-ID:a84b4c76e66710@pc33.atlanta.com
- CSeq:314159 INVITE
- Contact:<sip:bob@192.0.2.4>
- Content-Type:application/sdp
- Content-Length:131
- (Bob'sSDP not shown)
响应消息的第一行包含了响应码(200)和响应原因短语习语(OK)。其余其他行消息包含 header值域消息。Via,To, From,Call-ID,和 CSeq header 值域都是从 INVITE请求中拷贝过来的。(注意,这里有三个Via 头值–一个是Alice软电话添加的,另外一个是atlanta.com代理服务器添加到,还有一个是biloxi.com代理添加的)。Bob的软电话已经在header中添加了一个taq标签参数To。这个标签将会在两个终端的dialog中使用,也将会在此呼叫将来的请求和响应使用。
Contact头包含了一个URL地址,这个URL就是Bob可以直接访问的软电话地址。 Content-Type 和 Content-Length参考消息体(这里没有列出),这个消息包含了BobSDP 媒体的信息。
另外,在这个示例中,DNS和定位查询显示代理服务器可以做一个灵活的路由决定,它可以决定往哪里发送请求。例如,如果Bob软电话返回一个486 (Busy,忙状态)响应的话,biloxi.com 代理服务器可以代理这个INVITE到Bob的语音邮箱服务器。代理服务器也可以同时发送一个INVITE到多个地址。这种类型的并行查询方式称之为forking(分支)处理方式。
在这个示例中,200 (OK) 消息通过两个代理服务器返回到Alice,Alice软电话收到响应消息,软电话停止回铃音,表示呼叫已应答。最后,Alice软电话发送一个确认消息ACK,这个消息发送到Bob软电话来确认最终响应 (200 (OK))已收到。在这个示例中,这个ACK是通过Alice软电话直接被发送到了Bob软电话,发送过程绕开了两个代理服务器。这样处理的原因就是因为两个终端已经通过互相学习知道对方的地址,双方地址是通过INVITE/200(OK)交互时的Contact头获得,当然这个地址在初始时的INVITE是双方都不知道的。两个代理服务器的查询服务也不需要。因此,代理服务器则会退出这个呼叫流程。这个处理过程成功实现了 INVITE/200/ACK 三方握手,并且创建了SIP会话。完整的关于SIP会话创建的细节,请参考Section 13。
注意,为了帮助读者非常清晰地理解rfc3261,在本章节和未来的章节中笔者会适当增加一些第三方的资料和流程图,这样比完全介绍rfc3261协议本身更加清晰,以便帮助读者更好理解SIP协议。但是,为了保证rfc3261的权威性和完整性,如果是第三方的资料,笔者会尽量注明是非rfc3261协议资料。
![](http://www.ctiforum.com/uploadfile/2018/1207/20181207104705141.jpg)
非rfc3261协议资料
Alice和Bob之间的媒体会话启动,他们之间的软电话开始发送媒体数据包,媒体数据包的格式是他们之间的SDP交互互相同意支持的格式。一般来说,端对端的媒体数据通过不同的路径发送,而不是使用SIP信令消息的路径。
在这个会话过程中,Alice或Bob任何一方都可以有权决定修改媒体会话的属性。修改会话属性是通过发送一个re-INVITE消息,在此消息中包含一个新的媒体描述来实现。这个re-INVITE涉及到了已存在的dialog,因此其他的参与方知道这个消息是修改了现在的会话,而不是重新建立的新会话。其他方发送一个200(ok)接受这个修改。请求方对200(ok)发送一个ACK。如果其他方不能接受这个修改的话,它会发生一个错误响应,例如488 (Not Acceptable Here),同样也接收一个ACK确认消息。但是,这个re-INVITE失败不会导致目前的呼叫失败-这个会话仍然会继续使用以前协商的属性。完整的话会修改细节,请阅读Section14。
在呼叫结束后,Bob首先挂机(hangs up),并且生成一个BYE消息。这个BYE会直接路由返回到Alice的软电话,这里仍然绕过了代理。Alice确认了BYE接收,发送一个200(ok),结束这个会话和BYE消息事务。这里没有ACK发送-ACK发送仅发生在对INVITE请求的响应中。对于对INVITE特别处理的原因会在后续的章节中讨论,这里涉及了SIP中的可靠性机制问题,振铃应答的时间程度和分叉处理等因素。因为这个原因,SIP中的请求处理经常被划分为INVITE或者non-INVITE两个层面,除了INVITE method以外,还涉及其他的所有methods 。完整的关于会话结束的详情将在Section 15进行讨论。
Section 24.2 描述了在 Figure 1的完整的消息构成。
在某些案例中,对于代理来说可能非常有用,在整个会话期间可以看到两个终端之间在SIP信令路径上的所有消息。例如,如果 biloxi.com 代理服务器希望保持除了初始INVITE以外的SIP消息,它对INVITE添加一个要求的路由header值,这个值我们称之为Record-Route,用来解析主机或者代理的IP地址。因为Bob软电话(这个消息会通过200(ok)传送会Bob)和Alice软电话将会收到这个消息,在整个dialog过程中保存这个消息。biloxi.com 代理服务器将收到和对BYE代理转发这个ACK,BYE和200(OK)。每个代理可以独立决定收到的后续的消息,消息将被通过所有选择接收的代理发送,这些代理来接收这个消息。这个能力经常被代理使用,代理通过这个能力可以提供mid-call 功能或者呼叫期间的控制功能。
注册是另外一个SIP常用的操作。注册是一种方法,它可以使得biloxi.com服务器获知当前Bob的位置。Bob软电话基于初始化处理,在一定周期内Bob软电话对在biloxi.com的服务器发送REGISTER消息,我们称之为SIP registrar或者SIP注册。REGISTER 消息关联Bob的SIP软电话或者SIPS URI (sip:bob@biloxi.com),这个机器是当前Bob写入记录的地址(它在Contact头中传输SIP或者SIPURL)。这个注册会写入此关联,也被称之为在数据库中的绑定或者定位服务,此定位服务可以使用在biloxi.com 域的代理中。经常,对于一个域的注册服务器需要和这个域的代理协同工作。这里一定要注意,区分不同类型的SIP服务器功能概念是非常重要的,它们区别是在于逻辑处理的不同,而不是物理上,形体上的不同。
Bob不仅仅局限于从一台设备注册。例如,Bob的两个终端设备,一台在家里面,另外一台在办公室都发送注册消息。两台设备的消息都保存在定位服务中,允许代理执行各种对Bob 终端的定位查询。
同样的道理,同一时间,多个用户可以注册到一台单个设备上。
定位服务仅是一个抽象概念。通常情况下,它包括一些必要的信息,它支持代理输入一个URL,并且接收零个或多个URL,这些URL告诉代理往什么地址发送请求。注册是一种方式来创建这些信息,但也不仅仅是这一种方式。任意映射功能可以通过管理员自行决定。
最后,一定要注意,在SIP中注册是用来路由入局的SIP请求的,它不能充当出局的授权请求的角色。在SIP中,签权和身份认证的处理可以基于逐一请求的方式,使用 challenge/response 机制的方式来处理,或使用更低一层的方案来处理,这种方案的讨论在Section26有所描述。
完整的关于SIP注册的消息细节示例在Section 24.1讨论。
其他的SIP操作,例如查询SIP服务器的能力或终端使用OPTIONS,或使用CANCEL取消正在进行的请求等流程将会在后续之间进行讨论。
5 SIP 协议结构
SIP 是按照一定的层级结构创建的协议,这表示它的行为是根据一系列各自相对独立的处理流程来实现,每个处理阶段之间是松耦合关系。协议行为描述为多个层级,这样是为了支持呈现的目的,支持标准的函数描述,这些描述涉及了单一环境的多个要素。它不能通过任何方式来决定部署。当我们说一个要素“包含”一个层级时,我们的意思是它符合一系列在这个层级所定义的规范规则。
不是每个通过协议设定的要素都包含在每个层级。进一步说,在SIP协议中设定的要素是逻辑要素,不是物理形态的要素。一种物理实现可以选择不同的逻辑要素来执行,也许可以基于依次事务对事务的处理方式进行。
![](http://www.ctiforum.com/uploadfile/2018/1207/20181207104759183.jpg)
非rfc3261协议资料
SIP结构的最低层是语法和解码层。解码是通过增强的Backus-Naur Form grammar (BNF)语法来实现的。完整的BNF在Section 25有介绍。整个SIP消息结构的总览在Section 7介绍。
第二层是传输层。它定义了用户如何发送请求,如何接收响应和服务器如何通过网络接收请求和发送响应。所有SIP要素都包含一个传输层。传输层是在Section 18进行描述。
参考资料:
https://www.rfc-editor.org/rfc/pdfrfc/rfc3262.txt.pdf
关注微信公众号:asterisk-cn,获得有价值的Asterisk行业分享
Asterisk freepbx 中文官方论坛:http://bbs.freepbx.cn/forum.php
Asterisk freepbx技术文档: www.freepbx.org.cn
融合通信商业解决方案,协同解决方案首选产品:www.hiastar.com
Asterisk/FreePBX中国合作伙伴,官方qq技术分享群(3000千人):589995817