SIP协议


sip(Session Initiation Protocol)是P2P通信标准协议之一,SIP是属于应用层的控制协议,主要用于在一个或多个参与者之间创建、修改和中止会话(sessions)。会话的类型包括IP电话,多媒体流分发和多媒体会议等。SIP协议凭借其简单、易于扩展、便于实现等诸多优点越来越得到业界的青睐,它正逐步成为NGN(下一代网络)和3G多媒体子系统域中的重要协议,并且市场上出现越来越多的支持SIP的客户端软件和智能多媒体终端,以及用SIP协议实现的服务器和软交换设备。

SIP简介

SIP邀请(invitations)用于创建携带会话描述(如SDP信息)的会话,允许参与者使用一系列兼容的媒体类型.
SIP使用一种叫代理服务器的元素来帮助对用户当前位置进行转发,对用户进行验证和授权,并为用户提供相应的功能.
SIP同时也提供了注册函数以允许用户上传他们的当前地址供代理服务器使用.SIP协议运行在多个不同的传输协议之上.

SIP支持5个方面来建立和中止多媒体会话:

  • 用户地址(User location): 决定了用来通讯的终端系统.
  • 用户状态(User availability): 决定了被呼叫端的是否愿意加入通讯.
  • 用户性能(User capabilities): 决定了多媒体类型和媒体使用的参数.
  • 会话建立(Session setup): "响铃",在呼叫端和被呼叫端建立起会话.
  • 会话管理(Session management): 包括传输和中止会话,修改会话参数以及调用服务.

SIP不是一个垂直集成的通讯系统,而是作为一个组件与其他协议共同运作,如RTP等实时传输协议等.另外SIP不提供服务,
只提供可以用来实现各种服务的原语.比如,SIP可以定位用户并且传输一个不透明的对象到其当前地址.如果这个原语用来
传输SDP,终端就能得知会话的一些参数;如果同样的原语用来传输一张照片,那也可以实现一种"显示来电者头像"的服务.
由此可见,一种原语通常用来实现多种不同的服务.

SIP工作过程

下图描述了SIP的基本功能:定位一个终端,产生通讯请求,建立会话以及结束会话.

                 atlanta.com  . . . biloxi.com
             .      proxy              proxy     .
           .                                       .
   Alice's  . . . . . . . . . . . . . . . . . . . .  Bob's
  softphone                                        SIP Phone
     |                |                |                |
     |    INVITE F1   |                |                |
     |--------------->|    INVITE F2   |                |
     |  100 Trying F3 |--------------->|    INVITE F4   |
     |<---------------|  100 Trying F5 |--------------->|
     |                |<-------------- | 180 Ringing F6 |
     |                | 180 Ringing F7 |<---------------|
     | 180 Ringing F8 |<---------------|     200 OK F9  |
     |<---------------|    200 OK F10  |<---------------|
     |    200 OK F11  |<---------------|                |
     |<---------------|                |                |
     |                       ACK F12                    |
     |------------------------------------------------->|
     |                   Media Session                  |
     |<================================================>|
     |                       BYE F13                    |
     |<-------------------------------------------------|
     |                     200 OK F14                   |
     |------------------------------------------------->|
     |                                                  |

                     图 1: SIP会话建立

图中描述了两个用户Alice和Bob交换SIP信息的过程.(信息表示为Fn.) 首先,Alice在其PC上使用了SIP终端(假设是软件电话),
并且通过互联网打给Bob. 其中我们看到有两个代理服务器atlanta和biloxi,用来帮助双方进行会话建立.这个典型的排列经常
被称为SIP之梯(SIP trapezoid).

Alice呼叫Bob时,使用的是Bob的SIP身份信息,一种特定类型URI称为SIP URI,形式和E-mail地址类似,包含了用户名和主机名.
在本例中,Bob的地址为sip:bob@biloxi.com,biloxi是Bob的SIP服务提供商;同样,Bob联系Alice时也通过其SIP地址sip:alice@atlanta.com
来进行通信. SIP同样提供了安全的链接SIPS,和HTTPS类似,主要通过TLS进行内容加密, 加密的地址格式为sips:alice@atlanta.com

SIP基于一种类HTTP的请求/响应传输模型.每次传输包含一个调用了特定方法或函数的请求,以及至少一个响应.在本例中,
传输开始时Alice发送了一个INVITE请求到Bob的SIP URI. INVITE请求包含一系列头部(header)字段.头部字段被称为属性,
提供了关于报文的额外信息. 产生INVITE请求的终端包含了一个独特的通话标识符,目的地址,Alice的地址以及Alice
希望与Bob建立的会话的类型信息. 一个INVITE请求的例子如下,其中Alice的SDP信息没有显示出来:

  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

  (Alice的SDP信息,略)

                     图 2: Alice发送的请求报文

其中第一行包含了方法的名字(INVITE).后面的一些行则是一系列头部区段,各个头部字段的含义在下一节会说到.

由于Alice不知道Bob的准确地址,因此报文会先发送到Alice的SIP服务提供商,atlanta.com. 这个地址是可以在Alice
的终端(软件电话)上面进行配置的,当然也可以通过DHCP之类的协议来发现. SIP服务器接收SIP请求并按照其目的
进行转发. 在本例中, 代理服务器接收INVITE请求后,给Alice返回100(Trying)响应,表示请求正在进行转发.
SIP响应用一个三位数来表示状态,包含了和INVITE请求中同样的To, From, Call-ID, CSeq 和 branch(via内)参数,
从而允许Alice的终端将其与请求相联系. 代理服务器atlanta.com通过DNS等方法得到Bob的服务提供商地址.
并且在转发的报文中的via字段加上自己的地址信息. biloxi.com代理服务器接收到INVITE请求,并且返回100响应给
atlanta.com. 代理服务器查找其数据库(通常称为定位服务),其中包含了Bob的当前IP地址. 同时代理在转发请求前
也在头部的via字段加上自己的地址.

Bob的终端(SIP电话)接收到INVITE请求后,会提示Bob这是来自Alice的来电.同时Bob的终端返回180响应,
表示正在呼叫,响应一直转发回到Alice的终端,从而使Alice也能知道对方电话正在响.每个代理都通过头部的Via
字段来决定响应的发送方向,并且从via顶部去掉自己的地址信息. 因此虽然发送请求的时候用到DNS和定位服务,
但是发送响应的时候则不需要.

在本例中,Bob决定接起电话. 此时Bob的SIP电话发送200响应表示呼叫被应答.200响应包含了信息体(SDP)
表明Bob希望建立的会话类型.因此,这形成了两次SDP信息交换过程:Alice发送给Bob,然后Bob发送给Alice.
这个两次交换提供了基本的协商能力,并且基于简单的offer/answer模型. 如果Bob
不想接电话或者正在与别人通话,就会返回一个错误响应,从而不建立多媒体会话. Bob发送的200响应结构大体如下:

  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
  
  (Bob的SDP信息,略)

                     图 3: Bob发送的响应报文

Bob的SIP电话增加了一个tag参数到报文头部,这个tag会被两个端点合并到对话里,并且会在(本次通话)所有以后的请求和响应中包含.
Contact头包含了一个Bob能直接连接的URI,Content-Type 和 Content-Length表示消息体(没贴出来)的格式信息.
在本例中,代理服务器也可以拓展自己的功能,比如当接收到Bob返回的486(Busy Here)响应,则可以向Bob的语音信箱等
发送INVITE请求;一个代理服务器可以同时向多个地址发送请求,这种并行查找的特性通常称之为分叉(forking).

在200(OK)响应返回到Alice的软件电话上之后,电话停止响铃,并通知Alice对方已经接听,同时发送一个ACK报文到Bob
的终端,表示响应已经收到. 在本例中,ACK直接发送给Bob,而不通过两个代理服务器,是因为两个端点都知道了对方的地址,
因此不需要再通过代理去查找.

收到ACK之后,Alice和Bob就可以互相通信了. 通信完成之后,假设Bob先挂断电话,并产生一个BYE报文,直接发送给Alice,
Alice收到后确认请求,并返回200(OK)响应,从而结束此次会话.注意这里没有发送ACK,因为ACK只有在确认INVITE请求的响应时才发送.

注册(Registration)是另一个SIP常用的操作. 用户通过注册使得代理服务器能知道其当前的地址信息. 例如Bob
可以在初始化时,向biloxi.com发送注册请求(REGISTER),后者也称为注册商(registrar).
注册商会将Bob的SIP URI和其当前地址相关联起来(通常称为绑定),并把这个映射信息存储到服务器端的数据库中,
亦即上文说到的定位服务. 通常注册服务器和对应域名的代理服务器都是同一地址的,因此要知道SIP服务器的类型的
区别体现在逻辑上而不是物理上.

SIP协议结构

SIP是一个分层的协议,这意味着其行为由一系列同级但独立的段(stage)描述. SIP的最底层为语法和编码,其中编码由
BNF语法(Backus-Naur Form grammar)指定; SIP第二层为为运输层(transport layer),定义了客户端和服务端如何发送和接收
请求和响应;第三层为事务层(transaction layer),事务层是SIP的基础组件,一次事务包括发送的请求和对应的响应,
事务层处理应用层的重传,请求/响应匹配和超时等;事务层之上称为事务用户(TU, transaction user),每个SIP
实体(除了无状态的代理),都是一个TU.

所有的SIP元素,包括用户客户端(UAC),服务器(UAS),无状态(stateless)或者全状态(stateful)的代理,
以及注册商,都包含一个区分彼此的内核(core). 其中除了无状态的代理,其他元素的内核都是事务用户.
UAC和UAS的内核行为依赖于方法,对于所有方法有一些通用规则,这里不细说. 对于UAC而言,这些规则支配
着请求报文的构造.

SIP报文格式

SIP是基于文本(text-based)的协议,并且使用UTF-8字符集.一条SIP报文要么是从客户端到服务端的请求,
要么是服务端到客户端的响应;两种类型的报文都包含一个起始行,一个或者多个头部区域,一个表示头部结束的空行,
以及(可选的)正文部分(message body),每个部分以CRLF隔开:

     generic-message  =  start-line
                         *message-header
                         CRLF
                         [ message-body ]
     start-line       =  Request-Line / Status-Line

除了字符集的区别,大多数SIP的报文和头部语法都与HTTP/1.1相同,虽然如此,但SIP不是HTTP协议的拓展.

SIP Request

SIP请求的报文首行都包含一个请求行(Request-Line),请求行又包括方法名,请求URI以及协议版本,
并以SP(空格)分割除了在行尾,请求行不允许出现任何回车(CR)和换行(LF),元素中也不能出现行间的空字符(LWS, linear whitespace).

  Request-Line  =  Method SP Request-URI SP SIP-Version CRLF

其中:

  • Method: 表示方法,RFC3261定义了六个方法,分别是:
    • REGISTER: 用来注册联系人信息.
    • INVITE, ACK, CANCEL, BYE: 这四个方法用于会话的建立.
    • OPTIONS: 用来发现服务器的性能(capabilities).
  • Request-URI: 即SIP或者SIPS URI,用来表示请求要送往的服务或用户信息,其中不能包括控制字符,
    也不能包含在"<>"之中.
  • SIP-Version: SIP的版本号,与RFC3261对应的是"SIP/2.0".和HTTP/1.1的处理类似,但不同点为SIP处理
    版本号是以字符串的格式,虽然这在实践中并没什么太大关系.

SIP Response

SIP响应与请求不同,其起始行为状态行(Status-Line),状态行包括协议版本,状态码以及对应的状态文字说明,
和请求行类似,个元素以空格分隔,中间也不能出现换行和回车.

Status-Line  =  SIP-Version SP Status-Code SP Reason-Phrase CRLF

状态码(Status-Code)由3位数字组成,表示请求的结果. 状态码的第一位表示响应的种类:

  • 1xx(表示100-199,下同): 临时响应(Provisional),表示请求已经被收到,但还在处理之中.
  • 2xx: 成功(Success), 请求被成功接收,理解以及被接受.
  • 3xx: 重定向(Redirection), 可能需要重新选择发送地址以完成请求.
  • 4xx: 客户端错误(Client Error), 请求包含错误的语法,或者不能被服务器完成.
  • 5xx: 服务端错误(Server Error), 服务器处理一个合法的请求失败.
  • 6xx: 失败(Global Failure),

Header Fields

SIP报文的头部和HTTP的头类似, 也有同样的性质,如在多个头部区域指定同一个属性的值时可以合并成一个头部,
并使field-value以逗号分隔等,头部的格式如下:

  field-name: field-value

冒号两边可以加任意空格,但是一般不建议这样做,而是使filed-name和冒号间不留空格,并使冒号和field-value只见留一个空格.
以图2中Alice的Request请求报文为例,大致介绍其中一些常见的Header field-name:

  • Via: 包含了发送方想接受此次请求对应响应的地址,这里是pc33.atlanta.com,
    并且还包含了识别此次传输事务的分支参数(branch parameter).
  • Max-Forwards: 用来限制请求的最大跳数(max hops),在每个hop之后递减少.
  • To: 包含了此次请求的目的用户的显示姓名Bob(display name)以及SIP/SIPS URI(P2P通信标准协议(三)之ICE.

 

1、SIP业务基本知识

1.1 业务介绍

会话初始协议(Session Initiation Protocol)是一种信令协议,用于初始、管理和终止网络中的语音和视频会话,具体地说就是用来生成、修改和终结一个或多个参与者之间的会话。SIP的业务模式是一个点对点协议,其中有两个要素——SIP用户代理和SIP网络服务器。用户代理是呼叫的终端系统元素,而SIP服务器是处理与多个呼叫相关联信令的网络设备。用户代理本身具有一客户机元素(用户代理客户机UAC)和一服务器元素(用户代理服务器UAS)。客户机元素初始呼叫而服务器元素应答呼叫。这允许点到点的呼叫通过客户机-服务器协议来完成。下图是SIP业务的网络结构和各个参与者的关系。

wps_clip_image-377

SIP业务的核心特点集中在SIP的设计目标之一是提供类似公用交换电话网(PSTN)中呼叫处理功能的扩展集。在这个扩展集中,实现类似日常电话的操作:拨号,振铃,回铃音或者忙音,只是实现方式和术语有所不同。SIP也实现了许多信令系统7(SS7)中更高级的呼叫处理功能,尽管这两个协议相差很远。SS7是一个高度集中处理的协议,其特点表现为高复杂度的中心网络结构和无智能的哑终端(传统的电话机)。SIP则是一个点对点协议,所以它只需要一个相对简单的(因此也高度可扩展的)核心网络,而将处理工作下放给连接在网络边缘的智能端点(装有硬件或软件的终端设备)。SIP的许多功能在端点中实现,这与传统的SS7将其在网络核心设备实现的作法大异其趣。而协议的其他特点还有它是一个文本协议,所以易于调测,结构灵活;而且它是一个中性的底层传输协议,可用TCP或UDP(推荐UDP);同时呼叫和媒体信息同时传送:媒体信息的传送由SDP传送

SIP是互联网工程任务组(IETF)多媒体数据和控制体系结构的一个组成部分,因此它与IETF的许多其他协议都有联系,例如RTP(实时传输协议)和SDP协议。SIP与许多其它的协议协同工作,仅仅涉及通信会话的信令部分(control message)。SIP报文内容传送会话描述协议(SDP),SDP协议描述了会话所使用流媒体细节,如:使用哪个IP端口,采用哪种编解码器等等。SIP的一个典型用途是:SIP“会话”传输一些简单的经过封包的实时传输协议流。RTP本身才是语音或视频的载体。

1.2 业务过程和协议流程

wps_clip_image-6413

以上是INVITE包。我们可以看到在发起呼叫初期,终端向825002发出Invite的呼叫请求。

wps_clip_image-6465

以上是Trying包,说明终端825003正在试着连通服务器,进一步转接到825002.

由于设置了自动接听,所以此次通话没有振铃的包。

wps_clip_image-6538

这是ACK包,代表确认信号。

wps_clip_image-6566

以上是BYE包。这是825002挂断后服务器向825003发送的释放呼叫信号。

SIP包的分析


1.SIP协议:
Session Initiation(会话初始协议),允许使用Internet端点(用户代理)来寻找参与者并且允许建立一个可共享的会话描述。SIP允许创建基础的 networkhosts(叫做代理服务器),并且允许终端用户注册上去,发出会话邀请,或者发出其他请求。可以用来创建,修改和终止会话,它独立运作于通讯协议之下,并且
不依赖建立的会话类型。
SIP不是一个垂直集成的通讯系统。SIP可能叫做是一个部件更合适,SIP应该和其他的协议一起工作,才能提供完整的对终端用户的服务。虽然基本的 SIP协议的功能组件并不依赖于这些协议。
SIP本身并不提供服务。但是,SIP提供了一个基础,可以用来实现不同的服务。

2.SIP实施
每个SIP端点都有个用户名,也即是表示其身份的ID号,通过其ID,可以呼叫对方.比如,在IP电话A中,可以用这个ID来表示对方装置:sip: 0502004@192.168.2.30.前面表示电话号码,后是其IP地址.
当然,以上ID的形式只是一种彼此规定的代号而已,完全可以用shi@web.com来表
示其ID.

SIP是基于一个类似HTTP协议的请求应答的通讯模式。每一个通讯都包含对某个功
能的请求,并且起码需要一个应答。
比如,IP电话A在注册SIP服务器的过程中,就需要一个请求:Request: Register
192.168.2.13 (电话A->服务器)
而SIP服务器则必须给一个应答:Status: 200 OK (服务器->电话A)
又比如,电话A如欲与电话B通话,则首先,电话A给SIP服务器一请求,请求服务器帮它接上电话B,则这时候又需要一个请求.
如:Request: INVITE sip :0502004@192.168.2.13 (电话A->服务器)
服务器又必须给其一个应答:Status: 100 Trying .(服务器->电话A) 表示服务
器正在尽百分之百的力量帮它联系上.
这时候,服务器找到电话B,就给电话B一个请求,告诉它,有人想找你.你有空吗?
Request:INVITE sip: 015B0081587310007000D0000C578@192.168.2.40 (服务器
->电话B)
这时候,如果电话B恰巧有空(非通话断线状态),则会答服务器,说,空!请你
去叫一下他到我这儿来吧!
电话B会给出两条应答给服务器:Status: 100 Trying /Status: 180 Ring
服务器收到应答后,再给电话A发发送一个应答.Status: 180 Ring ,这时候电话A
的状态就表示响铃.
当电话A一摘机,则电话A和电话B就有个通话,此时,电话B给服务器一个条应答,
让他传到到电话A.
Status:200 OK
此时通话建立的所有准备工作完成,这时就只剩下RTP语音包在两个电话之间传
输,当然,SIP包还会时不时的出来调解一下,看看有没有异常状态.
最后一方挂断,则服务器又出作调停工作,发送一个请求给另一方:
Request:BYE sip: 015B0081587310007000D0000C578@192.168.2.40
而另一方则回一个应答:Status: 200 OK
通话完成!

这些SIP消息都是附在UDP包中完成传输的,通过ethereal截包工具,可以详细的看到其状态.
以下是一个请求连接的SIP包的图例:



可以看到,SIP包有三个主要部分:Request-Line(表示是请求信息),Message Header(SIP包的消息头哉),Message Body(SIP包的消息主体).

其中有几个要注意的: VIA域告诉大家本请求发送到哪里并且应答到哪里,Contract域告诉大家将来的请求将发送到哪里. To和From分别表示这个包下一站到哪个主机上面,来自哪里。
  CALL-ID包含一个全局的唯一标志,用来唯一标志这个呼叫,通过随机字串和softphone的自己名字或者IP抵制混和产生的。
   通过TO TAG, FROM TAG和CALL-ID完整定义了两端之间的端到端的SIP关系,并且表示这个是一个对话性质的关系。

至于消息的主体。则会描述媒体的类型,codec,或者采样速率。




3.一个具体的在正式通话前两个电话所发出的SIP包。
  ethereal截图: