首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

SIP注册呼叫流程最佳实践示例-十六个常用SIP流程示例-SIP注册,请求更新,会话创建等-RFC3665分享

SIP网络技术已经基本上处于IP语音技术和IMS网络的核心定位。因为其部署方式和呼叫流程存在多种不同,很多读者在学习时很难抓住其核心脉络。其实,在SIP的文档中,一些RFC规范组织以及发布了很多的指导文档,这些文档能够帮助读者对SIP网络呼叫中一些基本的呼叫流程做了详解说明,通过这些指导说明读者可以非常清晰地了解SIP呼叫业务中的一些基本流程,正常呼叫流程以及失败呼叫的处理等等,具体场景包括SIP注册,会话创建,通过各种代理的会话处理和失败状态的呼叫处理等等。

RFC3665为用户提供了比较基础全面的SIP呼叫流程的细节详解,包括了SIP注册,和呼叫,会话处理的最常见的16种呼叫场景的详解说明。今天,笔者对这16种呼叫的流程进行逐一解读和分享。内容章节包括背景说明,SIP注册流程和SIP会话创建流程三个主要部分。其中,SIP注册包括了五个注册流程,SIP会话创建包括了十一个关于会话创建的流程说明。

背景说明

因为SIP网络中涉及了多种网元,包括了SIP用户代理,客户端,SIP代理和转发服务器等,所以在示例中需要部署不同的实体来实现呼叫。另外,我们将讨论的示例流程仅基于RFC3261和RFC3264中的呼叫,关于SIP-PSTN的呼叫这里无太多涉及,读者可以参考RFC3666来进一步学习关于SIP到PSTN的呼叫流程。如果读者想了解其他呼叫业务的详解流程和其他基本的SIP网络的概念和深入讨论,这里不再做过多说明。读者可以参考以下链接来学习。

在这十六个示例中,需要的网络实体都有各自的地址和账号名称。具体的假设环境设置如下:

SIP注册流程

SIP注册是SIP网络环境业务的起始,没有注册也无从讨论其他呼叫业务。SIP注册流程的目的是SIP用户的AOR地址绑定具体的设备contact URL。关于AOR和注册绑定等话题读者参考以上链接。现在,我们具体讨论其注册流程。在SIP注册的示例包括了五个注册场景。

示例1-SIP成功注册流程。首先,我们看一下SIP成功注册的示例。此示例的注册流程如下:

Bob对SIP服务器发送REGISTER请求。此请求包括了用户的contact列表信息。以上注册显示使用了Digest的HTTP认证机制是方式,使用的是TLS传输(这里忽略显示,以下消息中显示)。使用TLS的目的是因为HTTP的Digest认证机制缺乏安全信息完整性保护,没有TLS的话,存在一定的注册攻击风险。关于Digest认证机制的问题,用户可以参考RFC3261-22.4章节。SIP服务器提供对Bob的挑战。Bob输入其有效的用户名称和密码。Bob的SIP客户端根据SIP服务器提供的挑战对用户信息加密,然后对SIP服务器端发送响应消息。SIP服务器端对安全凭证进行验证。然后,SIP服务器把用户信息注册到其服务器数据库中,对Bob的SIP客户端返回一个200(OK)响应。在响应的Contact头中包含了当前contact列表。认证格式是HTTP的Digest认证格式。这里假设Bob以前还没有注册到过SIP服务器。以下是SIP客户端成功注册的消息内容,包括了从F1到F4的交互信息。

F2消息:

F3消息:

F4消息:

示例2-contact列表更新流程。很多时候,SIP客户端的地址会发生改变,为了始终让SIP服务器端知道最新的地址信息,确保呼叫能够路由到正确的地址上,SIP客户端的列表信息需要更新。具体更新的流程如下:

Bob SIP Server

| |

| REGISTER F1 |

|------------------------------>|

| 200 OK F2 |

|

| |

Bob期望更新地址列表,能够确保SIP服务器转发请求到正确的地址中。Bob对SIP服务器发送注册请求。这里,Bob的请求中包含了更新的contact列表信息。因为用户已经对服务器端进行过了认证,用户在请求中提供了安全凭证信息,SIP服务器端不会再对Bob进行挑战。服务器端使用用户安全凭证信息验证其身份。服务器端注册用户用户信息到服务器的数据库中,更新用户的contact列表。在响应的Contact头中包含用户当前的contact列表信息。contact列表更新需要两个步骤,从F1到F2。消息交互流程如下:

F2消息

示例3-请求当前contact列表。Bob对代理服务器发送一个注册请求,请求中没有包含Contact头域值,这里表示用户期望和服务器端查询用户当前的contact列表。因为用户已经对服务器进行了认证,所以用户在请求中提供安全凭证,服务器端无需对用户进行挑战。

服务器端验证此安全凭证。服务器端返回一个200 OK响应,响应的Contact头域中包含了了用户需要查询的当前注册列表。F1消息如下:

F2 200 OK 返回消息:

示例4-取消注册。Bob期望从SIP服务器取消注册。Bob对SIP服务器发送一个注册请求。请求中包含一个超时周期为0的值(Expires: 0),并且提供了所有现存的contact地址信息。

因为用户已经对服务器端进行了验证,用户仅在请求中对服务器端提供安全凭证,服务器端无需对用户进行挑战。SIP服务器验证其安全凭证,服务器端从数据库中清除用户的contact列表,然后对Bob的SIP客户端返回200 OK响应。F1注册流程如下:

F2 消息如下:

示例5-未成功的注册。Bob对SIP服务器发送注册请求。SIP服务器端要求对Bob进行挑战。Bob输入其账号ID和密码。SIP客户端根据SIP服务器端的挑战对用户信息进行加密,然后对SIP服务器端发送响应消息。

SIP服务器端尝试验证其安全凭证,但是用户信息无效(用户密码不能匹配在服务器端已创建的用户帐户中的密码)。SIP服务器端对客户端返回一个401响应 (401 Unauthorized)。从F1到F4注册流程消息如下:

F1消息:

F2消息:

F3消息:

F4响应消息:

SIP会话创建

代理服务器使用HTTP Digest认证机制对Alice进行认证。这里假设Bob已注册在代理服务器2中,可以接受呼叫。

示例6-成功的会话创建。这里的Alice成功创建了会话,直接对Bob进行呼叫。成功呼叫经过了F1到F6几个流程。

F1流程:

F2流程:

F3流程:

F4流程:

这里开始双方RTP媒体流交互。接下来,Bob首先挂断了此呼叫。注意,这里的CSeq仍然是1,不是2(无增加)。双方仍然维持自己的独立的CSeq计数值,呼叫请求中的CSeq是由Alice生成,BYE请求中的CSeq是由Bob生成。

F5消息:

F6消息:

示例7-通过两个SIP代理服务器创建的会话。此示例中,双方终端通过两个SIP代理服务器创建了成功的会话。在此呼叫流程中,初始请求中包含了预加载的Router头,配置了代理服务器1的地址,此地址是Alice的outbound proxy代理服务器地址。此请求中不包含代理服务器1要求的Authorization安全凭证,因此会返回一个407响应包含挑战信息。发送了一个新的请求(F4)包含安全凭证和呼叫处理。Bob发送BYE请求结束此呼叫。

代理服务器1在请求中插入了Record-Route头消息,此头域将出现在所有后续消息交互中。代理服务器2也插入了自己的Record-Route头消息。ACK(F15)和BYE(F18)都有Record-Route。笔者历史文档中有类似的演示,读者有兴趣的话,可以参考如何使用两个OpenSIPS实现代理之间的呼叫。

此示例的处理流程如下。

F1消息:

F2消息:

F3消息:

F4消息-

F5消息:

F6消息:

F7消息:

F8消息:

F9消息:

F10消息:

F11消息:

F12消息:

F13消息:

F14消息:

F15消息:

F16消息:

F17:

这里注意,媒体流在双方之间创建,开始正式语音交互。然后,Bob首先挂机。同时,也应该注意,CSeq不是3,Alice和Bob各自独立维护自己的CSeq值。

F18消息:

F19消息:

F20消息:

F21消息:

F22消息:

F23消息:

示例8-通过多个代理认证的会话处理。在这个会话创建流程中,Alice使用两个代理完成了对Bob的呼叫,Alice的安全配置对两个域有效。因为初始请求F1中不包含代理1要求的安全凭证,因此代理服务器1返回一个407 Proxy Authorization进行挑战。新请求F4发送安全凭证,代理服务器2进行挑战,收到了正确的安全凭证后,开始处理呼叫,最后,Bob发送BYE消息结束呼叫(以下示例处理流程有错误)。

同样,代理服务器1在请求中插入了Record-Route头消息,此头域将出现在所有后续消息交互中。代理服务器2也插入了自己的Record-Route头消息。

F1消息:

F2,代理服务器对Alice认证:

F3:

F4-Alice重新发送一个新的请求,包含认证信息,这里使用了同样的Call-ID,但是增加了CSeq值。

以上处理中代理1接受了安全凭证,转发请求到代理服务器2。Alice的对端准备在49172端口接收呼叫。F5消息:

F6消息:

代理服务器2挑战Alice认证。F7消息:

代理服务器1从代理服务器2转发对Alice的认证,F9:

F10:

Alice对代理服务器1和代理服务器2重新发送请求,F11:

代理服务器1发现了Alice安全凭证,继续转发请求。F12消息:

F13:

代理服务器2发现了alice的安全凭证,通过认证,继续转发呼叫请求到Bob端。F14:

F15:

Bob收到呼叫请求后,马上应答此呼叫。F16:

F17:

F18:

F19:

F20和F21:

示例9-通过失败代理的成功会话。此示例中Alice通过代理实现了对Bob的成功呼叫。这里,Alice配置了两个代理服务器,一个是主代理服务器(代理服务器1),另外一个是备份独立服务器或者从代理服务器(代理服务器2)。这里可以通过DNS SRV记录来实现对代理服务器的路由定位。

Alice对两个代理服务器的域有效,支持其安全凭证。如果代理服务器1出现了服务器故障后(网络连通性可能无问题,但是无对呼叫请求的响应),不能继续执行呼叫服务,Alice通过从代理服务器实现对Bob的呼叫。

F1消息:

F2-F7和F1消息相同。忽略。Alice放弃对无响应的代理。对代理服务器2(从服务器)进行呼叫请求。F8消息:

代理服务器2对Alice提出挑战,F9:

F10:

Alice重新发送一个新的呼叫请求,携带安全凭证信息。F11:

代理服务器2接受了此挑战,安全凭证。代理服务器2转发此呼叫请求到Bob终端,准备从网络端的端口49172接收呼叫。F12:

F13:

F14:

F15:

F16:

F17-F19:

双方创建RTP媒体流,Bob然后挂机,发送BYE消息。F20-F23消息:

示例10-通过SIP ALG的会话处理。 在此示例中,Alice通过ALG网关和代理服务器实现了对Bob的成功呼叫。其呼叫是通过在F1请求中预设的Route头域来实现。这里要注意,媒体流创建不是通过端对端的流程来创建。ALG网关将结束媒体流和对媒体流进行桥接处理。ALG网关通过修改请求F1中的SDP中的,F10中的200 OK响应和任何的18x或者包含SDP的ACK消息来完成对媒体流的控制。我们很多的语音单通问题很可能就是ALG网关设置不当导致。具体处理方式,读者参考以下链接。

这里不再做太多细节介绍,仅对一般ALG流程做完整说明。

F1消息:

准备此端口49172接收呼叫。F2消息:

F3消息:

ALG网关准备从接收代理数据,从192.0.2.128/2000 到192.0.2.101/49172端口范围。代理服务器2使用定位服务决定Bob的地址。基于定位分析结果转发呼叫到Bob的地址。

F4流程:

F5消息:

F6:

Alice挂机,首先对ALG挂机,然后ALG对Bob挂机,发送BYE消息和200 OK。F14-F17:

示例11-通过转发和代理服务器的ACK中的SDP创建会话。 在此流程中,Alice呼叫Bob首先使用转发服务器,然后通过一个代理服务器来实现呼叫。呼叫请求首先发送到转发服务器,然后转发服务器对Alice返回一个302 临时响应。此临时响应中包含了Bob当前的SIP地址。Alice然后重新生成一个新的请求,通过代理服务器对Bob发起呼叫请求。在此呼叫请求中,没有携带SDP消息,SDP消息是在ACK中传输。Bob发送BYE消息结束呼叫。

F1消息:

F2消息,返回临时消息302:

F3:

F4:

F5到F10消息:

F11-F12,请求中未包括SDP,ACK包含SDP消息。

// 创建RTP媒体流。

F13-F16,Bob挂机,对代理发送BYE消息,返回BYE消息的200 OK。

示例12-通过重新发送请求(IP地址修改)创建会话。此示例演示了在会话期间的媒体修改引起的会话重新创建。当会话中,Bob的地址发生了改变以后,Bob重新对Alice发送了一个请求,请求中携带了新的contact和SDP消息。在此呼叫流程中,代理服务器不记录Record-Route的值,因此,初始交互后,此值不会出现在SIP消息路径中。

F1-F8的流程:

RTP媒体流创建,Bob修改为新的IP地址,重新对Alice发起请求,携带新的Contact地址和SDP。从F9开始,创建新的RTP媒体流。

Alice首先挂机,对Bob发送BYE消息(F12),Bob对BYE消息回复200 OK(F13)。

示例13-未成功,未应答的呼叫。此示例中,Bob应答呼叫之前(发送200 OK),Alice放弃了此呼叫。因为Alice没有收到来自于Bob的最终响应,Alice发送了一个取消请求CANCEL (F9)。如果此请求的200 OK已经和CANCEL相交的话,Alice将会对Bob发送一个ACK和BYE通知Bob以恰当方式挂机。

注意,CANCEL确认是通过200 OK,基于hop by hop的流程确认,不是简单端对端确认方式,忽略了跳点,不能直接Alice对Bob发送取消请求。确认发生在每个跳点,确保每一个跳点都有返回消息。

F1消息-F20消息流程:

示例14-未成功的忙呼叫处理。在此示例中,Bob处于忙状态,Bob对Alice的请求发送了一个486 busy here响应。这里不使用端对端处理,而采用基于hop by hop的处理方式,返回非2xx响应。另外要注意,许多SIP UA不返回486响应,因为它们可能支持了多线账号或者其他功能。

F1消息-F11包括了每个hop的486 响应以及其对应的ACK:

示例15-用户端的未成功无响应呼叫。在此示例中,针对Alice的请求,没有收到Bob的响应,期间代理服务器一直不断对Bob发送请求。经过对Bob尝试六次重新发送请求后,代理服务器2放弃请求,对Alice返回一个480 无响应消息。

F1消息:

F6-F11重新发送请求,最后放弃请求,对Alice返回480响应。

示例16-未成功临时无效呼叫。此示例中,Alice对Bob发起呼叫请求,Bob对Alice发送一个初始振铃响应,表示Bob已经获知此呼叫请求,其提示已经发生。但是,因为某种原因,Bob随后又对Alice发送了一个480无效响应。消息确认后,代理返回给Alice。注意,这里的480有对应的ACK,基于hop by hop处理,不是基于端对端处理。

F1消息-F14之间的响应和ACK。

参考资料:

https://www.rfc-editor.org/rfc/rfc3665

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230102A020KR00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券