第1章 SIP概述
1.1 SIP介绍
1.1.1 基本概念
SIP是一种应用层控制协议,用于在IP网上建立、修改以及终止多媒体会话或呼叫,现由SIP工作组负责,参考规范RFC2543。目前主要用于多媒体会议、远程学习、IP电话等等。
1.1.2 基本功能
SIP的基本功能有以下五种:
1. 用户定位(User location)- 决定哪个终端系统参加通信
2. 用户能力(User capabilities)- 决定通信所采用的媒体和媒体参数
3. 用户可用性(User availability)- 决定被叫方是否愿意加入通信过程
4. 呼叫建立(Call setup)- 振铃、主叫方和被叫方的连接和参数的建立
5. 呼叫处理(Call handing)- 呼叫转移、终止呼叫等
1.1.3 主要特征
1. SIP可以发起会话,也可以邀请用户加入以其它方式(如SAP、LDAP 等)发布或建立的会话;通过SDP协议,SIP可以在呼叫发起和呼叫进行过程对会话参数进行协商,如会话带宽要求、传输的媒体类型(语音、视频和数据等)、媒体的编解码格式、对组播和单播的支持等。 SIP可以提供呼叫控制功能(如呼叫保持、呼叫路由、呼叫转移、媒体转换等)。
2. SIP可以支持单播会话,也可以支持多播会话;
3. SIP与网络协议独立,即与底层协议无关(Lower-Layer-Protocol Neutral)。SIP可以在不同的传输层协议上工作,如TCP或UDP。当使用UDP的时候,SIP可以更好的支持多播会话;当使用TCP的时候,SIP可以更容易的通过防火墙。
4. SIP支持很多其他协议,如RSVP、RTP和RTCP、RTSP、SAP、SDP等。但是,SIP的功能和操作不取决于以上任何协议。
5. SIP是基于文本的协议, 简单灵活,可扩展性好; SIP采用Client/Server的体系结构,在很大程度上继承了HTTP和 SMTP协议的特征。
6. SIP协议是无状态的(Minimal State),服务器可以保持也可以不保持呼叫状态;
7. SIP透明支持名字映射和重定向服务,可以实现ISDN和IN电话用户服务; 通过网关,SIP可以实现PSTN电话之间的呼叫。
8. SIP支持用户的移动性和移动业务。
1.1.4 SIP地址 SIP Addressing
SIP地址格式由SIP URL(SIP统一资源定位器)定义, SIP URL 类似于mailto或 telnet URL。SIP在设计上充分考虑了对其他协议的扩展适应性。它支持许多种地址描述和寻址,包括:用户名@主机地址、被叫号码@PSTN网关地址和如Tel:010-62281234这样普通电话号码的描述等。SIP地址包括用户部分和主机部分,如:j.doe@big.com、j.doe@192.168.10.1;可以用来标识一个人、一个组里第一个可以访问的人、或者标识一个组。
SIP地址可以从带外信息获得(如媒体代理、email等)。
1.2 SIP组件
1.2.1 体系结构
SIP是基于客户机/服务器结构的。基本分为用户代理和网络服务器。
用户代理(User Agent )
l 用户代理客户端(User Agent Client)
l 用户代理服务器(User Agent Server)
网路服务器(Network Server)
l 代理服务器(Proxy Server)
l 重定向服务器(Redirector Server)
l 注册服务器(Registrar)
l 位置服务器(Location Server)
1.2.2 基本组件
1.2.2.1 用户代理(User Agent)
l 用户代理客户端UAC(User Agent Client):发起SIP呼叫的客户端应用程序。
l 用户代理服务器UAS(User Agent Server):接受SIP请求的服务器程序。作为用户的代理,根据接受到的请求代表用户返回相应的响应:接受、拒绝、转接。
用户代理客户端UAC和用户代理服务器UAS都可以终止一个呼叫。
1.2.2.2 代理服务器(Proxy Server)
代理服务器是代表其他客户机发起请求,既充当服务器又充当客户机的媒介程序。请求可能在代理服务器中被服务或者直接经过翻译后发送到其它的服务器。它在转发请求之前可能解释、改写、翻译原请求消息中的内容。
1.2.2.3 重定向服务器(Redirector Server)
重定向服务器在接收SIP请求后,把请求中的原地址映射成零个或多个新地址,返回给客户机。与代理服务器不同的是,重定向服务并不会发起自己的请求。与用户代理相区别的是,重定向服务并不会发起或中断呼叫。
1.2.2.4 注册服务器(Registrar)
注册服务器主要是接收客户机的注册请求,完成用户地址的注册。注册服务器应该支持用户鉴权。
注册服务器一般配置在代理服务器和重定服务器之间,并且一般配置位置服务器的功能。
1.2.2.5 位置服务器(Location Server)
需要注意的是,位置服务器并不是一个SIP服务器,SIP服务器可以通过任何非SIP协议如(SQL,LDAP,CORBA,etc.)来连接位置服务器。
位置服务器的主要功能是提供位置查询服务,主要是由代理服务器或重定向服务器用来查询被叫的可能的地址信息。
1.3 SIP消息
SIP消息分为两大类:请求(Request)和 响应(Response),响应又分为最终响应(Final Response)和 临时响应(Provisional Response)。
1.3.1 请求消息
请求消息分为6种:INVITE、ACK、BYE、CANCEL、REGISTER、OPTIONS。
1 INVITE
INVITE方法说明一个用户或业务参加一个会话。消息体部分包含了被叫的信息说明。对于双方呼叫,主叫需说明他能接受和发送的媒质类型。这个消息应该被SIP代理服务器、重定向服务器、用户代理服务器和客户机所支持。
2 ACK
ACK方法主要用于确认客户端对INVITE方法的请求已经响应。这个消息应该被SIP代理服务器、重定向服务器、用户代理服务器和客户机所支持。
3 BYE
客户机用BYE方法向服务器发消息来结束该呼叫。这个消息应该被SIP代理服务器、重定向服务器、用户代理服务器所支持。
4 CANCEL
CANCEL方法用于取消一个挂起的呼叫。这个消息应该被SIP代理服务器、重定向服务器、用户代理服务器和注册服务器所支持。
5 REGISTER
用于向定位服务器注册客户机的相关信息。
6 OPTIONS
用于查询服务器的相关信息和功能。这个消息应该被SIP代理服务器、重定向服务器、用户代理服务器和客户机、注册服务器所支持。
1.3.2 响应消息
响应消息分为6类:1xx,2xx,3xx,4xx,5xx,6xx。
1 1xx Informational(通知)
服务器或代理正在执行处理,终端应该等待响应。如果服务器需要200毫秒以上的时间进行处理,则向终端发送1xx响应。服务器可以发送多个1xx响应,终端不需发送ACK请求。
2 2xx Successful(成功)
请求成功,停止查询。
3 3xx Redirection(重定向)
3xx 响应给出用户新的位置,或者能够满足呼叫的另一个服务器,主叫应该终止当前查询,开始新的适当的查询。 任何重定向响应都不能列出Via中的地址,以防止forwarding loops,同时用户代理或者代理服务器必须检查从重定向服务器返回的地址,确认与以前尝试过的地址不相同。
4 4xx Request Failure(请求失败)
4xx响应定义了服务器的失败响应,客户端不应该重新发送相同的请求(例如可以加入适当的鉴权)。不过,同样的请求发到其他的服务器有可能成功。
5 5xx Server Failure(服务失败)
当服务器本身错误时,返回5xx响应。5xx响应并不表示最终错误,如果其他的可能的地址还没有尝试过,就不能结束一个查询。
6 6xx Global Failures(全局错误)
6xx响应指出这是关于指定的用户的最终信息,而不仅仅是Request-URI 中指出的实例请求。(the particular instance indicated in the Request-URI.)所有未来的对该用户的请求都会失败,还未结束的对该用户的查询都应该中断。
1.3.3 消息格式
SIP消息分为请求消息和响应消息,每一条消息都由以下几部分组成:
开始行,消息头,CRLF,消息体。
SIP-message = Request | Response
generic-message = start-line
*message-header
CRLF
[ message-body ]
开始行:
start-line = Request-Line | Status-Line
消息头:
分为通用消息头、请求消息头、响应消息头、实体消息头。
message-header = ( general-header | request-header | response-header | entity-header )
请求消息:
Request = Request-Line
*( general-header | request-header | entity-header )
CRLF
[ message-body ]
Request-Line = Method SP Request-URI SP SIP-Version CRLF
响应消息:
Response = Status-Line
*( general-header | response-header | entity-header )
CRLF
[ message-body ]
Status-Line = SIP-version SP Status-Code SP Reason-Phrase CRLF
各个消息头的具体内容:
general-header = Accept
| Accept-Encoding
| Accept-Language
| Call-ID
| Contact
| CSeq
| Date
| Encryption
| Expires
| From
| Record-Route
| Timestamp
| To
| Via
entity-header = Content-Encoding
| Content-Length
| Content-Type
request-header = Authorization
| Contact
| Hide
| Max-Forwards
| Organization
| Priority
| Proxy-Authorization
| Proxy-Require
| Route
| Require
| Response-Key
| Subject
| User-Agent
response-header = Allow
| Proxy-Authenticate
| Retry-After
| Server
| Unsupported
| Warning
| WWW-Authenticate
具体的消息头的内容说明和响应消息的说明,请参考附录A。
1.4 SIP操作
SIP服务器定位(Locating a SIP Server)
SIP事务(SIP Transaction)
SIP 邀请(SIP Invitation)
用户定位(Locating User)
注册服务(Registration Service)
1.4.1 SIP服务器定位 (Locating a SIP Server)
客户在发起呼叫时,需要将请求发送到本地配置的独立于Request-URI的SIP服务器或者由Request-URI 标识的IP地址和端口。在后一种情况下(直接发送),客户必须获得SIP服务器所用的协议、IP地址和端口号,如果没有指明端口号,可使用缺省端口(5060),如果没有指明传输协议,则首选UDP,如果发送失败, 则改用TCP发送。
客户应能理解指示服务器不可达的网络通知(如ICMP 消息),而不仅仅依赖于操作超时信息。如果客户发现服务器不能到达某个地址(TCP 的 Connect()返回ECONNREFUSED,UDP要使用Connect()绑定到目的地址),应能作出相应的反应,就好像是收到了4xx错误响应一样。
客户发现SIP服务器地址的步骤:若地址的主机部分是IP地址,客户就可以直接访问;若地址的主机部分是不IP地址,则需要查询DNS服务器,通过询问DNS服务器来查找一个或多个SIP服务地址。如果DNS服务器没有返回地址,则终端按照不能连接服务器处理。
对服务器地址的格式没有一个强制的规定,但约定俗成使用sip.domainname (例如:sip.example.com)的形式,可参考RFC2219。
客户端会缓存一个DNS服务器的检索结果,当终端向同一个服务发起呼叫时,就不必再次检索DNS。关于DNS缓存实效的问题可参考RFC1035。
1.4.2 SIP事务(SIP transaction)
一个SIP事务存在于一个客户与一个服务之间,由所有的(从最初的请求到最后的应答)消息组成。
一个事务只对应于一个呼叫,由Call-ID标识。所有对于一个请求的应答都包含相同的Call-ID, CSeq, To、From域 (或其他包含的值)。
客户机与服务器之间的每一个Call-ID只能有一个未结束的事务。
如果使用了TCP,那么单个SIP事务的请求和响应由相同的TCP连接承载。相同的客户机与服务器之间的几个SIP请求也可以使用相同的TCP连接承载,或者为每一个请求建立一个新的连接。如果客户机使用单点UDP发送请求,那么响应将发送到UDP请求的源地址(the address contained in the next Via header field of the response)。 如果客户机使用多点UDP发送请求,那么响应将发送到多点UDP的目的地址。对于UDP, 可靠性依靠重发来实现。
1.4.3 SIP邀请 (SIP Invitation)
1.4.3.1 概述
SIP会话由INVITE方法发起,通常情况下,INVITE包括会话描述(一般使用SDP格式),为被叫提供足够的会话信息;如果被叫同意加入会话,主叫就发送ACK方法确认呼叫成功;如果被叫拒绝加入会话或产生其他错误,主叫则发送BYE方法指示呼叫失败;
邀请过程:主叫通过INVITE请求邀请被叫加入会议或建立两方会话。如果被叫同意,则发送ACK 请求。如果主叫不想继续会话,则发送BYE请求。INVITE请求将包含会话描述, 写在SDP(RFC 2327)中。
对于多播会话(multicast sessions), 会话描述将枚举允许加入会话的媒体类型和格式。被叫如果不能接受该媒体类型或希望使用单播会话,那么必须返回一个会话描述。
对于单播会话(unicast session), 会话描述将包含主叫希望的媒体类型和格式与媒体数据发送地点。如果被叫同意加入,则返回一个同样的媒体描述。
SIP会话通常有以下两种方式:代理服务器方式和重定向服务器方式。
1.4.3.2 代理服务器方式
1、代理服务器接受INVITE请求
2、与位置服务器联系,获得完整地址
3、获得一个更精确的地址
4、服务代理根据位置服务返回的地址发送SIP INVITE 请求
5、用户代理服务器通知用户
6、向代理服务器返回连接成功.
7、代理服务器向主叫返回成功连接.
8、9、发端返回ACK确认连接成功建立.
ACK可以直接发送到被叫,而不通过代理,请求和应答使用相同的Call-ID.
1.4.3.3 重定向服务器方式
1、INVITE request,
2、3、contacts the 位置服务器,
4、将新地址返回给主叫,
5、返回ACK.
6、主叫向新的地址发起新请求,使用同样的call-ID 但使用高的CSeq,
7、连接成功.
8、主叫返回ACK.
1.4.4 SIP用户定位 (Locating a User)
考虑到用户可以在不同终端移动,SIP提供了定位功能。
用户可以在SIP服务器或位置服务器注册其位置信息,一个用户可以注册到不同的位置。位置服务器可以采用其他协议,如finger (RFC 1288)、rwho(RFC 2167)、LDAP (RFC 1777 )、 multicast-based protocols 或 operating-system dependent mechanisms 。位置服务器可以解析出零个或多个可能位置,这些位置可以按照成功访问的概率来存储。
不同类型的Server收到解析出的地址信息后,采取的动作有所不同:重定向服务器将返回的地址列表放在Contact headers中返回;而代理服务器则不断地尝试这些地址,直到呼叫成功(返回2xx响应)或被叫挂断(返回6xx响应)为止。
代理服务器在向前发送请求时,必须把自身的地址加到Via头指示的地址列表的尾部,这样做的目的是保证响应原路返回,防止请求环路(request loops)。在响应返回路径上,代理服务器要从Via头指示的地址列表移去自身的地址,从而对被叫和外部网络隐藏了内部的路由信息。
代理服务器必须时刻检查它产生的请求,以确认请求的目的地址并不包含在Via sent-by, via-received or via-maddr参数中。
代理服务器可以处理“分叉”(fork)请求,即收到一个请求而可以发出多个请求,这些请求(具有相同的Call-ID)可独立到达被叫。这样终端将收到多个邀请请求,每一个拷贝都拥有同样的Call-ID。用户代理必须返回同样的状态响应。重复的请求并不是错误。
1.4.5 SIP注册服务 (Registration Services)
用户在发起会话前,首先应到注册服务器注册。注册使用REGISTER方法。注册服务器通常将用户注册的地址信息保存在位置服务器,这样使代理服务器或者重定向服务器就知道那些地址是可以到达的。
注册信息是随时刷新的(默认周期是1小时),所以用户每隔一段时间都应主动注册。
注册服务一般伴随其他功能,如提供用户鉴权功能,或者通过注册服务安装呼叫处理程序或第三方应用。
1.4.6 改变现有会话 (Changing an Existing Session)
当需要改变现有会话参数的时候,可以通过重发INVITE来实现。重发INVITE时应该使用相同的Call-ID,但使用新的或不同的消息头或消息体来传送新的信息。这条再次发送的INVITE 必须比以前的请求拥有高的 Cseq。例如,两方正在会话,想加入第三方,转到多方会话方式,则会话的一方向第三方发出邀请,使用新的多播地址,同时向另一方发出同样的邀请,但是使用原来的Call-ID。
1.5 SIP的注册服务与鉴权(SIP Registration Services and Authentication)
SIP注册服务的目的是使SIP客户机能够使用SIP服务器提供的服务,或使之失效。在注册请求中,客户机将提供包含在Contact域中的一个或几个地址给注册服务器。这样代理服务器就可以使用注册信息进行IP电话的路由。同时,注册也可以提供鉴权服务。如果不提供鉴权服务,冒名顶替者就可以截听任何人的电话。
1.5.1 注册过程
l 目的:用户发起一个呼叫前,首先向服务器注册自己。
l 用户向服务器发出注册请求,消息体的Contact中列出地址表,表示用户的联系方式。
l 服务器向用户返回一个需要鉴权的信息。
l 用户填写用户ID和密码,提交。
l 服务器检验并通过对用户的信任,在数据库中注册用户,并返回200号响应。响应中包含用户当前的注册项,这代表用户以前没有进行过注册。
1.5.2 鉴权
SIP的鉴权过程参考了HTTP的鉴权过程。
可参考RFC1866,RFC2069。
第2章 会话描述SDP(Session Description Protocol)
2.1 概述
SDP制订的目的是描述多媒体会话,如会话通知、会话邀请或其他发起多媒体会话的形式。
SDP是纯粹的会话的描述格式而不是一个传输协议。它可以使用不同的传输协议,包括SAP(Session Announcement Protocol),SIP(Session Initiation Protocol), Real-Time Streaming Protocol, electronic mail using the MIME extensions, and the HTTP(Hypertext Transport Protocol)。SDP并不描述广播地址的分配,或者详细的消息描述,并且SDP也不是为沟通媒体编解码而设计的。
SDP被设计成一个用于通用目的,它可以广泛的用于网络环境和应用。
2.2 SDP的使用
SDP是一种多媒体会议的会话描述协议,SDP通常的使用模式为:一个客户机定期的向已知的广播地址和端口广播通知报文(announcement Packet),来通知一个会议的会话(conference session)。这是一种广播通知(Multicast Announcements)的形式。主要使用Session Announcement Protocol (SAP)来承载。
SAP报文基于UDP,
SAP(Session Announcement Protocol)头;
文本静荷(The text payload)是一个SDP会话描述。文本静荷的长度不应该超过1 Kbyte。如果使用SAP的话,一个报文只能承载一个会话通知。
除了使用SAP进行广播性的通知,电子邮件和WWW也可以传送会话描述。对于email 和WWW,MIME类型"application/sdp"是必须要使用的。这使为作为会话参与者的WWW客户端和邮件的读者提供的应用程序可以以一种标准的方式自动运行。
注意的是仅仅通过email和WWW通告的多播会话并不包含会话通知的接收者有能力接收这个会话的属性。因为多播会话可能在范围上受局限,连接到WWW服务器或接收电子邮件有可能超出了这一局限。SAP 通告不会有这样的问题。
2.3 SDP的内容
SDP的目的是传送多媒体会话中的媒体流的信息,以使会话描述的接收者可以参加会话。所以,SDP应该包含足够的信息来发起会话或使接收者加入会话。
SDP应该包含:
l 会话名和会话目的
l 会话激活的时间
l 会话由何种媒体组成
l 接收这些媒体的信息(地址,端口,格式等等)
l 会话所用到的带宽信息。
l 连接信息
通常情况下,SDP应该传送加入会话的足够的信息 (包含可能的特殊的加密钥匙)并且通知未参与者可能要用到的资源。
2.3.1 媒体信息 Media Information
SDP包含:
l 媒体类型(video, audio, etc)
l 传输协议(RTP/UDP/IP, H.320, etc)
l 媒体格式(H.261 video, MPEG video, etc)
对于IP多播会话,应该包含:
l 媒体的多播地址和媒体的传输端口
对于IP单播,需要传输以下信息:
l 媒体的目的地址和传输端口
这里的地址和端口与媒体和传输协议的定义有关。缺省情况下,地址和端口是发端的地址和端口及收端的地址和端口,可是,有些媒体可以定义使用这些来为实际的媒体流建立一个控制通道。
2.3.2 时间信息 Timing Information
会话可以是有时间限制也可以是无时间限制的,但是不管有无时间限制,他们都只能在有限时间内活动。
SDP可以传送:
l 一个任意的会话的起止时间范围的列表
l 每一个时间段可以循环的时间范围,如"every Wednesday at 10am for one hour"
这些时间信息是全局一致的,与本地的时间无关。
2.3.3 私有会话 Private Sessions
可以创建公共会话,也可以创建私有会话。私有会话主要通过经过加密的会话描述来传输。加密的细节主要与传输SDP的机制有关,可以参考SAP。
如果会话通告是私有的,那么就可以使用这个私有的会话通告来传输会话中的媒体解码所需的密码钥匙。其中包含每一个媒体所使用的加密方案。
2.3.4 预留 Obtaining Further Information about a Session
会话描述应该传输足够的信息,以使用户决定是否参与会话。SDP可以在Universal Resources Identifiers (URIs)加入额外的标记,以提供会话的更多的信息。
2.3.5 分类Categorisation
当SAP或其他的通告机制传输几种会话描述,那么应该可以过滤这些通告,决定哪些是感兴趣的,那些不是。SDP支持一种会话的分类机制,这是可以自动完成的。
2.3.6 国际化 Internationalization
SDP规范推荐使用UTF-8 encoding (RFC 2044)中的ISO 10646 字符集,以使不同的语言都可以表达。可是,为了简洁的表述,SDP也可以使用其它的字符集,如ISO 8859-1,国际化仅仅由free-text fields (会话名和背景信息)使用, 并不是所有的SDP都要使用。
2.4 SDP格式
SDP会话描述全部是基于文本的,使用UTF-8 encoding制定的ISO 10646 字符集,SDP域的名称和属性的名称只使用UTF-8中的US-ASCII子集, 但文本域和属性值可以使用完整的ISO 10646字符集。
选择文本编码形式是基于简便,以便使用不同的传输方式,允许更好的柔韧性和使用基于文本的工具来产生和处理会话描述。 因为给所有的SAP通告的整个带宽的分配是有严格限制的,所以编码尽量做得紧凑。又因为通告可能会通过一些不可靠的传输途径 (如: email)或者被一些中间的缓存服务器损坏,编码就必须被设计成有严格的顺序和格式,这样大多数的错误就会更容易被检测和丢弃。这也可以让没有密码钥匙的用户快速的监测和丢弃有密码保护的通告。
一个SDP会话描述有一组以下形式的文本组成。
<type>=<value>
一个会话描述由一个会话级描述(session-level description,整个会话和所有媒体流都接受的细节)和几个媒体级描述(media-level descriptions单个媒体流接受的细节)组成。
一个通告由一个会话级部分(session-level section)和0个或几个媒体级部分(media-level sections)组成。会话级部分由一个‘v=’行开始,后面跟随第一个媒体级部分。媒体描述由‘m=’行开始,后面跟随下一个媒体描述,或者是整个会话描述的结尾。通常情况下,会话级的值是所有媒体的缺省值,除非被媒体级的相同的值覆盖。
当SDP被SAP传输,每个包只允许一个会话描述。当SDP 被其他形式运载,几个SDP会话描述有可能会被组装到一起,(‘v=’行是上一个会话描述的结束,和新的会话描述的开始)。在每一个描述中,一些行是必需的,一些是可选的,但所有的必须按照下面的顺序出现(固定的顺序可以极大地提高错误检测并可以使用简单的解析器),可选行由‘*’标识。
SDP会话描述有以下三部分内容:会话描述、媒体描述、时间描述。
会话描述:
v= (协议版本protocol version)
o= (所有者和会话标识符owner/creator and session identifier).
s= (会话名session name)
i=* (会话信息session information)
u=* (URI的描述 URI of description)
e=* (邮件地址email address)
p=* (电话号码phone number)
c=* (连接信息connection information - not required if included in all media)
b=* (带宽信息bandwidth information)
One or more time descriptions (see below)
z=* (地区时间调整time zone adjustments)
k=* (加密钥匙encryption key)
a=* (0或多个会话属性行zero or more session attribute lines)
Zero or more media descriptions (see below)
时间描述:
t= (会话激活的时间time the session is active)
r=* (0或多个重复时间zero or more repeat times)
媒体描述:
m= (媒体名和传输地址media name and transport address)
i=* (媒体标题media title)
c=* (连接信息connection information - optional if included at session-level)
b=* (带宽信息bandwidth information)
k=* (加密钥匙encryption key)
a=* (0或多个媒体属性行zero or more media attribute lines)
更详细的说明请参考Rfc2327。
第3章 SAP (Session Announcement Protocol)
3.1 SAP概述
为了支持多播多媒体会话或者其他多播会话,为了向预期的参加者传递相应的会话建立信息,应该使用分布式的会话目录。一个会话目录的实例周期性的广播包含会话描述的报文,当这些报文被其他会话目录接收到后,潜在的远端参加者就可以使用这个会话描述来启动参与该会话所需要的工具。SAP协议就是这样一种通告协议,它描述了一种多播通告会话描述信息的方法。
SAP是一种为多播会话会议设计的目录通告协议,它定义了会话目录的客户所使用的报文格式,并且考虑了保密性和可测量性。
3.2 SAP内容
3.2.1 会话通告(Session Announcement)
SAP广播者周期的发送一个通告报文给已知的多播地址和端口。需要注意的是,在没有一个集中机制,没有附加的可靠性保证,尽力而为的UDP/IP标准上,任何SAP接收者的加入或退出对SAP广播者来说都是不可知的。
通告报文包含一个会话描述和一个鉴权头,会话描述可以被加密,但是并不推荐这样做。一个SAP通告按照会话声明的范围进行多播,并保证通告的接收者是在通告描述的会话范围之内。
SAP通告发送到的地址:
l 全球范围会话,那么广播地址的范围是224.2.128.0 - 224.2.255.255,SAP通告要被发送到地址:224.2.127.254
l 管理域范围内会话,广播地址由管理域内部确定,那么SAP通告发送到的地址是这个广播抵制范围内的最大可用地址。如广播地址范围是:239.16.32.0 - 239.16.33.255,那么SAP通告地址为:239.16.33.255。
SAP通告应该发送到的端口:9875。
IP的生存时间TTL设为255。
3.2.2 通告间隔(Announcement Interval )
3.2.3 会话删除(Session Deletion)
会话将在以下三种情况下被删除:
l 显式的超时(Explicit Timeout):会话的净荷中包含时间戳信息,显式的指定了会话的起止时间,如果当前时间超过了中止时间,那么会话应该被删除。
l 隐式的超时(Implicit Timeout):每一个会话描述的会话通告消息应该周期的发送到会话接受者的会话缓冲区,通知的周期可以由当前会话的设置来确定。如果接收者在10个会话通知周期内没有被接收到,或者是1个小时,或者是两者最大的哪一个,那么会话应该在接收者的会话缓冲区中被删除。1小时这个最小值是主要是考虑到网络短暂断开而设置的。
l 显式的删除(Explicit Deletion):接收端接收到会话删除报文,则会话被显式的删除。会话删除报文应该包含鉴权头,并且与以前的通告报文鉴权相匹配。如果没有鉴权头或不匹配,那么这个报文应该被忽略。
3.2.4 会话修改(Session Modification)
先前的会话可以通过通告修改的会话描述来进行修改。
会话修改与会话删除应该有同样的规则。会话修改报文应该包含鉴权头,并且与以前的通告报文鉴权相匹配。如果没有鉴权头或不匹配,那么这个报文应该被忽略。
3.2.5 Packet Format 报文格式
报文格式请参考RFC2974。
第4章 附录
4.1 SIP消息头域的说明
4.1.1 general-header类
通用头域描述消息基本属性,域名只有在协议版本改变时才可有效地扩展。通信中的所有方均认为是“通用头域”的新的头域也可认为是通用头域。不被认可的头域作为实体头域。
general-header = Via
| Record-Route
| From
| To
| Call-ID
| Cseq
| Contact
| Accept
| Accept-Encoding
| Accept-Language
| Date
| Encryption
| Expires
| Timestamp
4.1.1.1 Via
Via头域指示请求迄今为止所走的路径。它防止了请求的循环,同时确保了响应(回答)沿同样的路径返回。
4.1.1.2 Record-Route
Record-Route请求和响应头域可以被任何服务器加到请求中,这些服务器坚持以后的同一个Call leg的请求使用同样的路径。它包含了一个唯一可达的Request-URI来指示代理服务器。每一个代理服务器将它的Request-URI加到序列的开始。
呼叫方用户代理禁止在包含有Route头域的请求中使用Record-Route头域。
Record-Route = "Record-Route" ":" 1# name-addr
例: Record-Route: <sip:a.g.bell@bell-telephone.com>,<sip:a.bell@ieee.org>
4.1.1.3 From
指示请求的初始者。From域可以包含一个"tag"参数。
From =("From" | "f")":"(name-addr | addr-spec)
*(";"addr-params)
name-addr=[display-name]”<”addr-spec”>”
addr-spec=SIP-URL | URI
addr-params=tag-param
tag-param="tag="UUID
UUID=1*(hex | "-")
"tag"可以出现在一个请求的From头域中,当共享同一个SIP地址的用户的两个实例使用同一个Call-ID发出邀请时,必须使用此"tag"。
"tag"必须是全球唯一的,并且是一个经过加密的至少32比特的随机数。一个单个的用户应该在一个Call-ID所标识的整个呼叫中保持同一个tag。
Call-ID、To和From用于标识一个Call leg。呼叫和Call-leg的区别在于多个响应对派生请求的呼叫。
Examples:
From: "A. G. Bell" <sip:agb@bell-telephone.com>
From: sip:+12125551212@server.phone2net.com
From: Anonymous <sip:c8oqz84zk7z@privacy.org>
4.1.1.4 To
To通用头域说明了请求的接收者。
To =("To" | "t")":"(name-addr | addr-spec)
*(";"addr-params)
name-addr=[display-name]”<”addr-spec”>”
addr-spec=SIP-URL | URI
请求和响应必须包含To头域,指示请求的预定接收者。如果请求包含了不止一个Via头域,则必须增加"tag"参数。如果Via头域不止一个,那么表明请求至少经过一个代理服务器的处理。因为接收者不知道此请求是哪一个代理服务器派生的请求,所以从安全方面考虑,可认为它们都派生了请求。
"tag"参数作为一种通用机制,用于区分由一个SIP-URL标识的用户的多个实例。因为代理可以派生请求,所以同一个请求可以到达用户的多个实例(例如:移动和住宅电话);
当响应与请求相匹配时,如果请求的To域中未包含"tag"参数,那么响应To域中的"tag"参数将忽略。"tag"允许代理派生同一个呼叫的未来的请求,而只对几个可能的响应UAS中的一个定位(寻址)。它也允许被叫方的多个实例发送可以区分的请求。
当SIP服务器接收到一个请求,此请求的To域中含有它不能识别的URI时,它应该返回一个400(Bad Request)响应。
Call-ID、To和From用于标识一个Call leg。呼叫和Call-leg的区别在于多个响应对派生请求的呼叫。"tag"允许代理派生同一个呼叫的未来的请求,而只对几个可能的响应UAS中的一个定位(寻址)。它也允许被叫方的多个实例发送可以区分的请求。
4.1.1.5 Call-ID
Call-ID通用头域唯一标识一个特定的请求或者一个特定客户的所有登记。来自同一个客户的所有的登记应该使用同样的Call-ID头值,至少是在同一个重新启动的循环中。
REGISTER和OPTIONS方式使用Call-ID值来精确匹配请求和响应。一个单个的客户发布的所有的REGISTER请求应该使用同一个Call-ID,至少在同一个有效循环中。
Call-ID = (“Call-ID” | “i”)”:”local-id”@”host
Local-id = 1*uric
i是Call-ID的缩写形式。
“host”应该是一个真正的域名或者是一个全球性的IP地址。如此,”local-id”应该是一个由URI字符组成的标识,此标识在”host”中是唯一的。建议使用经过加密的随机标识。Call-ID的值禁止被重用于另一个不同的呼叫。Call-ID区分大小写。〕
例:
Call-ID: f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com
i:f81d4fae-7dec-11d0-a765-00a0c91e6bf6@foo.bar.com
4.1.1.6 Cseq
对于每一个请求,客户必须使用Cseq(Command sequence)通用头域。此头域包含了请求方式和一个提出请求的客户所选定的十进制序列数,在同一个Call-ID中此Cseq值唯一。此序列数必须为一个32位的无符号整数,它的初始值是任意的,但必须小于等于2**31。连续的请求在请求方式、头域和消息上是不同的,但有同样的Call-ID,它们的Cseq也必须是严格单调增加的相邻的序列数;序列数不能形成环。重传请求有相同的Cseq,但消息体或者头域不同的INVITE请求需要一个新的更高的Cseq。服务器必须在它的响应中回送请求中的Cseq。如果在所接收的Cseq头域中没有method,服务器应该正确的填充。ACK和CANCEL请求必须包含与它们相联系的INVITE请求同样的Cseq。而当BYE请求释放一个请求时必须含有以更高数值的Cseq。如果BYE请求中的Cseq值不高,那么将产生一个400(Bad Request)响应。
"Method"值使得客户将对于INVITE请求的响应和对于一个CANCEL请求的响应(一般是200响应)区分开来。代理可以产生CANCEL请求;如果代理增大序列数,那么有可能与同一呼叫中用户代理以后发送的请求发生冲突。
Cseq ="Cseq" ":" 1*DIGIT Method
Example:
CSeq: 4711 INVITE
4.1.1.7 Contact
Contact通用头域可出现在INVITE、ACK和REGISTER请求中,1xx、2xx、3xx和485响应中。通常,它提供了一个URL,用户可以通过此URL来进行进一步的通信。
INVITE和ACK请求:Contact域表明请求从哪个位置发起;这允许主叫方直接向被叫方发送未来的请求,如BYE,而不是通过一系列的代理。由于所想要的地址可能是代理的地址,所以只Via头域并不够。
INVITE 2xx响应:一个用户代理服务器在发送一个限定的、肯定的响应(2xx)时,可以加入一个Contact响应头域,表明对于未来的请求它可 以直接到达的SIP地址,如ACK请求。Contact头域包含了服务器自己或者代理的地址,
INVITE 1xx响应:一个UAS发送一个临时的响应(1XX)可以插入一个Contact响应域。语义同2XX INVITE响应。
REGISTER:REGISTER请求中的Contact域表明用户的位置。
REGISTER 2xx响应:一个REGISTER响应可以返回可以达到的用户的所有地址。
3xx和485响应:Contact头域指示一个或多个可选的地址。可以出现在对于INVITE、BYE和OPTIONS方式的响应中。Contact头域包含的URI给出了新的位置和用户名,或者简单地说明其他的传输参数。300(Multiple Choise)、301(Moved Permanently)、302(Movec Temporarily)或者485(Ambiguous)响应应该包含一个含有可尝试的新地址的URL的Contact域。
Contact = ( "Contact" | "m" ) ":" ("*" | (1# (( name-addr | addr-spec )
[ *( ";" contact-params ) ] [ comment ] )))
name-addr = [ display-name ] "<" addr-spec ">"
addr-spec = SIP-URL | URI
display-name = *token | quoted-string
contact-params = "q" "=" qvalue
| "action" "=" "proxy" | "redirect"
| "expires" "=" delta-seconds | <"> SIP-date <">
| extension-attribute
extension-attribute = extension-name [ "=" extension-value ]
l q:表明所给的位置的相对重要性,“qvalue”从0到1,值高参考性大。
l action:只用于使用REGISTER登记时。表明是否客户希望服务器代理或者重定向用户想要的未来的请求。
l expires:表明URI的活动时间。注意与Expire头域的联系:如果Contact 中存在expires参数,则使用其表示的时间;若不存在,则使用Expire头域所表示的时间。
例: Contact: "Mr. Watson" <sip:watson@worcester.bell-telephone.com> ;q=0.7; expires=3600,
"Mr. Watson" <mailto:watson@bell-telephone.com> ;q=0.1
4.1.1.8 Encryption
Encryption = "Encryption" ":" encryption-scheme 1*SP
#encryption-params
encryption-scheme = token
encryption-params = token "=" ( token | quoted-string )
encoding:描述PGP所使用的encoding或者“armor”,“ascii”表示标准的PGP ASCII包裹,没有包含“BEGIN PGP MESSAGE”和“END PGP MESSAGE”的行,没有版本标识。此加密部分默认为二进制。
例: Encryption: PGP version=2.6.2,encoding=ascii
4.1.1.9 Expires
Expires头域给出了消息内容活动的日期和时间。此头域只用于INVITE、REGISTER方式。
在REGISTER请求中,它指示登记的有效期限。在响应中,服务器指示所有登记最早的期限时间。服务器可以选择一个比客户请求的时间短的时间间隔,但不能比客户请求的时间长。
在INVITE请求中,主叫方可以限制邀请的有效性,例如,客户希望限制搜寻的期限或者会议邀请的期限。如果搜寻在此期限内未完成,代理将返回一个408(Request Timeout)响应。在302响应中,服务器可以建议客户最大的重定向期限。
此域的值可以是一个SIP-date,或者是一个以秒为单位的数字形式。
Expires = “Expires” “:” (SIP-date | delta-seconds)
例: Expires: Thu, 01 Dec 1994 16:00:00 GMT
Expires: 5
4.1.1.10 Timestamp
Timestamp通用头域指示客户何时向服务器发送请求。此头域的值只对客户有用。服务器必须回送完全一样的数值,同时如果它有确切的消息,可以增加一个小数值指示从它接收到请求开始所过去的时间。客户使用timestamp头域来计算到达服务器的round-trip时间,以便调整重传的timeout时间。
Timestamp = "Timestamp" ":" *(DIGIT)[ "." *(DIGIT) ][delay]
Delay = (DIGIT) [ "." *(DIGIT)]
4.1.1.11 Date
Date = "Date" ":" HTTP-date
此处,HTTP-date只能是rfc1123-date。
rfc1123-date = wkday "," SP date1 SP time SP "GMT"
date1 = 2DIGIT SP month SP 4DIGIT
; day month year (e.g., 02 Jun 1982)
wkday = "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun"
month = "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec"
(GMT):Greenwich Mean Time
例如: Date: Tue, 15 Nov 1994 08:12:31 GMT
当请求或者响应被第一次发送时,Date头域指示发送日期和时间,所以,重传将使用与相应的初始同样的Date头域。
4.1.1.12 Accept
Accept域用于INVITE、OPTIONS和REGISTER请求方式中,指示在响应中能够接收的媒体的类型(缺省值为application/sdp)。
4.1.1.13 Accept-Encoding
Accept-Encoding请求头域与Accept头域相似,但它限制在响应中可接受的content-codings。
4.1.1.14 Accept-Language
客户用Accept-Language请求头域向服务器指示它接收原因短语、通话描述符或者消息体中所承载的状态响应时所使用的语言。Proxy可以用此域来帮助选择呼叫的目的地。
4.1.2 entity-header类:
用于描述消息体内容的长度、格式和编码类型等属性,可用于请求消息或响应消息。
实体头域定义了消息体信息之后的内容(如:Content-Length、Content-Type、Content-Encoding),或者如果没有消息体,则定义请求所指示的资源。
entity-header = Content-Type
| Content-Encoding
| Content-Length
4.1.2.1 Content-Type
Content-Type实体头域指示发送给接收者的消息体的媒体类型。
Content-Type=(“Content-Type”| “c”)“:”media-type
例: Content-Type: application/sdp
Content-Type: text/html; charset=ISO-8859-4
4.1.2.2 Content-Encoding
Content-Encoding=(“Content-Encoding” | “e”)”:” 1#content-coding
Content-Encoding实体头域作为“media-type”的一个修饰语。它的值指示适用于实体消息体的其他的内容编码,指示为了获得Content-Type头域所给出的media-type,必须使用的编码方案。Content-Encoding主要用于压缩消息体,而不丢失它底层的媒体类型的标识。
如果多个编码适用于一个实体,那么内容便必须按照他们被应用的顺序列出。
所有的Content-Encoding值都区分大小写。
客户可以将内容编码应用于请求消息体中。如果服务器不能对消息体解码,或者不能识别任何的Content-Encoding值,它必须发送一个415“Unsupported Media Type”响应,在Accept-Encoding头域中列出可以接受的编码。
服务器可以将内容编码应用于请求消息体中,但它只能使用请求的Accept-Encoding头域中所列出的编码。
4.1.2.3 Content-Length
Content-Length实体头域指示消息体的长度。形式上以八个比特为一个字节。
Content-Length = (“Content-Length” | “l”)”:” 1*DIGIT
应用程序应该使用此域来指示所传送的消息体的大小,而不管实体所用的媒体类Content-Length的值应为非负数,0表示没有消息体。
l 服务器如果收到一个不包含Content-Length域的UDP请求,那么它便认为此请求压缩了包的剩余部分。
l 服务器如果收到一个包含有Content-Length域的UDP请求。但它的值比消息体的实际长度大,客户则应产生一个400类的响应。
l 在UDP包中,如果接收完消息体的最后一个比特后,还有其他的数据,服务器必须将此数据视为另一个消息。也就是说,允许在一个UDP包中包含有多个消息。
l 如果一个响应中未包含Content-Length,客户便认为此响应压缩了UDP包或者数据的剩余部分,直到关闭TCP连接。
例:Content-Length: 3495
4.1.3 request-header类:
为请求头域,只可用于请求消息,它用来传递有关请求或客户机本身的一些附加信息,对请求进行补充说明。客户将关于请求和关于客户自己的其他信息传送给服务器。这些域类似于请求的变量,语义上相当于可编程语言方式调用的参数。请求头域的扩展与通用头域相同。
request-header = Authorization
| Contact
| Hide
| Max-Forwards
| Organization
| Priority
| Proxy-Authorization
| Proxy-Require
| Route
| Require
| Response-Key
| Subject
| User-Agent
4.1.3.1 authorization
客户通过一个Authorization头来重新测试请求。
Authorization = “Authotization”“:”“pgp”
*(“;”pgp-response)
pgp-response = realm | pgp-version | pgp-signature | signed-by | nonce
pgp-signature = “signature”“=”quoted-string
signed-by = “signed-by”“=”<”>URI <”>
用户必须在重新提交此请求之前增加CSeq头。此表示必须与请求的From头相联系,除非提供了signed-by参数。
pgp-signature:由ASCII码包裹的PGP标识,出现在“BEGIN PGP MESSAGE”和“END PGP MESSAGE”之间,没有版本标识。如果重新侵入并不担心的话,服务器可以不产生nonce。不产生nonce避免了增加其他形式的请求,401响应和可能的ACK消息,也减少了round-trip时间的耽搁。
使用ASCII码包裹的版本,与包含二进制的信号相比,减少了25%的空间利用率,但对于接收者将它们组合到一起来说却很容易。一般信号为200比特长。PGP信号机制允许客户简单地将请求传给一个外部的PGP程序。此依赖于代理服务器不允许改变头域的顺序或者头域内容的这么一种需要。
realm:复制于相关的WWW-Authenticate头域的参数。
signed-by:当且仅当请求未被From域的实体所标记时,signed-by指示所标
记的实体的名称,表现为一个URI。
标记了的SIP消息地接收者应该丢弃任何在Authorization域之上的end-to-end域,因为他们可能是被路由器或者代理故意增加的。
4.1.3.2 Proxy-Authorization
Proxy-Authorization请求头域允许客户向要求验证的代理来鉴别自己。
Proxy-Authorization头域的值由信任组成,此信任包含了用户代理向代理提供的验证信息和/或被申请的资源领域(realm of the resource requested)。
Proxy-Authorization = "Proxy-Authorization" ":" credentials
与Authorization不同,
Proxy-Authorization头域只应用于使用Proxy-Authenticate域要求验证的下一个输出的代理。
当有多个代理时,Proxy-Authorization头域被接受信任的第一个输出代理所使用。
一个代理可以将信任从客户请求通过中继传到下一个代理,这种方式可以作为一种代理之间合作验证一个给定请求的机制。
4.1.3.3 Proxy-Require
Proxy-Require头域用来指示代理必须支持的一种特征,即是否需要代理。如果不支持,对于客户,任何Proxy-Require头域特征必须被代理所否定。代理服务器将此域与Require域等同看待。
4.1.3.4 Require
客户使用Require请求头域,通知UAS客户希望服务器所支持的选项,以便合适地处理请求。如果服务器不能识别此选项,它必须返回420(Bad Extension)响应,在Unsupported头中列出它不能识别的选项。
Require = “Require” “:” 1#option-tag
代理和重定向服务器必须忽略不可识别的特征。如果一个特定的扩展名需要中介设备支持,那么此扩展名必须在Proxy-Require域中标记。
4.1.3.5 Response-Key
Reponse-Key =”Response-Key””:””pgp”pgp-eparams
pgp-eparams = 1#(pgp-version | pgp-encoding | pgp-key)
pgp-key = “key””=”quoted-string
如果ASCII编码通过编码参数来请求,key参数则包含了用户的公共密钥(从pgp key ring用“pgp –kxa user”解得的)。
4.1.3.6 Priority
Priority请求头域指示了客户所认为的请求的紧急程度。
Priority ="Priority" ":" priority-value
priority-valur="emergency"|"urgent"|"normal"|"non-urgent"
推荐:值"emergency"仅用于生命,肢体,财产处于即将来临的危险之中时使用(此头域通常与Subject头域联合使用)
4.1.3.7 Hide
客户使用Hide请求头域来指示:它希望对随后的代理和用户代理隐藏Via头域指示的路径。此头域的使用有两种形式:Hide:route和Hide:hop。Hide头域通常由客户用户代理来增加,但也可以由发送路径上的任何代理增加。
如果一个请求包含了"Hide:route"头域,所有紧跟的代理应该隐藏它们先前的hop。如果请求包含了"Hide:单脚跳"头域,只有下一个代理应该隐藏它先前的hop,然后删除此Hide选项,除非它也想要保持匿名。
除非确实需要将路径保密,否则最好不要使用Hide头域;Hide域的使用给代理增加了额外的处理开销和限制,同时可能产生482(Loop Detected)响应,这种情况在未使用Hide 头域时可以避免。
Hider 头域有如下语法定义:
Hide = "Hide" ":" ("route" | "hop")
4.1.3.8 Route
Route请求头域决定了请求的路由。每一个主机将删除第一个入口,然后将此请求代理到那个入口所列的主机处,将它作为Request-URI。
Route =” Route” “:” 1#name-addr
4.1.3.9 Max-Forwards
Max-Forwards请求头域适用于任何请求方式,用来限制前转请求的代理或者网关的数目。当客户跟踪一个出现了错误或者循环的请求链时,也可以使用此头域。
Max-Forwards="Max-Forwards"":" 1*DIGIT
Max-Forwards值表明了此请求消息允许被前转的剩余次数。
对于接收到包含有Max-Forwards头域的请求的代理或者网关来说,它必须检测并且修改此头域先前的值,以便前转此请求。如果域值是0,那么接收者禁止前转此请求。相反,对于OPTIONS和REGISTER方式的请求来说,它(接收者)必须将自己作为最终的接收者来作出响应。对于其他的方式,服务器应返回483(Too many hops)响应。
如果接收到的Max-Forwards域值大于0,那么前转的请求中的Max-Forwards域的值必须应减1
4.1.4 response-header类:
为响应头域,只可用于响应消息,它用来传递有关响应的附加信息,对响应进行补充说明,如有关服务器的信息和需要作出的下一步动作的提示等;允许服务器发送关于响应的无法放在Status-Line中的其他信息。这些头域给出了关于服务器和关于进一步访问由Request-URL指示的资源的信息。响应头域的扩展与通用头域相同。
response-header = Allow
| Proxy-Authenticate
| Retry-After
| Server
| Unsupported
| Warning
| WWW-Authenticate
4.1.4.1 Proxy-Authenticate
Proxy-Authorization请求头域允许客户向要求验证的代理来鉴别自己。
Proxy-Authorization头域的值由信任组成,此信任包含了用户代理向代理提供的验证信息和/或被申请的资源领域(realm of the resource requested)。
Proxy-Authorization = "Proxy-Authorization" ":" credentials
与Authorization不同,Proxy-Authorization头域只应用于使用Proxy-Authenticate域要求验证的下一个输出的代理。当有多个代理时,Proxy-Authorization头域被接受信任的第一个输出代理所使用。一个代理可以将信任从客户请求通过中继传到下一个代理,这种方式可以作为一种代理之间合作验证一个给定请求的机制。
4.1.4.2 WWW-Authenticate
WWW-Authenticate=”WWW-Authenticate””:””pgp”pgp-challenge
pgp-challenge=*(“;”pgp-params)
pgp-params=realm | pap-version | pgp-algotithm | nonce
realm=”realm””=”realm-value
realm-value=quoted-string
pgp-version=”version””=” <”>digit*(“.”digit)*letter<”>
pgp-algorithm=”algorithm””=”(“md5” | ”sha1” | token )
nonce=”nonce””=”nonce-value
nonce-value=quoted-string
realm:显示给用户的一个字符串,以使用户知道使用哪一个身份。此字符串应该至少包含执行验证的主机名,也可以另外表示可能接入的用户的收集。一个例子是“Users with call-out privileges”
pgp-algotithm:此参数的值表明了用于产生标识(信号)的PGP消息完整性检验方法(MIC)。默认为“md5”。“md5”表示MD5检验码,“sha1”表示SHA.1算法。
pgp-version:PGP的版本,客户必须使用。通常的值时“2.6.2”和“5.0”,默认为5.0。
nonce:一个经过说明的服务器数据串,每当产生一个401响应时,此数据串便被唯一产生。建议使用base64或者十六进制的数据串。此nonce的内容是独立实现的。其实现的质量依赖于一个好的机会。因为nonce只用于阻止重新的侵入,所以对于服务器就方便来说,单元中的一个时间标记就已足够。由于在呼叫建立周期中的重新侵入只有有限的作用,所以几秒钟的时间标记通常应该是足够的,在此情况下,服务器并不保留此nonce的记录。
4.1.4.3 Retry-After
Retry-After头域用在503(Service Unavailable)响应中,向提出申请的客户指示,此服务预计多长时间无效。用在404(Not Found),600(Busy)和603(Decline)响应中,指示被叫方多长时间内再次有效。此域的值可以是SIP-date和以秒为单位的整数值。
REGISTER请求用“Contact: *; expires:0”删除登记时可以使用Retry-After头域。此时,Retry-After域值指示用户多长时间内可以再次可达。注册服务器器对未来的呼叫作出响应时可以包含此消息。可以使用一个commend选项来指示关于重新呼叫的其他消息。“duration”选项参数指示从有效的初始时间开始,多长时间内被叫方有效可达。
Retry-After = ” Retry-After” ”:” (SIP-date | delta-seconds)
[comment] [“:” “duration””=”delta-seconds]
4.1.4.4 Server
Server响应头域包含了关于UAS用来处理请求的软件的信息。
Server = "Server" ":" 1*( product | comment )
product = token ["/" product-version]
product-version = token
例如: Server: CERN/3.0 libwww/2.17
product:所使用的服务器;
comment:服务器中的重要部分。
如果响应通过代理来前转,那么代理禁止修改此Server响应头域,它应该包含一个Via头域。
4.1.4.5 Warning
Warning响应头域中包含了关于响应状态的其他信息。
Warning = "Warning"":" 1#warning-value
Warning-value = warn-code SP warn-agent SP warn-text
Warn-code = 3DIGIT
Warn-agent = (host[":"port]) | pseudonym
Warn-text = quoted-string
一个响应中可以有多个Warning头域。
"warn-text"使用自然语言。
任何一个服务器都可以在响应中加入Warning头。代理服务器必须将Warning头域加在任何一个Authorization头域之前,由于此限制,Warning头域必须加在任何已存的未被signature覆盖的Warning域之后。代理服务器禁止删除它所接收到的响应中的任何Warning头域。
当响应中有多个Warning头域时,用户代理应该尽可能将它们按照在响应中出现的顺序都显示出来。如果不能全部显示,用户代理应显示在响应中出现的较早的警告。
"warn-code"包含了三个数字,第一个数字"3"表示SIP的专用警告。
下面列出已定义的警告,需要注意的是:所有的警告都由通话描述引起。
300--329:通话描述中的关键字出现的问题;
330-339:通话中所申请的基本网络业务相关的警告;
370-379:通话描述中所申请的定量的QoS相关的警告;
390-399:不属于以上所述类型的警告的混杂。
300:不兼容的网络协议; 301:不兼容的网络地址格式;
302:不兼容的传输协议; 303:不兼容的带宽单元;
304:无效的媒体类型; 305:不兼容的媒体格式;
306:无法识别的属性; 307:无法识别的通话描述参数;
330:无效的多点传送;(用户位置不支持多点传送)
331:无效的单点传送;(用户位置不支持单点传送,通常是由于防火墙的
存在)
370:无效的带宽;(带宽数超过允许范围)
399:混杂的警告;(接收到此警告的系统禁止自动采取措施)
10 :Response is stale(旧的响应)当响应是旧的时,必须包含。
11 :Revalidation failed(重新生效失败)由于重新发送响应失败,只
能返回旧的响应时,必须包含。
12 :Disconnected operation(非连接操作)
13 :Heuristic expiration(探索超时)
14 :Transformation applied(已用过的事务)
99 :Miscellaneous warning(混杂的警告)
4.1.4.6 Allow
Allow实体头域列出了Request-URI指示的资源所支持的方式集。此域的目的是通知接收者与资源相联系的有效方式。在405(Method Not Allowed)响应中必须有Allow头域;在OPTIONS响应中应该有Allow头域。
Allow = “Allow”“:” 1#Method
4.1.4.7 Unsupported
Unsupported响应头域列出了服务器不支持的特征。(只用于420响应)
Unsupported = “Unsupported” “:”1#option-tag
4.2 响应代码
4.2.1 1xx Informational(通知)
1xx |
| Informational(通知) | 服务器或代理正在执行处理,终端应该等待响应。如果服务器需要200毫秒以上的时间进行处理,则向终端发送1xx响应。服务器可以发送多个1xx响应,终端不需发送ACK请求。 |
| 100 | Trying | 呼叫进行期间有一些未指明的行为,如正在执行数据库请求,但是用户还没有被定位。 |
180 | Ringing | 用户代理已经定位注册用户的地址,正在向被叫用户振铃。 | |
181 | Call Is Being Forwarded | 代理服务器正在将呼叫进行转接。 | |
182 | Queued | 呼叫需要排队,当被叫可用的时候,将返回最终的响应。The reason phrase 将给出当前呼叫的状态,如"5 calls queued; expected waiting time is 15 minutes". |
4.2.2 2xx Successful
2xx | 200 | Successful | 请求成功,停止查询。 |
4.2.3 3xx Redirection(重定向)
3xx |
| Redirection(重定向) | 3xx 响应给出用户新的位置,或者能够满足呼叫的另一个服务器,主叫应该终止当前查询,开始新的适当的查询。 任何重定向响应都不能列出Via中的地址,以防止forwarding loops,同时用户代理或者代理服务器必须检查从重定向服务器返回的地址,确认与以前尝试过的地址不相同。 |
| 300 | Multiple Choices (多种选择) | 响应返回几个可选择的地址,用户或用户代理可以首选一个发出连接请求。 响应包含一个资源特征和位置的列表,通过这个列表,用户或用户代理可以选择适合的目的。实体的格式必须由Content-Type 头域中的媒体类型指定。格式的选择也要在Contact 域中指出。 与HTTP不同,SIP应答将包含几个Contact域或一个Contact域中的地址列表。用户代理将使用Contact头域的值自动的进行重定向,或者让用户自己选择。可是,规范里并没有定义这些自动选择的标准。 这个状态响应适用范围:被叫可以通过几个不同的位置访问,同时服务器不愿意或不能代理这个请求。 |
301 | Moved Permanently(永久移动) | 不能由Request-URI 中的地址找到用户,客户端必须根据响应的Contact头域给出的地址重发请求。主叫应该使用新的值更新所有的本地目录,地址簿,用户位置缓存,并把请求重定向到列出的地址。 | |
302 | Moved Temporarily(临时移动) | 客户端必须根据响应的Contact 头域给出的地址重发请求。重定向的时间可以由Expires header指定。如果没有明确的期限,这个地址只能在这次呼叫中有效,不能被以后的呼叫使用。 | |
305 | Use Proxy(使用代理) | 请求必须通过响应的Contact field指定的代理服务器转交,Contact field给出了代理服务器的URI。接受者可以通过代理服务器重复这个请求。 305响应只能被用户代理服务器产生。 | |
380 | Alternative Service(替换服务器) | 呼叫不成功,但是可以选择替代的服务器。替代服务器由响应的message body 描述。消息体的具体格式并没有具体定义,等待以后在标准化。
|
4.2.4 4xx Request Failure(请求失败)
4xx |
| Request Failure(请求失败) | 4xx响应定义了服务器的失败响应,客户端不应该重新发送相同的请求(例如可以加入适当的鉴权)。不过,同样的请求发到其他的服务器有可能成功。 |
| 400 | Bad Request | 请求包含错误的语法,不能被理解。 |
401 | Unauthorized(未经授权) | 请求需要用户鉴权。 | |
402 | Payment Required | 现在未定义 | |
403 | Forbidden(禁止) | 服务器接收了请求,但是拒绝接受,不管是否通过鉴权,不要再次发送请求了。 | |
404 | Not Found(没有找到) | 服务器明确指出Request-URI指定的用户在自己的域中不存在;如果Request-URI指定的域与任何请求的接收者所控制的域都不匹配,这个状态也将被返回。. | |
405 | Method Not Allowed(不允许使用该方法) | 在Request-URI指定的地址中,Request-Line 列出的方法是不允许的,这个响应应该包含Allow header field ,包含一个列表,列出在本地址上所有允许的操作。 | |
406 | Not Acceptable(不接受) | 请求的资源可以发送一个响应,其中的accept headers中列出了不被接受的请求的详细描述。 | |
407 | Proxy Authentication Required(代理服务器需要鉴权) | 这条相应代码于401相像,但是407指出的是客户机必须首先在代理服务器上通过鉴权,代理服务器必须返回一个Proxy-Authenticate header field,允许通过代理服务器查找请求的资源。客户机可以使用一个适当的Proxy-Authorization header field重新发送这个请求。 这个状态码是在通过通信通道时使用的(例如通过电话网关),而不是被叫要求鉴权。 | |
408 | Request Timeout(请求超时) | 在Expires request-header field规定的时间内,服务器没有响应。例如不能为用户定位。客户机可以稍候重发请求,不需更改请求内容。 | |
409 | Conflict(冲突) | 由于与现有的资源冲突,请求不能被完成。 当前的请求在REGISTER中的参数与已存在的注册相冲突。 | |
410 | Gone(不存在) | 请求的资源在服务器上已经不存在而且不知道转移到了什么其它地址。 这种状况被认为是永久的。如果服务器并不知道或难以确定这种状况是不是永久的,那么应该返回404状态代码。 | |
411 | Length Required(需要长度) | 服务器因为需要Content-Length 定义而拒绝接受请求。客户机在添加了一个合法的Content-Length header field 来指出消息体的长度之后,可以重发请求。 | |
413 | Request Entity Too Large(请求实体太大) | 因为请求实体的长度大于服务器能够处理的最大长度,所以服务器拒绝请求。服务器将关闭连接,以防客户机继续执行该请求。 如果这种情况是暂时的,服务器将返回Retry-After header field来指出客户机需要等待多长时间以后才能重新尝试连接。 | |
414 | Request-URI Too Long(Request-URI 太长) | 由于Request-URI 太长,超过了服务器的处理能力,而被服务器拒绝。 | |
415 | Unsupported Media Type(不被支持的媒体类型) | 服务器拒绝提供服务,因为请求的消息体使用了不被请求资源支持的格式,服务器必须用Accept, Accept-Encoding and Accept-Language header fields返回一个列表,指出支持的格式。 | |
420 | Bad Extension(错误的扩展) | 服务器不能识别请求头域中指定的协议扩展。 | |
480 | Temporarily Unavailable(临时的不可用) | 被叫和系统成功连接,但是被叫现在临时不可用,例如没有logged in 或者以一种不能与被叫通信的方式logged in 。这种响应应该包含Retry-After header 来指出最好何时重新呼叫。这个错误不排除用户可能在其他位置成功连接。这种响应不会终止任何查询。reason phrase可以指出更加精确的被叫不可用的原因,这个值也可以被用户代理更改。 响应码 486 (Busy Here) 可以用来指出更加精确的呼叫失败的原因。 这个响应码也可以由重定向服务器返回,指出虽然确认了Request-URI中指出的用户,但是当前没有可用的地址提供给主叫。 | |
481 | Call Leg/Transaction Does Not Exist | 这个状态码在以下两种状况下返回:服务器接收到了BYE请求,但是与任何已存在的call leg都不符合;或者是服务器接收到了CANCEL请求但是与任何已存在的呼叫事务都不符合。(服务器将简单的丢弃ACK请求,并把他认为是一个不知道的事务) | |
482 | Loop Detected(检测到Loop) | 服务器收到一个请求,其中的Via域包含自己。 | |
483 | Too Many Hops(太多的Hop) | 服务器收到的请求,其Via纪录的Hop数超过了Max-Forwards header field所允许的最大数量。 | |
484 | Address Incomplete(地址不完整) | 服务器收到的请求包含的To address 或 Request-URI 不完整,需要提供完整的信息。 这个状态码可以用来与拨号交互(overlapped dialing),客户端并不知道拨号的长度,客户端不断的扩展字串长度,提示用户继续输入,直到不再接收到484状态码为止。 | |
485 | Ambiguous(不明确) | 请求中提供的被叫的地址不明确。响应可以在Contact headers包含一个近似地址的列表。 这个有提示作用的地址列表可能会侵犯其他用户或组织的隐私权,应该可以设置服务器返回404响应(Not Found),或者限制列出替换地址。 Example response to a request with the URL lee@example.com : 485 Ambiguous SIP/2.0 Contact: Carol Lee <sip:carol.lee@example.com> Contact: Ping Lee <sip:p.lee@example.com> Contact: Lee M. Foote <sip:lee.foote@example.com> 一些email 和voice mail系统提供了这样的功能。 这个状态码与3xx是有区别的。300指出的是不管选择什么都能到达同一个人或同一种服务,对3xx来说,自动选择或顺序查找给出的地址都是有意义的。 但是对485响应,用户的介入是必需的。 | |
486 | Busy Here(忙) | 被叫的终端系统连接成功,但是被叫不想或不能接听。这个响应会在Retry-After header中包含一个合适的时间。用户也可以使用其他的服务,例如通过voice mail service。这个响应不会中断任何查询。 如果客户知道不会有任何终端系统接受呼叫,那么就应该使用 600 (Busy Everywhere)。 |
4.2.5 5xx Server Failure(服务失败)
5xx |
| Server Failure(服务失败) | 当服务器本身错误时,返回5xx响应。5xx响应并不表示最终错误,如果其他的可能的地址还没有尝试过,就不能结束一个查询。 |
| 500 | Server Internal Error(服务器内部错误) | 服务器内部的未预期的情况导致不能完成服务,客户机将显示详细的错误情况,可以在几秒钟后重试请求。 |
501 | Not Implemented(不能实现) | 服务器不支持请求的操作,不能完成请求。当服务器不能识别请求的方法并且没有能力为任何提出这种方法的用户提供服务,则可以返回这个错误代码。 | |
502 | Bad Gateway(错误的网关) | 一个作为网关或代理的服务器,当尝试完成请求时从下游服务器接收到了错误的响应 | |
503 | Service Unavailable(服务不可用) | 当前服务器不能接受请求,可能是过载或正在维护,这意味着这是临时状况,可能延迟一段时间后这种状况就会减轻。如果知道确切时间,Retry-After header将会指出。 如果没有给出 Retry-After ,那么客户端应该把这个响应与500响应等同对待。 Note: 并不是所有服务器在过载的时候会返回503响应,一些服务器在过载的时候会简单的拒绝连接。 | |
504 | Gateway Time-out(网关超时) | 作为网关的服务器,不能从其连接的服务器(如位置服务器)获得及时的响应。 | |
505 | Version Not Supported(不支持的版本) | 请求中列出的SIP协议版本不被服务器支持或拒绝支持,响应将包括一个实体,指出为什么这个版本不被支持,和服务器支持的其他协议。这个实体的定义将在以后实现。 |
4.2.6 6xx Global Failures(全局错误)
6xx |
| Global Failures(全局错误) | 6xx响应指出这是关于指定的用户的最终信息,而不仅仅是Request-URI中指出的实例请求。(the particular instance indicated in the Request-URI.)所有未来的对该用户的请求都会失败,还未结束的对该用户的查询都应该中断。 |
| 600 | Busy Everywhere | 被叫的终端系统连接成功,但是被叫忙,不希望现在接听呼叫,响应可以在Retry-After header指出一个合适的时间再呼叫。如果被叫不想提供一个原因(declining the call),那么被叫要使用603 (Decline)。如果用户知道所有的终端设备(如语音信箱)都不会应答,则使用这个响应,否则使用 486 (Busy Here) |
603 | Decline(拒绝) | 被叫的终端设备连接成功,但是被叫明确地指出不想或不能接听。相应可以在Retry-After header指出一个合适的时间再呼叫。 | |
604 | Does Not Exist Anywhere(不存在) | 服务器指出用户提供的To request field 不存在,任何查找都没有结果。 | |
606 | Not Acceptable(不接受) | 用户代理连接成功,但是会话的某些方面例如被请求的媒体、带宽、地址类型不被接受。 606 (Not Acceptable)响应意味着,用户想要连接,但是会话描述不能被完全接受。606 (Not Acceptable)响应可以在Warning header field中包含一个不能连接的原因列表。Reasons are listed in Section 6.41. 这个响应是希望不要频繁的进行协商,当一个新的用户被邀请加入一个已存在的会话,就不必要协商了。(It is hoped that negotiation will not frequently be needed, and when a new user is being invited to join an already existing conference, negotiation may not be possible.) 这个消息由邀请发起者来决定606响应是否起作用(act on)。 |