笔者在前面的章节中已经针对一些基础概念做了比较全面的分析和详解,通过对这些必要的基础概念的分享,读者可以对SIP的基础骨干有了一个清晰的认识。万里长征第一步。学习任何知识,都需要我们从基础轮廓开始,慢慢接触细节知识。我们在以前的学习中可以获知,SIP协议实际上是基于HTTP协议发展而来的(SIP协议不是HTTP协议的扩展),因此,它的基本操作流程也同样符合HTTP协议的基本原理。进一步来说,其基本的处理流程就是一个请求和响应的流程。如果读者需要进一步了解其SIP流程和基本的概念,可以查阅:
SIP协议及新IP企业通信网络技术概论-核心SIP技术介绍-2
SIP协议及新IP企业通信网络技术概论-核心SIP技术介绍-2

我们按照以上图例根据不同的呼叫业务可以进一步解读出SIP消息中关于请求和协议的更多的技术细节,最基础的两个大类就是请求methods和响应码,请求methods可以支持不同的请求,响应码也根据对端状态支持了非常不同的响应码。在请求和响应交互中,通过不断变换的SIP头进行进一步的协商来完成呼叫流程。所以,我们在本章节的讨论中,我们将对SIP消息核心知识进行全面讨论,主要包括通常使用的请求methods(13或者14种methods),响应码(1xx-6xx)和SIP头。在具体实战的操作过程中,技术人员同样需要通过双方的交互信息来对流程做相应的处理,也需要这些交互消息来排查问题。
注意,我们这里所说的SIP消息和SIP规范中的message有着非常明显的不同。此消息和彼消息是完全不同的内涵。一般来说,SIP消息就是请求和响应的消息,客户端对服务器端发送请求消息,服务器端对客户端返回响应消息。我们这里通常所说的SIP消息是指一般的SIP请求和响应消息,而在SIP规范中的message是SIP规范的一种扩展的method,它允许SIP终端之间发送即时消息(instant message)。
1、SIP请求methods和响应码
请求和响应是SIP响应的两大核心要素。这两大要素结合SIP头决定着呼叫的最终结果。在具体的SIP请求中,根据RFC3261,SIP请求根据SIP呼叫请求的不同环境,SIP请求又细分6种不同的methods,这6种methods是RFC3261规范所规定的methods,另外还有8种常用的扩展SIP methds,这8种methods不是RFC3261的规范规定的methods,它们是通过SIP的扩展协议获得的支持。所以,我们这里总共介绍14种不同的常用的SIP请求方式。
在SIP请求methods中,我们经常遇到的SIP请求methods包括:
- REGISTER:用来注册一个用户代理,通过临时绑定一个用户代理的URI到AOR地址,这样服务器端能够获悉其用户代理的位置。简单来说,它负责注册contact消息。
- INVITE,通过邀请一个用户参与到会话来发起一个呼叫。另外,INVITE也可以修改会话。
- ACK,一个acknowledgement或者消息确认是作为一个对200 OK响应或其他响应的一个确认响应。这些响应是初始INVITE请求的结果,此时应该会产生会话,ACK仅对INVITE负责或者(re-INVITEs)。
- CANCEL用来取消待处理的请求。
- BYE用来指示结束呼叫或者会话。
- OPTIONS 负责查询服务器端的媒体支持能力。
- INFO,负责mid-session的SIP信令消息之间的通信,它是一个RFC3261的扩展协议,具体规范参考RFC2976。具体使用示例包括PSTN网关的PSTN信令消息,传输会话中中需要传输的DTMF,计费账号余额,无线移动端的无线信号状态,会话之间传输图片或者其他非媒体的数据。
- PRACK,其全称是Provisional ACK,从字面意思可以看出,它本身是一个临时的ACK。因为它是一个临时的响应,所以它仅用来对1xx临时响应做出响应。在某些情况下,如果初始INVITE请求没有携带SDP消息体的话,在1xx临时响应后,PRACK可以包含相关的SDP消息体。另外需要注意,为了验证其可靠性,每个临时响应(例如从UAS来的183响应)都给定一个序列号,通过响应消息中的RSeg头来传输,从UAC来的PRACK的消息中包含一个RAck头,表示一个针对临时响应的序列号的确认。它也是通过一个RFC3261规范的扩展协议来支持,具体规范参考RFC3262。
- Refer 用来转接呼叫,也可以用来联系外部资源。Refer method是SIP规范的扩展协议。具体关于定义Refer method规范,读者可以查阅RFC3515。
- SUBSCRIBE用来在稍晚时间请求一个事件提醒或一系列事件。常见的示例是用来订阅一个请求提示(Notification),当某人的IM在线状态发生改变(离线,在线,忙状态等)以后,对其发送提示事件。关于订阅的扩展协议,读者可以查阅RFC3265。
- NOTIFY用来对已订阅的事件发送notify提示消息,它也可以通过SIP服务器端对SIP客户端发送客户端事件提示,例如语音邮箱留言等。读者也可以按照RFC3265的规范进一步了解notify提示method。
- Update用来支持客户端更新会话协商中的一些参数,例如媒体流的参数以及编码等。注意,update不会影响dialog的状态。关于更多update method,读者可以参考SIP的扩展协议RFC3311。
- Publish发布和注册一样,它也允许用户创建,修改和移除状态,不同的是它负责发布事件状态,用户可以根据事件本身状态来提示订阅用户。具体规范查阅RFC3903。
- Message method是SIP的扩展协议,用来传输请求的消息体中的即时消息。通过SIP 初始会话技术,结合在线状态和即时消息构成了当前最强大的即时通讯系统。目前,即时消息或者IM使用已经非常普及,包括我们的QQ等。但是,SIP的强大之处在于提供了在线状态应用,对基于会话初始应用机制提供支持,但是对即时消息支持不是SIP的优势。因此,读者可以看到,在SIP应用中即时消息的使用仍然不是市场主流。关于SIP 消息的规范读者可以查阅RFC3428,关于在线状态和即时消息规范读者可以查阅RFC2778和RFC2779。
关于以上SIP method的其他深入讨论,读者可以查阅参考链接,或者阅读笔者的历史文档。因为篇幅原因,这里不再介绍。一些比较常见的method,例如, 100rel/PRACK,读者可以查阅历史文档:
SIP拓展协议RFC3262概述和100rel/PRACK详解
2、SIP请求和响应中的header
前面我们介绍了SIP的methods和它的一些控制协议支持的methods。在各种methods中,INVITE是我们最常用的method。在这些methods中需要通过各种header来进行通信协商。在本章节我们重点介绍一下method中的header和其响应中的header。因为篇幅所限,我们这里仅介绍INVITE method和其响应,读者可以查阅SIP规范和其具体扩展协议深入了解更多的用途说明。以下是根据RFC3261官方介绍的一个基本的示例

INVITE的SIP头 |
INVITE 200 OK响应的SIP头 |
||
头名称 | 说明 | 头名称 | 说明 |
Request-Line | 表示请求类型,INVITE中包含目的地UA的SIP URI和其SIP以及版本 2.0 | Status-Line | 表示正在使用SIP 2.0, 返回 200 OK。 |
Via | 表示传输层协议使用,使用UDP,包含响应返回的IP地址和端口,branch ID(不可修改的)确认事务的唯一性,和RPORT | Via | 服务器端插入的头,支持回环检测,允许 200 OK找到返回到终端的路径。返回此请求的响应,要注意,如果有route的话,应该发route;如果没有route,则发Contact返回响应;如果没有Contact,则发From返回。 |
From | 显示呼叫方信息,呼叫方SIP URI,事实上是呼叫方的caller ID | From | 初始呼叫方信息和其SIP URI |
To | 显示被呼叫方的信息 | To | 初始被呼叫方UA |
Call-ID | 是一个全局ID,针对具体某个dialog,在此dialog中,所有请求和响应事务都具有此同一Call-ID。 | Call-ID | 是一个全局ID,针对具体某个dialog。 |
CSeq | 用来确认事务和其事务的处理顺序。在呼叫中,每个呼叫对象会维护自己的CSeq,并且会根据成功状态会依次递增。 | CSeq | 用来确认事务和其事务的处理顺序。在呼叫中,每个呼叫对象会维护自己的CSeq,并且会根据成功状态会依次递增。 |
Contact | 显示一个SIP URI,表示在后续请求中可以使用这个SIP URI联系到此agent。 | Contact | 显示一个SIP URI,表示在后续请求中可以使用这个SIP URI联系到此agent。 |
Allow | 此agent支持的一个methods 列表 | Allow | 此agent支持的一个methods 列表 |
Max-Forwards | 用来限定代理或者网关前转到下一跳的最大数量,每经过一个代理或者网关此值会递减1,默认推荐值为70. | ||
Content-Type | 描述在此应用中的内容,应用,SDP类型。 | Content-Type | 描述在此应用中的内容,应用,SDP类型。 |
Proxy-Authorization |
用来支持对proxy代理的安全信息。 | ||
Supported | 描述此agent支持的扩展,例如100rel,timer,replaces 等等。 | ||
User-Agent | 表示具体的代理信息 | User-Agent | 表示具体的代理信息 |
Content-Length | 表示SDP消息体的长度,以byte为单位。 | Content-Length | 表示SDP消息体的长度,以byte为单位。 |
Record-Route | 代理插入的头域值,强制在此dialog中的后续请求通过此代理路由 |
响应中的Via,From,To,Call-ID,CSeq是完全从请求中拷贝过来的。
To,From不会在请求和响应的交互中发生替换。
不同的服务提供商或者SIP终端发送的头信息顺序可能不同,这是符合规范的,例如CSeq和Call-ID的位置顺序发生变化。
Supported/Reqiure的功能支持,客户端通知服务器端需要支持的列表,服务器端返回require的功能列表。
关于以上问题的详解,读者可以进一步了解:
除了以上的关于SIP头的一些介绍以外,在一些对带宽非常敏感的网络环境中,为了节省带宽,SIP协议可以支持SIP头的压缩格式或者缩写,具体的格式如下:
缩写 | Header | 定义协议 | 原始含义 |
---|---|---|---|
a | Accept-Contact | draft-ietf-sip-callerprefs | -- |
b | Referred-By | -refer- | "by" |
c | Content-Type | RFC 3261 | |
e | Content-Encoding | RFC 3261 | |
f | From | RFC 3261 | |
i | Call-ID | RFC 3261 | |
k | Supported | RFC 3261 | "know" |
l | Content-Length | RFC 3261 | |
m | Contact | RFC 3261 | "moved" |
o | Event | -event- | "occurance" |
r | Refer-To | -refer- | |
s | Subject | RFC 3261 | |
t | To | RFC 3261 | |
u | Allow-Events | -events- | "understand" |
v | Via | RFC 3261 |
有时,在某些比较特殊的部署环境中,我们可能会看到一些带X前缀的拓展的头参数值。例如,有时需要对每个终端的声音增益进行调整时,可以通过其扩展到X头来调整。如果需要对话单用户进行定义时,也可以通过X扩展头来定义。这样操作带来的问题是,一些系统如果对X头不支持的话,服务器端可能直接丢弃,并且拒绝解析这些字段,导致很多兼容性问题。因此,RFC6684规范对X扩展进行了说明,X头将不再进行支持。
除了X头以外,P header是一个仍然普遍使用的头域值。它一方面使用在计费消息中,另外一方面主要使用在网络穿越的环境设置中包括SBC用户场景。例如,计费使用的P-Charge-Info,在可信网络环境中P-Asserted-Identity传输用户认证信息。特别在FCC强制要求美国运营商部署STIR/SHAKEN规范时,P-Asserted-Identity是必要的头之一。关于STIR/SHAKEN,读者可以查阅:
关于SIP P扩展头的完整规范说明,读者可以查阅RFC3325和RFC3455规范。
4、总结
在本文章中,笔者主要介绍了SIP协议中的14个核心的methods,另外根据一般用户场景,我们也介绍了请求和响应中的SIP头主要的头域值介绍。笔者通过最常见的INVITE请求method结合其响应码为大家简单介绍了其头值的具体内容。另外,笔者也讨论了头值的状态变化,在这些header头值中,一些关键的头值在交互中不会发生变化或者修改,这些问题笔者也要注意。
除了RFC3261中一些标准的SIP头以外,SIP支持其他的扩展头,包括X头和P头值扩展,这些头值可以进一步完善具体或者特殊用户场景多其他参数的支持。
虽然笔者尽量在讨论中涵盖SIP规范的关于SIP methods和响应码以及SIP扩展头的全部内容,但是,因为篇幅所限和实际应用示例非常繁多,用户只能通过最常见的INVITE和响应来为读者解读SIP核心概念,希望起到一个抛砖引玉的作用,其他的methods可以根据读者提供的RFC规范线索做深入了解。
参考资料:
- https://datatracker.ietf.org/doc/html/rfc2976
- https://www.ietf.org/rfc/rfc3262.txt
- https://datatracker.ietf.org/doc/html/rfc3311
- https://www.ietf.org/rfc/rfc3428.txt
- https://datatracker.ietf.org/doc/html/rfc2976
- https://datatracker.ietf.org/doc/html/rfc3265
- https://www.ietf.org/rfc/rfc3903.txt
- https://datatracker.ietf.org/doc/html/rfc6648
- https://datatracker.ietf.org/doc/html/rfc3455