使用OpenSER构建电话通信系统BuildingTelephonySystemswithOpenSER(翻译人:老黑转载地址:)第一章:SIP介绍(IntroductiontoSIP)会话初始化协议是互联网工程任务组(IETF)制定的协议标准,在多个RFC(RequestforComments)文档中被进行了描述说明。RFC3261是最近的一个RFC,一般称它为SIP版本2。SIP是一个应用层的协议,用来建立,修改,终止会话(sessions)或是多媒体通话(multimediacalls)。这些会话可以会议(conferences),e-learning,网络电话和一些相似的应用。它是同HTTP协议相类似的文本协议并且被设计用来发起,保持,关闭用户之间的交互会话。目前SIP已经是VoIP领域被广泛使用的协议之一了,市场上几乎每一台IP电话都会支持它。本章结束的时候你将能够:描述SIP是什么描述SIP是干什么的描述SIP的框架解释SIP主要部件的意义理解并比较主要SIP消息描述INVITE和REGISTER请求消息头部的处理过程在建立和关闭多媒体通话的过程中,SIP协议支持五种要素。用户定位(Userlocation)用户参数协商(Userparametersnegotiation)用户可用性(Useravailability)通话建立(Callestablishment)通话管理(Callmanagement)SIP协议被设计成多媒体框架的一部分,而这种多媒体框架包括RVSP,RTP,RTSP还有SDP等其他协议。然而,SIP却并不依靠其他这些协议工作。SIP基础(SIPBasics)SIP在工作的方式上与HTTP协议相类似。SIP的地址像是e-mail的地址。SIP代理中使用的一个比较有趣的特性就是“别名(alias)”,也就是说你可以有多个SIP地址,譬如:johndoe@sipA.com+554845678901@sipA.com45678901@sipA.com在SIP的体系结构中,有多个用户代理和提供不同服务的服务器。SIP使用点对点(peer-to-peer)的分布模型来和服务器进行消息的交互。服务器只进行消息(signaling)的处理,而用户代理的客户端和服务端既可以处理消息也可以处理媒体。下面的图描述了这样的一个体系:在SIP模型中,用户代理,通常是一台SIP话机与它的SIP代理进行交互,从上图可以看到,外呼代理(outgoingproxy)将使用INVITE消息向外发出通话请求。外呼代理将观察这通通话是否是被定向到外部的域名。然后它将向DNS服务器发出请求将目标域名解析为对应的IP地址。然后再将通话请求发送给DomainB对应的SIP代理。呼入代理(incomingproxy)将在地址列表(locationtable)中查询agentB的IP地址。如果在地址列表这个地址与之前在注册过程中的IP地址对应,那么呼入代理就可以定位这个地址了。现在就可以使用这个地址将通话请求发送到agentB了。agentB收到这个SIP消息后(INVITE),就拥有了可以与agentA建立RTP会话(通常是音频方面的会话)所需要的信息。使用BYE消息可以终止这个会话。SIP代理在VoIP提供者里的作用/上下文(SIPProxyintheContextofaVoIPProvider)通常VoIP服务的提供者们并不会实现像上幅图那样的纯粹的SIP四边形结构,他们不会允许你向一个外部的域名发送通话请求,因为如果这样,那么将影响他们的收入(revenuestream)。取而代之的是一个接近三角形的SIP网络结构。(如下图所示)SIP工作原理(SIPOperationTheory)在上图中,你可以看到SIP体系结构中的主要的构成部件。所有的SIP消息都会经过SIP代理服务器。另一方面,由RTP协议承载的媒体流则是从一端直接流向另一端。我们将在下面的列表中简要的对其中的一些构成部件进行解释。用户代理客户端(UACuseragentclient)——发起SIP消息的客户端或终端用户代理服务端(UASuseragentserver)——对接收到的从用户代理客户端发起的SIP消息进行相应的服务端。用户代理(UAuseragent)——SIP终端(IP电话,电话适配器(ATA),软电话(softphone))代理服务器(ProxyServer)——从用户代理接收请求,并且如果指定的被请求的终端不在其域中时,会将请求发送给另外的SIP代理。重定向服务器(RedirectServer)——接收请求,但是不直接发送给被叫用户,而是向主叫方发送目的地址的信息。定位服务器(LocationServer)——向代理服务器和重定向服务器提供被叫者的联系地址。通常,物理上,代理服务器,重定向服务器和定位服务器存在于同一台电脑和软件中。SIP注册过程(SIPRegistrationProcess)SIP协议中使用了一个构件叫做注册服务器。它不仅能够接收REGISTER消息请求,还能够将收到的消息包中的信息保存到管理对应域名的定位服务器上面。SIP协议具有发现能力;换句话说,就是如果一个用户要与另外一个用户开始会话,那么SIP协议必须要发现这个用户能够到达的主机存在。由于定位服务器可以收到请求消息并找到向什么地方发送,所以这个发现过程由定位服务器来完成。而这则是基于管理每个域的定位服务器维护着一个定位数据库的事实来实现的。注册服务器不仅可以接收客户端的IP地址,还能够接收其他类型的消息。比如,能够收到服务器上面的CPL(CallProcessingLanguage)脚本。在一台话机能够接收一通通话之前,它需要在定位数据库中有注册信息。在这个数据库中我们要拥有所有电话的各自的相关的IP地址。在我们的例子中,你将看到SIP用户8590@voffice.com.br注册到200.180.1.1上面的过程。RFC3665定义实现了一个最小的功能集合,这是使得SIP进行IP网络交互时的最好实践。下面的图就是根据RFC3665中的描述所画出的注册事务处理流程。按照rfc3665中所说,与注册一个用户代理的过程相关的有五个基本的流程,如下所述:1.一个新的成功的注册(Asuccessfulnewregistration)——用户代理在发送Register请求后,将收到认证过程的挑战。我们将在阐述验证过程的章节中看到这个过程的细节。2.联系列表的更新(Anupdateofthecontactlist)——由于不再是新的注册,消息中已经包含了摘要(digest),那么不会返回401消息。为了改变联系列表,用户代理仅仅需要发送一条在CONTACT头中带有新的联系信息的注册信息即可。3.请求获得当前的联系列表——在这种情况下,用户代理将把发送消息中的CONTACT头置空,表明用户希望向服务器询问当前的联系列表。在回复的200OK消息中,SIP服务器将把当前的联系列表放在其CONTACT的头中。4.取消注册(Cancellationofaregistration)——用户代理在发送的消息中将EXPIRES头置成0,并且将CONTACT头设置为“*”表示将此过程应用到所有存在的联系信息。5.不成功的注册(UnsuccessfulRegistration)——用户代理客户端(UAC)发送一条Register请求消息,收到一条“401Unauthorized”消息,事实上,这个过程同成功注册过程相同。但是接下来,它进行哈希运算尝试进行认证。而服务器检测到的是一个无效的密码,继续发送“401Unauthorized”消息。这个过程一直重复直到重复次数超过在UAC设置的最大值。作为SIP代理运转的服务器(ServerOperatingasaSIPProxy)在SIP代理模式下,所有的IP消息都要经过SIP代理。这种行为在向诸如计费(billing)的过程中帮助很大,而且迄今为止,这也是一种最普遍的选择。但是它的缺点就是在会话建立过程中的所有的SIP交互中,服务器造成的额外开销也是客观的。要记住的是,即使服务器作为SIP代理在工作时,RTP包也总是直接从一端传送到另一端,而不会经过服务器。作为SIP重定向运转的服务器(ServerOperatingasaSIPRedirect)SIP代理可以运行在SIP重定向模式。在这种模式下,SIP服务器的处理量是相当巨大的,因为它不需要保持事务处理的状态。在对INVITE消息进行初始化后,仅仅向UAC回复一条“302MovedTemporarily”消息就可以离开SIP对话(dialog)了。在这种模式下的SIP代理,即使只是利用非常少的资源也可以每小时传送上百万的通话。当你需要的规模很大并且不需要对通话计费的情况下,这种模式通常会被使用。基本消息(BasicMessages)在SIP环境中会被发送的基本的消息有:大多数时间内,你会使用到REGISTER,INVITE,BYE还有CANCEL。而另外一些消息会被用在其他的特性当中。举例来说,INFO被用在DTMFrelay和通话中消息信息(mid-callsignalinginformation)。PUBLISH,NOTIFY和SUBSCRIBE则用来支持列席系统(presencesystems)。REFER用来进行通话转接(calltransfer)而MESSAGE则应用于一些聊天应用程序中。更新的消息也会随着协议标准化进程而随之出现。像HTTP协议一样,这些消息的响应也会以文本形式出现。其中一些最终的响应消息被列在下图当中:SIP对话流程(SIPDialogFlow)这一节将通过一个简单的例子来介绍一些基本的SIP操作。先让我们来诊视下图展示的两个用户代理之间的消息顺序。你可以看到伴随这RFC3665描述的会话建立过程还有几个其它的流程。我们在这些消息上标上了序号。在这个例子中用户A使用IP电话向网络上的另外一台IP电话发出通话请求。为了完成通话,使用了两个SIP代理。用户A使用称为SIPURI的SIP标识向用户发出通话。URI就像是一个电子邮件地址,比如sip:userA@sip.com。一种可靠安全的SIPURI也可以被使用,譬如sips:userA@sip.com。使用SIPS建立的通话将会在主叫和被叫之间使用安全可靠的传输机制(TLS-TransportLayerSecurity)事务(transaction)的建立始于用户A向用户B发送INVITE请求消息。INVITE请求中包含一些特定头域。这些头域被称之为属性,为消息提供了额外的一些信息。包括唯一的标识,目的地,还有关于会话(session)的信息。第一行是消息的方法名(themethodname)。接下来是列出的头域。这个例子包含了所需要的头的最小集合。我们将在下面简要的描述这些头域。VIA:它包含了用户A等待发出请求对应响应的所在地址。还包含了一个叫做“branch”的参数,这个参数用来唯一的标识这个事务(transaction)。VIA头将最近从“SIP跳”(SIPhop)定义为IP,传输,和指定事务参数(TheVIAheaderdefinesthelastSIPhopasIP,transport,andtransaction-specificparameters)。VIA专门用来路由响应消息。请求经过的每一个代理都会增加一个VIA头。而对于响应消息而言,相对于再次向定位服务器或是DNS服务器进行定位请求,使用VIA头进行路由将更加容易。TO:它包含了名字(显示名(displayname))和最初选择的目的地的SIPURI(这里是sip:userB@sip.com)。TO头域不被用来路由消息包。FROM:它包含了名字和表明主叫ID(callerID)的SIPURI(这里是sip:userA@si