Overview of Operation

来自Asterisk 中文技术社区
James.zhu讨论 | 贡献2020年3月16日 (一) 10:50的版本 →‎完整SIP操作总览
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

完整SIP操作总览[编辑]

此部分使用一个简单示例介绍了SIP的基本操作。它实际上是一个学习辅导,没有包含任何正式的说明。 第一个示例显示了SIP的基本功能:终端定位,希望通信的意愿,创建会话参数的协商和创建会话后会话拆线。

图表1 显示了一个典型的介于两个用户之间的SIP消息交互,两个用户分别是Alice和 Bob。(每个消息都通过一个带字母F的标签来标注,文本号码说明一个标注号码)。在这个例子中,Alice使用了一个在PC上运行的SIP应用程序(作为一个软电话)来呼叫Bob,Bob的电话是一个基于互联网的SIP电话。这个图例也同时显示了,这里有两个SIP 代理服务器介于Alice和BoB之间来支持会话管理工作。在图例1中,这种典型的设置方式我们通常称之为“SIP 拓扑图” "SIP 框架" 。

Alice使用自己的SIP身份 “呼叫”Bob,这种SIP身份是一种URL类型,我们这里称之为SIP URL。SIP URLs在Section 19.1中做了定义。它的格式和邮件的格式非常相似,一般都包括一个用户名称和主机名称。在这个例子中,它就是 sip:bob@biloxi.com, 这里biloxi.com是一个Bob的SIP服务提供商。Alice可能也具有和Bob的URL同样的类型,或点击一个超链接后进入一个地址薄。SIP同样也提供一个安全的URL,被称之为SIPS URL。安全URL的示例为sips:bob@biloxi.com。通过SIPS URL发起的呼叫可以保证安全,加密的传输,它用来传输所有从呼叫方到被呼叫方域的所有SIP消息。 从这里,开始,SIP的请求消息安全地发送到被呼叫方,但是安全机制依赖于被呼叫方域的安全策略设置。

SIP 是基于一种类似于HTTP-形式的请求/响应事务处理模式。每个事务处理包括一个启动了特别method方法的请求,或者一个功能,和至少一个来自于服务器端的响应构成。在这个例子中,事务处理是以Alice的软电话开始,软电话发送一个INVITE请求,携带了Bob SIP URL地址。这里,INVITE就是一个SIP method方法,它指定了一个执行命令,请求方(Alice)想让服务器方(Bob)接收这个请求。这个INVITE请求中包含了几个头域header fields。Header fields 被命名为属性值,这些属性值提供了关于消息的其他额外信息。在INVITE中的某些属性表示了呼叫的唯一身份,目的地地址,Alice的地址,和Alice和Bob之间创建会话所期望的会话类型的信息。INVITE (F1消息中)可能类似于这样的流程:

Sip-op.png

INVITE sip:bob@biloxi.com SIP/2.0

Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds

Max-Forwards: 70

To: Bob <sip:bob@biloxi.com>

From: Alice <sip:alice@atlanta.com>;tag=1928301774

Call-ID: a84b4c76e66710@pc33.atlanta.com

CSeq: 314159 INVITE

Contact: <sip:alice@pc33.atlanta.com>

Content-Type: application/sdp

Content-Length: 142

文本消息的第一行包含了一个方法名称method(INVITE)。 紧接着的是几行包含一个header 值域的列表。在这个示例中,它们包含了最少的要求设置。这些头header简单描述如下:

  • Via 包含了一个地址(pc33.atlanta.com),Alice希望对这个请求获得响应的地址。它也包含了一个branch参数来确认这个事务处理。
  • To 包含了一个显示名称(Bob)和一个SIP或者SIPS URL(sip:bob@biloxi.com) 。Display names在 RFC 2822 [3]有介绍。
  • Call-ID包含一个对这个呼叫的全局唯一确认信息,它是由一个任意字符串和软电话主机名称或IP地址组合而成。To tag的组合,From tag的组合,和Call-ID完整定义了一个Alice和BoB两者之间的点对点的SIP关系,这种关系可以看作一个dialog对话。
  • CSeq或Command Sequence包含一个整数和一个method名称。这个CSeq是一个增长的数值,它是支持每一个在dialog里新的请求,并且是一个普通的序列号码。
  • Contact包含一个SIP或者SIPS URI,它用来表示一个直接的路由去联系Alice,通常情况下,它由一个用户名称以及它所在的全限定域名构成(FQDN)。 如果使用了全限定域名(FQDN)的话,许多终端系统没有已注册的域名,因此,这里IP地址是允许的。Via头告诉其他参数往哪里发送响应消息,Contact告诉其他参数往哪里发送将来的请求消息。
  • Max-Forwards最大前转来限定一个请求到达目的地的最大跳跃(hop)数量。它是由一个整数数值构成,在经过一个跳转时会降低一个数值。
  • Content-Type 包含一个信息体的描述,这里忽略。
  • Content-Length contains an octet (byte) count of the message body.

完整的SIP头域集合在Section 20 中有详细的定义。

会话的细节,例如媒体类型,编码,采样率等没有在SIP中进行描述。 这些细节而是包含在了SIP消息体中,它们通过编码以后以各种协议的格式出现。其中一种协议格式就是 会话描述协议-Session Description Protocol (SDP) (RFC 2327 [1])。这个SDP消息(没有在这里显示)示例是通过SIP消息来传输,传输的方式类似于电子邮件中的附件方式来传输,或类似于通过HTTP消息传输网页页面内容的方式。

因为软电话不知道Bob的地址或biloxi.com域名中的SIP服务器地址,软电话发送一个INVITE 到SIP 服务器端,这个SIP服务器支持Alice的域,atlanta.com。 atlanta.com SIP 服务器已经配置了Alice的软电话,或者通过DHCP发现了软电话地址信息。

这个atlanta.com SIP 服务器是一个代理服务器。代理服务器接收请求,然后作为一个请求者转发这些请求。在这个实例中,代理服务器接收到了INVITE请求,然后发送了一个100 (Trying) 响应给Alice的软电话。这个100 (Trying) 响应表示这个INVITE已经被收到,代理正在通过路由设置路由这个INVITE到其目的地。在SIP中,响应消息使用一个三位数的码和描述短语作为回复消息。这个响应消息在Via中包括同样的To, From, Call-ID, CSeq 和 branch参数 parameter,这些参数和INVITE中的一样,这些参数允许Alice的软电话关联响应消息来发送INVITE消息。这个atlanta.com代理服务器定位到这个代理服务器在biloxi.com,它可能执行一个特别的DNS查询来找到服务biloxi.com 域的SIP 服务器。这个部分的描述在[4]中。 因此,它获得biloxi.com 代理服务器的IP地址,然后转发或者在这里代理其INVITE请求。在转发这个请求之前,这个 atlanta.com 代理服务器添加另外一个Via头域,这个头域包含自己的地址(这个INVITE已经在第一个Via包含了Alice的地址)。biloxi.com 代理服务器收到这个 INVITE消息后,然后回复一个带100 (Trying) 响应消息到atlanta.com 代理服务器,表示它已经收到了这个INVITE消息,正在处理这个请求。代理服务器会查询一个定位服务器,我们称之为定位服务,定位服务包含当前Bob的IP地址。(我们将会在下一个部分看到如何实现数据库查询。)biloxi.com 代理服务器会添加另外一个Via header ,并且携带自己的IP地址,这个地址是针对这个INVITE请求的,代理转发这个请求到Bob的SIP软电话。

Bob的软电话收到这个INVITE 消息后,对 Bob 发出提示,告诉他有从Alice来的电话呼叫,Bob决定是否应答这个呼叫,这里Bob的软电话会产生振铃提示。Bob的软电话提示180振铃,这个响应消息会路由根据相反的方向回到两个代理服务器。每个代理使用Via header 域值来决定发送响应的地址方向,并且从顶部路由记录中删除自己的地址。因此,尽管要求DNS和定位服务查询 路由这个初始的INVITE请求,180(Ringing)响应返回到呼叫方时可以没有查询消息或没有代理服务器中所保持的状态。

这样也获得了一个合理的响应属性,每个看到INVITE消息的代理服务器也可以看到所有对INVITE的响应消息。

当Alice的软电话收到这个180 (Ringing)响应后,它会传递这个信息给Alice,传递过来的信息方式可以使用一个回铃音(ringback tone)或或者在Alice终端屏幕显示一个消息。

在这个示例中,Bob 决定应答这个呼叫。当他拿起电话听筒时,他的SIP电话会发送一个 200 (OK) 响应消息来表示这个呼叫已经应答。这个200 (OK) 包含了一个消息体,这个消息体带了这个呼叫会话的媒体描述类型,这个媒体描述中说明了Bob希望和Alice创建会话。因此,这里有一个两阶段的SDP消息交互过程:Alice发送一个交互消息给Bob,Bob然后发送了一个交互消息给Alice。 这个两阶段的交互提供基本的协商能力,它是基于一个简单的offer/answer SDP交互模式来进行的。 如果Bob不希望应答这个呼叫或者Bob电话可能被占线,他此时和其他人进行通话,那么Bob终端则会发送一个错误响应消息而不是200 (ok),这样就会导致没有媒体创建的情况。 完整的SIP响应码在在Section 21中列出。Bob发送的200 (OK) (图例 1中的消息F9)可能类似于这样:


SIP/2.0 200 OK

Via: SIP/2.0/UDP server10.biloxi.com ;branch=z9hG4bKnashds8;received=192.0.2.3

Via: SIP/2.0/UDP bigbox3.site3.atlanta.com ;branch=z9hG4bK77ef4c2312983.1;received=192.0.2.2

Via: SIP/2.0/UDP pc33.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

响应消息的第一行包含了响应码(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参考消息体(这里没有列出),这个消息包含了Bob SDP 媒体的信息。

另外,在这个示例中,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。

Alice和Bob之间的媒体会话启动,他们之间的软电话开始发送媒体数据包,媒体数据包的格式是他们之间的SDP交互互相同意支持的格式。一般来说,端对端的媒体数据通过不同的路径发送,而不是使用SIP信令消息的路径。

在这个会话过程中,Alice或Bob任何一方都可以有权决定修改媒体会话的属性。修改会话属性是通过发送一个re-INVITE消息,在此消息中包含一个新的媒体描述来实现。这个re-INVITE涉及到了已存在的dialog,因此其他的参与方知道这个消息是修改了现在的会话,而不是重新建立的新会话。其他方发送一个200(ok)接受这个修改。请求方对200(ok)发送一个ACK。如果其他方不能接受这个修改的话,它会发生一个错误响应,例如488 (Not Acceptable Here),同样也接收一个ACK确认消息。但是,这个re-INVITE失败不会导致目前的呼叫失败-这个会话仍然会继续使用以前协商的属性。完整的话会修改细节,请阅读Section 14。

在呼叫结束后,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或者SIP URL)。 这个注册会写入此关联,也被称之为在数据库中的绑定或者定位服务,此定位服务可以使用在biloxi.com 域的代理中。经常,对于一个域的注册服务器需要和这个域的代理协同工作。这里一定要注意,区分不同类型的SIP服务器功能概念是非常重要的,它们区别是在于逻辑处理的不同,而不是物理上,形体上的不同。

Bob不仅仅局限于从一台设备注册。例如,Bob的两个终端设备,一台在家里面,另外一台在办公室都发送注册消息。两台设备的消息都保存在定位服务中,允许代理执行各种对Bob 终端的定位查询。

同样的道理,同一时间,多个用户可以注册到一台单个设备上。

定位服务仅是一个抽象概念。通常情况下,它包括一些必要的信息,它支持代理输入一个URL,并且接收零个或多个URL,这些URL告诉代理往什么地址发送请求。注册是一种方式来创建这些信息,但也不仅仅是这一种方式。任意映射功能可以通过管理员自行决定。

最后,一定要注意,在SIP中注册是用来路由入局的SIP请求的,它不能充当出局的授权请求的角色。在SIP中,签权和身份认证的处理可以基于逐一请求的方式,使用 challenge/response 机制的方式来处理,或使用更低一层的方案来处理,这种方案的讨论在Section 26 有所描述。

完整的关于SIP注册的消息细节示例在Section 24.1讨论。

其他的SIP操作,例如查询SIP服务器的能力或终端使用OPTIONS,或使用CANCEL取消正在进行的请求等流程将会在后续之间进行讨论。