【SIP协议】学习初学笔记

 

作者:gnuhpc 
出处:http://www.cnblogs.com/gnuhpc/

 

 

1.SIP这玩意是怎么走来和如何构建的?

通俗的说,SIP就是一个轻量级信令协议,它可以作为音频、视频、及时信息的信令。

说到SIP是怎么出来的就要提H.323,而提到这个标准由不得不提到ITU-T,我们就先说说指定SIP的IETF(Internet Engineering Task Force)和制定H.323的ITU-T(International Telecommunications Union–Telecommunications Standard Sector)之间一些小趣事吧。ITU-T和IETF想事儿总是不一样的,它们俩往往从两个不同的角度来进行。ITU-T作为一个隶属于美国的国际标准化组织,传承了美国政策的一致性和试图完成维护世界和平的角色,所以它制定出来的标准一定是经过无数轮的反复和草案,花了N年制定出一个最终的,广为接受的结果。而恰恰相反,IETF则更趋近于实用主义,信奉“rough consensus and running code”,也就是说能用进行,边用边补充呗。因此在大多数时候,IETF标准制定的周期要比ITU-T短一些,这可能也归因于IETF每年举办三次开放性论坛。这些春季、夏季、秋季会议会安排在世界各地,并且向各个对此感性趣的组织开放(去瞅一瞅吧:http://www.ietf.org/meetings/meetings.html )多个IETF工作组在这些会议上相聚,针对他们现在的系统开发敲定一些技术细节,对于要是到了会议结束时还是没有解决的问题那就几个月后的下次开会继续研究呗。简而言之,IETF以一种实际实用的角度去完善体系架构和协议设计。

说了这么多可能你还没有意识到我在扯这些是为了什么,但是请记住这些正是SIP(Session Initiation Protocol)架构所体现的核心思想——先用着,再扩展。SIP的结构是建立于两个常用协议之上的:在RFC 2821中的SMTP 协议(Simple Mail Transfer Protocol )——它定义了电子邮件的消息格式,以及定义在RFC 2616的HTTP协议 (Hypertext Transfer Protocol )——它定义了基于Web的多媒体通信消息。另外,SIP又使用了定义在RFC 3550中的RTP/RTCP协议(Real Time Transport Protocol/Real Time Control Protocol )——它定义了在IP网上的多媒体包格式,还使用了定义在RFC 2327的SDP协议(Session Description Protocol )——它定义了一个多媒体会话的参数和特征。因此,SIP是建立在其他IETF提出的协议之上的,这有点像H.323建立在诸如H.225.0和H.245等ITU-T制定的协议之上,它的两个比较基础的RFC分别是版本1.0 RFC2543和版本2.0 RFC3261。当然,SIP还运行于其他IETF定义的传输协议之上,比如TCP(Transport Control Protocol ), UDP(User Datagram Protocol ) 和IP (Internet Protocol )等。这样,这么多著名的,并且被广泛应用的协议为SIP提供了超于H.323的简单明了的特性。

在网上看到了这样三个MindMap,觉得很能表达SIP的基本核心思想:

clip_image002

clip_image004

clip_image006

关于SIP的架构,我们一定要知道这玩意不是什么新鲜玩意,你看看它基于什么就知道了,这么个拼出来的东东架构能崭新到什么地步呢?我的粗浅理解是SIP的主要架构其实就是一个典型的C-S架构:一个Client客户端在RFC3261中定义为一个发送SIP请求并接收SIP回应的网络元素,这个Client可能与也可能不与人进行交互。对应的,一个Server服务器是接受SIP请求并且给予其回应的网络元素。比如最典型的是一个SIP请求INVITE,邀请一个用户或者服务器参与会话,若得到的是肯定的响应的话,那么则会返回响应SUCCESS。要是再深入一点,我们可以将这样一个简单的分类进行细分:

     Client分为两类:

用户代理客户端User Agent Client :它是一个逻辑功能,它创建请求、并且使用这个功能实体的一些具体功能发送出请求。

代理Proxy :中文翻译过来还是代理,但是这个与上边的Agent不一样,它是一个中间设备,既作为Client,也作为Server ,可以解释、翻译、改写一个请求,并将请求转发给其他的服务器,完成路由功能。有时候有状态和无状态Proxy,所谓有状态就是Proxy根据不同的情形作出不同的处理,这些处理具有前后的相关性,比如三个人传数字,A要通过B给C传一个数字,一种情况是不管A说什么,B都说同一数字给C,这叫做无状态Proxy;另一种状态是A说1的话,B就传给C数字2,要是A说2的话,B就传给C数字3,这样就是一个有状态的Proxy。有些资料上有所为B2BUA,实质与Proxy很相似,只不过更加灵活。

    Server分类三类:

用户代理服务器User Agent Server: 它是一个逻辑功能,它对一个请求产生应答。

重定向服务器Redirect Server: 一个将客户端的请求重定向去联系另一个服务器以完成请求的服务器。

注册服务器Registrar :一个接受REGISTER 注册请求,并将信息放置于位置服务器的服务器。

注意:我们在书上常常看到的UA是一个概括的说法,之所以区分UAS和UAC只是从逻辑上区分,实质上不一定是独立物理实体。

2.SIP该在哪,能干啥?

我们学习SIP就要知道它的地位,有个宏观的了解才能知道N多协议之间的关系:

clip_image008

既然根据RFC 3261,SIP是基于STMP和HTTP的,并且底层使用了IP、UDP和TCP,那么它就是一个应用层协议,也就是说,它能为End User提供服务,你能看得见摸得着。描述SIP应用服务的单位是会话,也就是英文中Session一词,意为在两个或多个参与者之间有顺序的交换信息,更深入一点,SIP必须先去扮演建立会话的角色,然后再在通信中管理会话。大家更关注的有三点:

a.多于两个的参与者就意味着呼叫可能是多点的,而不仅仅是点对点的那样子。

b.End User可能总不是从相同的地点发起呼叫的,我们需要添加追踪这些End User的功能。

c.End User可能会使用文字、音频、视频等的混合媒体类型,这些在网路中对网络的带宽、最大传输延时等都有不同的要求和限制。SIP还需要对此进行有效处理。

针对以上的Concerns,RFC 3261主要定义了五个方面的SIP多媒体会话管理能力:

· 用户位置管理:决定哪一个端系统用于这次通信。

· 用户可用性:决定被叫端是不是愿意参与这次通信。

· 用户容量:决定用于这次通信的媒体以及其参数。

· 会话建立:在被叫和主叫两端建立会话参数。

· 会话管理: 包含转接和终止会话、修改会话参数、调用会话业务。

3. SIP依靠怎么运作?

既然SIP是建立在SMTP和HTTP上的,那么其消息格式也有巨大的相似度,但是注意到一个SIP会话的资源是通信资源,而不是页面或者网页资源,这是与HTTP不同的地方。一个身份或者叫做一个寻址体制必须在请求/响应集有效建立之前建立。身份标识就是所谓的SIP URI(SIP Uniform Resource Indicator),其中包含了充足的信息来初始化一个会话。使用这个标识的资源的例子(RFC 3261中提供的)有:有在线业务的用户、在一个消息系统中的一个邮箱,在一个组织中的一组逻辑用户(例如销售部门),一个PSTN电话号码等等。SIP URI与电子邮件地址类似,这也是借用了SMTP协议中的规定:典型的包含两部分,第一部分为用户名,第二部分为主机名,sip:huangpc@bupt.cn 这是RFC 2543所介绍的最通常的格式 当然SIP URI还有其他的一些格式,比如在RFC 3261中引入的安全SIP URI:sips:huangpc@bupt.cn 这个是在TCP上的TLS作为安全传输层的一种方式。

定义了用户标识后,我们就可以定义请求的标识了——SIP中称为方法(Method)。其他的扩展方法在后续的RFC中都有定义。

· REGISTER: 用于与SIP服务器进行注册。

· INVITE: 用于表明用户或者服务器被邀请参与这个会话。这个消息体中将包含一个对被叫端的会话描述。

· ACK: 仅用了INVITE请求,表明收到请求。

· CANCEL: 用于取消一个pending 的请求。

· BYE: User Agent Client用户代理客户端发送,来告诉服务器它希望结束通话。

· OPTIONS: 向服务器查询它的能力。

定义完请求,很自然我们需要回应的语言规范:包含状态码和描述性短语。分为六类:

· 1xx: 暂时性回应,表明已经接收到,正在处理之中。

· 2xx: 成功回应,表明动作已经被接收,理解并且接受了。

· 3xx: 重定向回应,需要进一步的动作来处理处理这个请求。

· 4xx: 客户端错误回应,请求中语法不对,不能被服务器接受。

· 5xx: 服务器错误回应,服务器不能处理这个有效的请求。

· 6xx: 全局错误回应,这个请求不能被任何服务器接受。

你现在可能比较纳闷,这都是些关于SIP会话建立和拆除的部分,但关于这个会话中要传的文字、音视频等的格式等双方是怎么知道的呢?在INVITE中,就带有了这些信息,这个信息的格式则又引出了另一个RFC,RFC 2327,会话描述协议(Session Description Protocol (SDP))。

SIP和其他协议一样都有这样的一个要求:在会话开头时两端要有充分的信息交流。使用的两个协议就是定义在RFC 2974中的SAP(Session Announcement Protocol )和定义在RFC 2327的SDP (Session Description Protocol)。简单来说,SAP提供了一种定期宣传多媒体会话,向有意参与会话者传递相关会话信息的机制。使用它来支持Mbone(Internet Multicast Backbone),因此关兴趣的各方都会清楚的指导目前正在进行的一些会话。而SDP则定义了描述一个通信会话的格式,同样的,它也可以用于不同的传输协议,比如SAP、SIP、HTTP或其他等传输协议。学习时要注意SDP的载体是SIP。RFC 2327专门注明了一些SDP能提供的比较关键的信息:

会话名和目的。

会话激活的时间。

构成会话的媒体。

怎么样接收这些媒体(地址、端口号、格式等)

而另一些信息则是可选附带的,例如会议使用的带宽,负责这个会话的那个人的联系方式等等。

说到这些你可能觉得很抽象,我们赶紧那个例子RFC 2327中的例子来看看:

     v=0
     o=mhandley 2890844526 2890842807 IN IP4 126.16.64.4
     s=SDP Seminar
     i=A Seminar on the session description protocol
     u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
     e=mjh@isi.edu (Mark Handley)
     c=IN IP4 224.2.17.12/127
     t=2873397496 2873404696
     a=recvonly
     m=audio 49170 RTP/AVP 0
     m=video 51372 RTP/AVP 31
     m=application 32416 udp wb
     a=orient:portrait

我们看到SDP格式包含多行文本,都是以 = 的格式书写的,RFC中的星号*指的是选择项。我们主要有三类的会话描述:会话描述、时间描述、媒体描述,具体你可以参看RFC 2327。注意这个例子中,两个m开头的行,定义了音视频的概要,这些概要是在RFC 3550 Real Time Protocol (RTP)中的第13节和RFC 3551 RTP Profile for Audio and Video Conferences with Minimal Control 中的第6节,在编码最后的那个0和31,这是在后续RTP帧中要使用的负载类型值,用来确定媒体和编码类型。49170和51372都是接收者的端口,发送者端口分别加1,也就是说在这个例子中49171和51373是发送者的端口。

4.SIP到底怎么运作?

一个最简单的例子是在SIP呼叫建立两个直接相连的端对端的通话过程。发起者会发起一个INVITE消息给对端来发起会话,接着会收到Ringing和OK消息。被叫端返回ACK表明连接完成,可以进行信息交流了。当不需要这个连接时,任何一端发送BYE消息给对端,对端返回OK来终止呼叫。

注意,SIP消息和具体的媒体流并不是在一个层面运作的。例如,一个VoIP电话是先通过SIP信令完成交互后再开始具体媒体流的传输的,如下图,SIP的根本作用的完成点对点(或多点)的媒体流传输的前序工作。

clip_image010

在RFC 3261中描述了一个比较复杂的例子:使用了代理服务器作为通信通路。SIP代理服务器代表其他的Client发起请求,并且在许多时候作为路由模式,将SIP请求转发给另一个距离最终目的地(也就是被叫端)较近的设备。因此,SIP代理服务器扮演着两个角色——在接收请求时是server角色,在发送请求时是client角色。注意,代理服务器必须可以解释一个SIP消息,并且需要的时候转发这条消息前对其进行重写,大的网络中可能有多个代理服务器。在RFC3261中的第四节中有个比较有趣的例子,描述了两个SIP终端通过两个代理服务器建立呼叫的过程。在这个例子中,两个终端位于两个不同的城市:Atlanta and Biloxi,因此是在两个相互隔离的网络中。每个网络有它自己的代理服务器,分别称为atlanta.combiloxi.com 若在Atlanta的Alice想呼叫在Biloxi的Bob,那么Alice的电话就会发送以下的INVITE消息给它的代理服务器atlanta.com

Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob
From: Alice ;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 142

当这个消息通过网络转到Bob后Bob要是愿意接受这个呼叫那么它就会返回一个OK,这个消息会先到biloxi.com 代理:

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 ;tag=a6c85cf
From: Alice ;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 131

我们注意到有相同的Call-ID来保证这个会话的单一性。更多的细节参看RFC 3261里的这个例子的具体解释。

5.SIP中的信令和媒体之间的关系:

SIP等于为媒体的建立进行实现的沟通,打个比喻,只有你知道你要说话的那个人在那,并且两个人都要找到彼此畅通的语言,这样才能更有效的沟通。

而真正开始两人滔滔不绝的倾心交谈了,就与前边这些对话前的相互了解和基本沟通没有关系了。

clip_image012

6.几个重要的概念:

呼叫(call): 呼叫是一个非正式的术语,用来表示一个多媒体会话,用Call-ID来标识;不论两方通话还是在多方通话中,在每个UA中是使用同一个Call-ID;


事务(transaction) 请求(UAC)+最终响应(相邻的UAS),SIP基于事务。所谓相邻就是说transaction存在于相邻的SIP实体,而不是存在于两个UA之间。CSeq标识。一个事务中包含一个请求消息、0个或多个临时响应消息、1个或多个最终响应消息(2xx~6xx)。SIP是事务性的协议。事务的区分通过Via字段栈顶的Branch的值来确定,这是由于对于请求消息每经过一个有事务状态的Proxy的时候,该Proxy需要为这个事务创建一个服务器端事务和一个客户端事务,并且将自己的URI添加到Via的栈顶,并生成一个Global ID做为Branch的值,以此值来表示一个与之相对应的事务。SIP在事务层面定义了状态机和定时器来实现重传。

下图是一个回复200 OK的成功的INVITE事务:是不是INVITE事务区别在于 UAC需要为每个INVITE最终请求(2xx~6xx)生成ACK响应,而其他的请求消息(INFO,OPTION,etc)则不必如此。因为INVITE的地位比较重要, 所以需要这样一个三次握手的机制来保证会话的双方都能够确保事务的完整性,这一点和TCP连接建立的三次握手比较像。

clip_image014

注意在上图这两个UA中,每一个代理服务器都将自己的地址加入返回的ACK的Via头域中,而非成功的transaction则不会加入,见RFC 3261 (p.24)。CSeq头域的值必须与INVITE相同,并且CSeq的方法必须是ACK。中间响应消息 1xx 的使用则是为了节省网络开销设计的,一旦 UC 收到任何一个中间响应消息,则 UC 必须停止消息重发定时器,不再从发这个请求消息,反之则直到收到最终响应消息或重发定时器超时。一旦客户端UAC的事务在Calling状态收到任何中间响应消息1xx,事务则自动切换到Processing状态,停止请求消息的重发。并且需要将中间响应消息传送给TU事务用户。在呼叫业务中,TU以及上层应用可以根据中间响应消息在用户界面上提示用户。一旦事务切换到Processing状态,任何其他中间响应消息也都要传送给TU。

而非INVITE事务则如下:

clip_image016

当UAC发出非INVITE请求时,它就会在事务管理子层上开启定时器F(TCP)或者是E(UDP),确保超时的时候进行重传。这适用于除了 ACK请求外的其他非INVITE请求。每次超时重传时E的时间都被翻倍,直到最大的4秒。而F超时时,UAC就会认为是Timeout,这个事务将被删除。

对话(dialog/leg): 代表着两个SIP UA之间持续一段时间的端到端的联系(如:一段通话)。也就说仅仅存在于端到端的信令关系。当一个UAS发出对于INVITE(或者REFER)的非失败最终响应<=>200OK(BYE),则Dialog建立,同时这也是session的开始。UA和SIP代理服务器之间不会有对话。在SIP中呼叫中包含一个或多个Dialog(这仅仅存在于多方通话中)。Dialog终结于任意一端发出 BYE。Early Dialog可以通过UAC发出的CANCEL进行终结,更确切的说,所有早期对话在接收到非2XX最终响应时就被终结了。 Call-ID-value、To、From进行标识。Forking时体现明显。

clip_image018

在这个Forking的例子中,这个用户注册了三个设备,在用户被呼叫时,INVITE的Contact头域就被转换为三个INVITE发往三个设备。后边的q指的是优先级,q越小,优先级越高。其中的SIP注册服务器相当于一个Forking代理,尽管这个实体接收到两个ACK,但是除了这些ACK外,它与主叫方的信令交互都是属于一个transaction的,而与被叫方则分别建立了Transaction。另外,被叫方收到的两个ACK由分别建立了Transaction。注意Device3返回了488这样的非成功响应,SIP注册服务器(Forking代理服务器)没有将该响应发回主叫方,这是SIP代理一个重要的特征,SIP代理还能自行发出Request:CANCEL消息。

UAS对话层接收到一个新的对话请求INVITE消息后,在建立会话的响应消息2xx中,将请求消息里面的所有Route-Record字段拷贝到2xx消息中,并且UAS的对话层必须添加一个Contact字段使得对话中后续的响应(INVITE在2xx响应的情况下也包括ACK消息)、请求消息可以直接和本UA联系。当UAC收到UAS的INVITE的2xx响应消息后,如果2xx中不包含任何Route-Record字段的,则UAC可以选择直接发送ACK到Contact中地址&端口。


会话(session) 多方用户的媒体关系,在对话的控制下建立。

下图是Early dialog、Session、Dialog、Transaction等的在一个UA-UA的呼叫中的体现:

clip_image020

在这个例子中,通过INVITE事务而成功建立起来的dialog必须有一个ACK进行回应,这是第二个transaction的开始,尽管ACK并没有回复,但是由于新的 branch-value被填入,所以这个ACK代表了一个新的Transaction的开始。注意,此时 transaction number (CSeq) 并没有根据INVITE而增加--也就是说若收到的最终响应不是2XX(是3XX--6XX),则该transaction中包含ACK,若最终响应是2XX,则ACK属于一个新的transaction(此处存疑,国外有资料将其视为一个新的transaction,但是RFC3261中的意思却是ACK不属于INVITE Transaction,也不创建新的Transaction,但会重新计算Transaction参数--branchID)。早期对话是UAS以一个1XX响应作为回应时建立的。这样做的好处是在UAC可能在早期对话中发出诸如UPDATE这样的SIP请求。

7.在线状态(Presence

有人译为“呈现”,个人觉得译为在线状态比较贴切,这是一种激动人心的SIP应用,它使您能够确定用户位置,并判断是否能够通过电话、电子邮件/文本或视频与其进行通信。人员和应用都可以利用状态信息,从而使企业有机会将通信整合到业务流程之中。IETF指定了许许多多的SIP扩展来支持在线状态这个功能,我们列举如下:

· RFC 2778: A Model for Presence and Instant Messaging

· RFC 2779: Instant Messaging/Presence Protocol Requirements

· RFC 3261 SIP: Session Initiation Protocol

· RFC 3856: A Presence Event Package for the Session Initiation Protocol

· RFC 3859: Common Profile for Presence

主要的组成有:

Presence Agent(PA):PA为SIP使用者的代理人,能够接收和处理Presence的消息。它也能够回应和重新整理其它的消息(如公开的消息或SIP以外的任何消息)。当一个用户改变其状态时,它还能给订阅者发送通知。其可以与 SIP proxy server放在一起实现,也可以作为一个独立实体存在。

Presence User Agent (PUA) :查询更新PA。

8.全网看SIP

在非IMS网络中,拓扑结构如下:

clip_image022

在这个结构中,有三个主要的部分:

公网与业务定制者节点:这是PSTN网络以及在用户层面的设备。

DMZ区域:对接外网的一些网络元素,用于安全方面。

核心网:网络消息处理的核心区域。

需要的注意是:

1.在核心网部分的媒体服务器有时候也可以扮演UA的角色,比如你定制语音留言这个业务,那么这个媒体服务器就负责播放提示音和录音。网关在某个层面上也是扮演了UA的角色。

2.IP PBX是一种B2BUA,另外,SBC也是一种B2BUA,负责隐藏内网拓扑结构。应用服务器也是一种B2BUA,供修改业务参数等操作使用。

9.NAT问题

下图所示SIP可能会出现的NAT问题:

clip_image023

目前商用的方法是使用Session Border Controller (SBC),也就是说在应用层提供NAT服务,SBC监听SIP请求,当得到一个请求时,它不仅检查IP头以便路由这个包,它也查看SIP消息内部的contract地址,并且在将其路由到下一跳之前将该地址改为一个可路由的地址,这个可路由的地址不一定是公网地址,只要下一个节点可以路由即可,如下图所示:

clip_image024

posted @ 2012-01-16 15:18  gnuhpc  阅读(4642)  评论(0编辑  收藏  举报