1、SIP协议简单介绍:
一、SIP基本概念
1.1 定义
SIP(Session Initiation Protocol,会话发起协议)是由IETF(Internet工程任务组) 提出的IP电话信令协议, 是采用UTF-8字符集来进行编码的文本协议。
SIP是一种通信协议,定义了如何在通信设备(计算机,电话,手机,PDA等)之间相互连接和信息交换。
SIP是一种信令控制协议,可以配置和管理任何类型的 peer-to-peer 通信会话, 但并不关心媒体类型 (语音、短信、游戏、视频等)。
1.2 SIP实体
SIP协议定义了多个实体,理解它们在使用SIP协议的体系结构中所起的不同作用是至关重要的。
1.2.1 用户代理
用户代理(UA,User Agent)表示一个终端系统。它可以是SIP电话机或者电脑上的SIP软终端。它包括两部分,用户代理客户端(UAC,User Agent Client)和用户代理服务器端(UAS,User Agent Server),前者产生请求,后者产生对应的响应。
UAC和UAS是逻辑上的两个部分,每个终端系统都包含了UAC和UAS的功能。
图1.2.1 一个简单的SIP呼叫的例子
如图1.2.1所示,Tesla发起INVITE(请求),Marconi接收INVITE请求,因此,此时Tesla就是用户代理客户端 (UAC),Marconi是用户代理服务器端(UAS);会话建立后,Marconi发起BYE(结束)请求,Tesla发送对应的响应,因此,此时 Marconi就是用户代理客户端(UAC),Tesla是用户代理服务器端(UAS)。
1.2.2代理服务器
代理服务器(Proxy)是将请求消息路由到UAS以及将相应消息路由到 UAC的实体。一个请求消息在到达UAS之前可能要经过若干个代理服务器的转发,每个代理服务器都要进行路由决策,并在将请求信息转发到下一个实体之前对 其进行修改。响应消息将遍历请求信息所经的那些服务器,但顺序却完全相反。
代理服务器是一个逻辑SIP实体。当一个请求消息到来时,一个能作为代理服务器的SIP实体首先决定是否需要由自己来应答这个请求,例如请求消息中 可能有格式错误,或者在执行代理功能之前需要先获得客户端的鉴权证书等,而该实体亦可用任何适当的错误码来响应。SIP实体直接应答一个请求时,它承担的 角色就是UAS。
按照工作模式,代理服务器分为有状态代理服务器(Stateful Proxy)和无状态代理服务器(Stateless Proxy)两种类型(《SIP揭密》中分得更细,分为保留呼叫状态PROXY,保留状态PROXY和无状态PROXY)。
无状态代理服务器只是作为一个简单的消息转发实体,它根据请求消息来做转发目的地和路由决策,然后把请求转发到下游的某个实体;对于响应消息,则只简单地将其往上游方向转发。一旦消息转发完毕,无状态代理服务器将丢弃所有与此消息相关的信息。
有状态代理服务器会记住它所收到的每个请求的信息,如事务状态,以及作为某一请求的处理结果而发送的任何请求的信息。这些信息将影响它对后续的、与先前接收的某一请求相关的信息的处理。
1.2.3重定向服务器
重定向服务器(Redirect Server)是一个SIP实体,它接受用户代理或代理服务器的请求,对这些请求发送3xx(重定向响应)响应,响应消息中包含了请求的目标用户的可能地址的列表,以便用户代理或代理服务器重新发送请求消息。
1.2.4注册服务器
注册服务器(Registrar Server)是一个接收注册的SIP服务器,用以进行管理以及特定的服务。一个注册服务器通常伴同一个重定向服务器或者一个代理服务器同时出现。
1.2.5定位服务器
定位服务器(Location Server)不是SIP实体,但是它们是任何实用SIP协议的体系结构中非常重要的一部分。位置服务器存储并且向用户返回可能的位置信息。它可以利用从 注册服务器或者其他数据库得来的信息。大部分的注册服务器接收到位置信息时即刻将这些信息上载到定位服务器。但是,在定位服务器和SIP服务器之间并不实 用SIP协议。一些定位服务器实用轻量目录访问协议(LDAP,Lightweight Directory Access Protocol)[RFC1777]和SIP服务器进行通信。
1.3 SIP方法(method)
在SIP的REQUEST中,核心的方法(method)定义了6种:INVITE、ACK、BYE、CANCEL、OPTIONS和REGISTER。
INVITE消息用于发起一个新的会话;
ACK消息用于完成会话的建立;
BYE消息用于结束一个会话;
CANCEL消息用于取消一个请求(一般是针对INVITE);
OPTIONS消息用于查询服务器的能力;
REGISTER消息用于发送注册请求消息。
除了以上方法以外,还有其他扩展的方法,如INFO、NOTIFY等等。
1.4 SIP响应
响应消息的起始行为状态行(Status-Line),状态行由协议版本、状态码和状态原因短语组成,各个部分之间用一个空格字符进行分隔。下面介绍其中的状态码。
SIP协议中共定义了6类状态码,其中状态码的第1位数字用于指示响应类型,后两位数字表示具体响应。下面用“1xx”标识状态码为“100-199”之间的响应。
1xx:临时响应,表示请求消息正在被处理;
2xx:成功响应,表示请求已被成功接收,完全理解并被接受;
3xx:重定向响应,表示需采取进一步以完成该请求;
4xx:客户机错误,表示请求消息中包含语法错误信息或服务器无法完成客户机请求;
5xx:服务器错误,表示服务器无法完成合法请求;
6xx:全局故障,表示任何服务器无法完成该请求;
二、SIP Message
2.1 Message Struct
SIP消息分为请求和响应两类,其中请求消息是UAC(客户端)发往UAS(服务器端),响应消息是UAS发往UAC。但是,不管请求消息还是响应消息,它都是由一个起始行、若干个头字段和一个消息体组成,其中的消息体是可选。SIP消息的格式如下所示:
起始行
消息头部(若干个头字段)
空行
消息体(SDP)
其中的起始行对于请求是请求行,对于响应是状态行。
下面分别给出请求消息和响应消息的完整的例子。
一个完整的SIP请求消息如下所示:
INVITE sip:marconi@radio.org SIP/2.0
Via: SIP/2.0/UDP lab.high-voltage.org:5060;branch=z9hG4bKfw19b
Max-Forwards: 70
To: G. Marconi
|
From: Nikola Tesla
Call-ID: 123456789@lab.high-voltage.org
CSeq: 1 INVITE
Subject: About That Power Outage...
Contact:
Content-Type: application/sdp
Content-Length: 158
v=0
o=Tesla 2890844526 2890844526 IN IP4 lab.high-voltage.org
s=Phone Call
c=IN IP4 100.101.102.103
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
对应完整的200OK的响应消息:
SIP/2.0 200 OK
Via: SIP/2.0/UDP lab.high-voltage.org:5060;branch=z9hG4bKfw19b
;received=100.101.102.103
To: G. Marconi
From: Nikola Tesla
Call-ID: 123456789@lab.high-voltage.org
CSeq: 1 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 155
v=0
o=Marconi 2890844528 2890844528 IN IP4 tower.radio.org
s=Phone Call
c=IN IP4 200.201.202.203
t=0 0
m=audio 60000 RTP/AVP 0
a=rtpmap:0 PCMU/8000
2.2 Requests
2.2.1 请求行
请求消息的起始行为请求行(Request-Line)。请求行的格式如下所示,由方法名、请求URI和协议版本组成,各部分之间均用一个空格字符进行分隔。除此之外,请求行必须用回车换行字符表示行终结。请求行的格式如下:
格式:Request-Line = Method Request-URI SIP-Version
Method:方法表示请求的类型,核心的类型有6种,INVITE,ACK,BYE,CANCEL,REGISTER和OPTIONS
Request-URI:请求的URI表示此请求将要被发送的目标地址
SIP-Version:一般为SIP/2.0
例子:INVITE sip:Bob.Johnson@company.com SIP/2.0
2.2.2 请求头字段
见2.4节。
2.2.3 消息体
见2.5节。
2.3 Responses
2.3.1 状态行
响应消息的起始行为状态行(Status-Line),状态行由协议版本、状态码和状态原因短语组成,各个部分之间用一个空格字符进行分隔。状态行的格式如下所示:
格式: Status-Line = SIP-Version Status-Code Reason-Phrase
SIP-Version:一般为SIP/2.0
Status-Code:该参数为一个3为的十进制整数,来报告事物的状态,如早先描述的,状态码是从100~699的整数并且分成代表不同意义的6类
该参数用于对Status-Code参数进行简单的文本描述
例子:SIP/2.0 180 Ringing
2.3.2 响应头字段
见2.4节。
2.3.3 消息体
见2.5节。
2.4 Header Fields
头字段提供了关于请求(或应答)的消息和关于这些消息所包含的消息体的信息。一些头字段可以在请求或应答两种消息中使用,而其他的头字段只能单独特定地用于请求(或应答)。头字段由头字段名、后边跟着一个冒号、再后面跟着头字段值组成。头字段格式如下所示:
field-name:field-value
核心协议中定义的SIP头字段如下表所示:
Where |
Header fields |
Exam |
可出现在请求与响应中
|
Alert-info 通知信息 |
Alert-Info: |
Allow 允许 |
Allow: INVITE, ACK, OPTIONS, CANCEL, BYE |
|
Call-ID 呼叫标识 |
Call-ID: 34a5d553192cc35@15.34.3.1 |
|
Contact 联系 |
Contact: sip:bell@telephone.com |
|
Content-disposition 内容部署 |
Content-Disposition: session |
|
Content-encoding 内容编码 |
Content-Encoding:gzip |
|
Content-language 内容语言 |
|
|
Content-length 内容长度 |
Content-Length:349 |
|
Content-type 内容类型 |
Content-Type: application/sdp |
|
Cseq 命令序列 |
CSeq: 1 INVITE |
|
From 源 |
From: tag=3342436 |
|
Organization 组织 |
Organization: MCI |
|
Retry-after 此后重试 |
Retry-After: 3600 |
|
Record-route 记录路由 |
Record-Route:
|
|
Subject 主题 |
Subject: More good info about SIP |
|
Supported 支持 |
Supported: rel100 |
|
To 目标 |
To: sip: babage@engine.org; tag=2443a8f7 |
|
Via 通过 |
Via: SIP/2.0/UDP 100.101.102.103; branch=z9hG4bK776a |
|
只出现在请求中
|
Accept 接受 |
Accept: application/sdp |
Accept-encoding 接受的编码 |
Accept-Encoding: text/plain |
|
Accept-language 接受的语言 |
Accept-Language: en |
|
Authorization 授权 |
Authorization: Digestusername="Cust1",realm="company.com", nonce="9c8e88df84f1cec4341ae6e5a359", opaque="",uri="sip:user2@company.com", response="e56131d19580cd833064787ecc" |
|
Call-info 呼叫信息 |
Call-Info: m/my_picture.jpg>;purpose=icon |
|
In-reply-to 在答复中 |
In-Reply-To: a8-43-73-ff-43@company.com |
|
Max-forwards 最大转发次数 |
Max-forwards: 70 |
|
Priority 优先级 |
Priority: emergency |
|
Proxy-authorization 代理授权 |
Proxy-Authorization: Digest username="Customer1", realm="company.com", nonce="9c8e88df84f1cec4341ae6e5a359", opaque="", uri="sip:user@company.com", response="e56131d19580cd833064787ecc" |
|
Proxy-require 代理需求 |
Proxy-Require: timer |
|
Require 需求 |
Require: rel100 |
|
Route 路由 |
Route: |
|
只出现在响应中 |
Authenticaton-Info 鉴别信息 |
Authentication-Info: rspauth="9105jr98li459jgfp" |
Proxy-authenticate 代理鉴别 |
Proxy-Authenticate: Digest realm="example.com", nonce="9c8e88df84f 1cec4341ae6e5a359", opaque="", stale=FALSE, algorithm=MD5 |
|
Unsupported 不支持 |
Unsupported: rel100 |
|
Warning警告 |
Warning: 302 proxy "Incompatible transport protocol" |
|
WWW-authenticate WWW鉴别 |
WWW-Authenticate: Digest realm="example.com", nonce="9c8e88df84f1 cec4341ae6e5a359", opaque="", stale=FALSE, algorithm=MD5 |
下面重点介绍以下头字段:
Via:
Via头字段指定目前请求消息经过的路径,同时指定响应也要按该路径返回。该字段值中的branch ID参数是一个事务标识符,代理服务器用它来检测环路。
Via头字段包含一个用来发送消息的传送协议和客户端的主机名或者网络地址,该头字段还可能包含一个接收响应的端口号。本字段还可以包含下列参 数:"maddr"、"ttl"、"received"和"brance"。具体实现时,brance参数的值必须从"z9hG4bk"这个字符串开始。
Via头字段的缩写形式为v,例如:
Via: SIP/2.0/UDP erlang.bell-telephone.com:5060;brance=z9hG4bK87asdks7
Max-forwards:
在RFC3261中规定,Max-Forwards(最大转发次数)头字段必须和任何方法一起规定向下游转发消息的代理服务器和网关的个数。当某客户端沿着某条链路发送请求消息的时候,使用该字段可以有效地防止链路中出错或者发生回环。
Max-forwards头字段的值是一个0-255的整数,指示了该请求还允许被转发的次数。转发该请求时,每经过一个服务器该值就减一。一般默认为70。例如:
Max-Forwards: 70
To:
该头字段指定了请求的逻辑接收者。"display-name"参数用于人机接口,为可选。"tag"参数一般用于标识对话。
To头字段等价性的判定同From头字段。它的缩写形式为t。例如:
To: The Operator
t: sip:+12125551212@server.phone2net.com
另外,将一个请求的To头字段和Request-URI区分开来非常重要。在整个会话过程中,To头字段含有同样的内容,它是打算用于远端用户代理的。它不能被代理改变。
而Request-URI含有在信令路径中下一跳的地址,并因此在路途中被每个代理改变。
From:
From头字段用于指示请求的发起者,也就是发送请求(不是对话)的源地址。这可能与对话的发起者并不同。当被叫发出请求时,From字段中就是使用被叫的地址。From的缩写形式是f。例如:
From:"A. G. Bell"
f: Anonymous
Call-ID:
Call-ID头字段唯一的标识某个客户端的某个特定的会话或所有的注册请求。一个多媒体会议可以发起几个Call-ID不同的呼叫,例如,一个发 起者A可以邀请用户B参与一个会议,随后又邀请用户C参与同一个会议,那么,A与B有一个Call-ID,A与C有另一个Call-ID。那么,A发送 BYE请求时,就是通过不同的Call-ID来选择结束那个会话。Call-ID区分大小写并逐字节比较。缩写形式为i。例如:
Call-ID:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@biloxi.com
i:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@192.0.2.4
Cseq:
命令序列头字段Cseq位于请求消息中,包含两个字段:一个无符号整数字段和一个方法名。该头字段用于把某对话中的事务进行排序且提供了一种唯一标 识某事务的方法(即INVITE、ACK等method),并能够区分某请求是新的请求还是从发的请求。如果两个Cseq的数字序列以及方法都相等那么这 两个Cseq就是等价的。
例如:Cseq: 4711 INVITE
200 OK中的Cseq:完整地复制对应请求中的Cseq,不做任何修改;
ACK中的Cseq:和对应的最终响应有相同的整数序列,只是方法名变为ACK;
CANCEL中的Cseq:和对应的请求(一般是INVITE)由相同的整数序列,只是方法名变为CANCEL;
如下图:
Contact:
Contact字段的值含有一个URI,UA可根据这个地址,直接找到另一个UA,从而避开SIP服务器。
例如:Alice通过SIP Proxy呼叫Bob。Alice发送“INVITE sip:bob@biloxi.com SIP/2.0”到Proxy,中间过程不用管它,在Bob送回的200 OK的响应里包含了Contact字段“Contact:
sip:bob@192.0.2.4 SIP/2.0”到Bob。
Contact头字段的值中还可以包含一个显示名称、含有URI参数的URI和头字段参数。在RFC3261中定义了Contact参数“q”和“expires”。这些参数只用于REGISTER请求及其响应以及3xx响应。
当Contact头字段包含一个显示名称的时候,带有所有的URI参数的URI应放于三角括号<>中,否则,URI后面的参数都认为是头字段参数而不是URI参数。
解析显示名称、URI、URI参数以及头字段参数的规则同样适用于To和From头字段。Contact头字段的缩写是m(“moved”)。
例如:Contact:"Mr. Watson"
m:
Record-Route和Route:
Record-Route头字段由代理服务器插入请求消息中,这样可以使该对话中将来的请求仍能经过该代理服务器。举例如下:
Record-Route:
Route头字段有一个代理服务器列表,用来指定请求消息的路由。举例如下:
Route:
2.5 Bodies(SDP)
请求和应答都可能含有消息体,它被一个空行和消息头分开。被SIP消息携带的消息体通常是会话描述符(即SDP),但它也可以由任何不透明物体组成,它就象附件一样包含在SIP消息中。在这里我们主要介绍会话描述符。
2.5.1 SDP介绍
会话描述协议(SDP,Session Description Protocol)规定了对描述会话的必要信息怎样进行编码。两个SIP实体可以通过携带SDP消息体来使它们之间的多媒体会话达成一致。但SDP不支持媒体编码方案的协商,这些功能均由下层传送协议完成。
SDP用于构建INVITE和200 OK响应消息的消息体,供主\被叫用户交换媒体信息。
SDP包括以下一些方面:
1) 会话的名称和目的
2) 会话存活时间
3) 包含在会话中的媒体信息,包括:
媒体类型(video, audio, etc)
传输协议(RTP/UDP/IP, H.320, etc)
媒体格式(H.261 video, MPEG video, etc)
多播或远端(单播)地址和端口
4) 为接收媒体而需的信息(addresses, ports, formats and so on)
5) 使用的带宽信息
6) 可信赖的接洽信息(Contact information)
2.5.2 SDP语法
SDP会话描述是基于文字的,一个会话描述由一些类似如下形式的文字行组成:
Tyte=value
类型域为一个单独字符,而值域的格式则取决于它前面的类型语。一个SDP描述含有会话级信息和媒体级信息。会话级信息应用于整个会话。例如,它能成 为会话始发者或者会话的名字。媒体级信息作用于特殊的媒体流。例如,它能作为一个编码器给音频流编码或者是给视频流发送端口号。
一个SDP会话描述以会话级信息和媒体级信息开始,如果任意一个出现,另外一个就接着在后面出现。会话级部分以v=0开始,v代表类型,0为值,意思是协议版本号为0(SDP版本0)。接下来的行直到媒体流部分或者会话描述的终点,提供了整个会话的信息。
媒体级部分以m行开始。下面的行直到下一个m行出现,或者直到会话描述的终点,提供了特定媒体流的信息。
SDP具体语法如下:
会话描述:
v= (protocol version) //SDP版本,默认为0
o= (owner/creator and session identifier) //<用户名><会话id><版本><地址>
s= (session name) //会话名
i=* (session information) //会话信息
u=* (URI of description) //u=http://www.zte.com.cn/staff/sdp.ps
e=* (email address)
p=* (phone number)
c=* (connection information -如已经包含在所有媒体中则该行不需要)
b=* (bandwidth information)
z=* (time zone adjustments) //时区调整
k=* (encryption key) //<方法>:<密钥>或k=<方法>
a=* (zero or more session attribute lines) //a=<属性> 或a=<属性>:<值>
时间描述:
t= (time the session is active) //<开始时间><结束时间>,单位秒
r=* (zero or more repeat times) //<重复时间><活动持续时间
媒体描述:
m= (media name and transport address)//m=<媒体><端口><传送><格式列表>
i=* (media title媒体称呼)
c=* (connection information - 如已经包含在会话级描述则为可选)
b=* (bandwidth information)
k=* (encryption key)
a=* (zero or more media attribute lines)
注:v,o,s,t,m为必须的,其他项为可选。
如果SDP语法分析器不能识别某一类型(Type),则整个描述丢失;
如果"a="的某属性值不理解,则予以丢失
整个协议区分大小写
"="两侧不允许有空格
会话级的描述就是媒体级描述的缺省值
所有均格式为=
2.5.3 一个例子
v=0 //SDP版本
o=Tesla 2890844526 2890844526 IN IP4 lab.high-voltage.org //会话发起者是Tesla,地址是lab.high-voltage.org
s=Phone Call //会话名字是Phone Call
c=IN IP4 100.101.102.103 //接收地址是100.101.102.103
t=0 0 //在什么时候是激活的
m=audio 49170 RTP/AVP 0
//音频流,端口是49170,音频流在udp上通过RTP传输,
//值0意味音频是在单个信道中使用PCM u—law进行编码和以8kHz的频率采样
a=rtpmap:0 PCMU/8000
三、SIP协议行为
3.1 会话过程
UAC通过向服务器发送INVITE消息开始会话发起过程,该请求可能通过网络中间的服务器设备的转发,最终到UAS。如果UAS同意建立本次会 话,则返回2XX响应,如果不同意或者发生意外情况(重定向或者错误),则返回3XX、4XX、5XX、6XX响应。UAC对于这些最终响应产生ACK, 建立会话成功或者失败。在收到最终响应之前,UAS也可以发送临时响应(1XX)来通知UAC当前的处理进展情况。
在会话建立成功以后,任何一端UA可以通过发送re-INVITE请求来调整会话,修改会话的某些属性,例如:增加或删除媒体流,改变媒体发送或接受地址等。
当需要结束会话的时候,任何一端UA可以通过发送BYE请求,来结束会话。对端同意结束,则发送200 OK应答,结束会话成功。
图3.1 最基本的两个UA之间的SIP呼叫
最基本、最简单的SIP呼叫是两个UA之间之间的点对点呼叫。如上图所示。
下面就最基本的SIP呼叫,分别针对发起会话、调整会话和结束会话进行说明。
3.1.1 发起会话
图3.1.1 建立会话的三次握手
如图3.1.1所示,INVITE、200 OK、ACK三条消息为会话发起过程中的三次握手。三次握手过程的完成,唯一标识了会话的成功建立。
UAC的INVITE消息的产生
RFC3261规定,由UAC产生的一个有效的SIP请求消息必须至少包含下列头字端:Via、Max-Forwards、To、From、 CSeq和Call-ID头字端,不仅是在INVITE,它们在所有的SIP请求消息中都是必选的。这六个头字段是构建SIP消息的基本单元,它们共同提 供了大部分的关键的消息路由服务,包括消息的寻址、响应的路由、消息传播距离限制、消息排序,以及事务交互的唯一性标识等。另外,请求行 (Request-Line)也是必选的。
各头字段的说明见上文。具体地,请求行(Request-Line)中的Request-URI设置为与To头字段一值(除REGISTER以外的 所有请求的初始Request-URI都应该与To头字段一值);Via头字段设置为响应消息将要被发送的地址,其brance参数值在时间和空间
作者: hedonism
- 该日志由 hedonism 于10年前发表在综合分类下,最后更新于 2013年12月01日.
- 转载请注明: SIP协议 | 学步园 +复制链接
抱歉!评论已关闭.