SIP协议概述

SIP(Session Initiation Protocol)是一种应用层协议,用于在IP网络上发起、管理和终止多媒体会话,例如语音电话、视频会议和即时消息等。其基本功能是允许用户发现和建立通信。它是一种灵活且可扩展的协议,允许添加和修改各种元素以支持新的应用场景。

SIP通过建立会话描述协议(Session Description Protocol,SDP)会话描述信息(Session Description)来描述会话信息,包括媒体类型、编码方式、媒体参数等。SIP使用统一资源标识符(Uniform Resource Identifier,URI)来标识用户和终端设备,可以将一个用户的多个设备关联在一起。通过交换消息,SIP实现了会话的建立、修改和关闭,包括会话控制、用户定位、消息路由和安全管理等。

SIP协议不仅适用于互联网,还可用于企业内部网络、移动通信网络等多种网络环境中。它已经成为企业通信、互联网电视、网络游戏、物联网等领域的标准协议之一。

SIP协议的消息结构

SIP(Session Initiation Protocol)是一个文本协议,它通过文本消息交换的方式实现了会话控制。一个SIP消息包括请求消息和响应消息,每个SIP消息都由三部分组成:起始行、首部和正文。

  1. 起始行:起始行是SIP消息的第一行,它包括了请求方法、URI(Uniform Resource Identifier)和SIP协议版本号(例如SIP/2.0)。

  2. 首部(SIP Header):SIP消息的首部包含了若干个首部字段,用来描述SIP消息的属性、特征、传输路由、身份和数据编码方式等信息。

SIP消息的首部分为请求首部和响应首部,请求首部包含了请求方法相关的参数、目标地址、发送方身份等信息,响应首部包含了响应状态码、响应消息相关的参数等信息。

  1. 正文(SIP Body):SIP消息的正文可包含描述SIP会话必要信息的数据,例如会话描述协议(Session Description Protocol,SDP)描述信息。正文是可选的,可以是任意类型的数据。

SIP消息的结构如下:

请求消息:

1
2
3
4
5
6
7
8
9
10
11
12
INVITE sip:[被叫方URI] SIP/2.0
Via: SIP/2.0/[传输协议] [本机IP地址]:[本机端口号];rport
Max-Forwards: 70
From: "发送方” <sip:[发送方URI]>;tag=[本地标识]
To: <sip:[被叫方URI]>
Call-ID: [唯一标识]
CSeq: 1 INVITE
Contact: <sip:[发送方URI]>
Content-Type: application/sdp
Content-Length: [消息体长度]

[消息体]

在这个请求中,INVITE表示请求的方法,[被叫方URI]是被呼叫方的统一资源标识符,SIP/2.0是版本号,头部域包括了必选头(Via、Max-Forwards、From、To、Call-ID、CSeq和Contact)和可选头(Content-Type、Content-Length),消息正文(即会话描述信息)包含了媒体类型、编码方式等会话参数。

响应消息:

1
2
3
4
5
6
7
8
9
10
11
SIP/2.0 200 OK
Via: SIP/2.0/[传输协议] [中间设备IP地址]:[中间设备端口号];received=[远端IP地址];rport=[远端端口号]
From: "发送方” <sip:[发送方URI]>;tag=[本地标识]
To: <sip:[被叫方URI]>;tag=[远端标识]
Call-ID: [唯一标识]
CSeq: 1 INVITE
Contact: <sip:[中间设备IP地址]:[中间设备端口号]>
Content-Type: application/sdp
Content-Length: [消息体长度]

[消息体]

响应消息的首部与请求消息类似,但包含了不同的头域,例如“From”头域中包含了请求者的信息,而“To”头域则包含了被呼叫方的信息,同时在响应消息中还可以包含自定义的头域。

起始行

请求起始行

SIP请求行包含三个字段:SIP方法、URI和SIP版本。常用的SIP方法包括:

  1. OPTIONS:此方法发送给服务器,用于查询服务器的特性、支持的方法等信息。
  2. INVITE:此方法建立一个会话,这个会话可以是电话呼叫、多方通话、视频会议等,这个方法需要ACK响应来确认建立了会话。
  3. ACK:此方法用于确认服务器响应INVITE请求。
  4. BYE:此方法用于通知终止一个会话,结束当前的连接。
  5. CANCEL:此方法可以取消正在进行的会话。
  6. REGISTER:此方法用于向服务器注册一个URI,这个URI可以是电话号码或者是一个SIP地址。
  7. INFO:此方法用于描述当前状态,例如传输的信号质量等。
  8. PRACK:此方法是用来向服务器确认一个 Provisional Response。
  9. SUBSCRIBE:此方法是用于一个设备订阅一个资源的状态变化,这个订阅和发布机制可以被用于Presence和事件通知。
  10. NOTIFY:此方法用于向订阅者(Subscriber)发送通知,这个方法被用在Presence和事件通知。
  11. UPDATE:此方法用于更改一个会话,例如改变媒体类型等。
  12. MESSAGE:此方法用于发送一个基于文本的消息。

示例:一个SIP请求的起始行

1
INVITE sip:8003@192.168.2.31:5868 SIP/2.0

响应起始行

SIP协议中对响应的分类包括临时响应和最终响应。

临时响应包括1xx系列的状态码,用于表示服务器已经接收到请求并且正在处理,但是还需要更多时间来完成处理。常见的1xx状态码有:

  • 100 Trying:服务器已经收到请求,并且正在处理,但还没有最终的响应结果。
  • 180 Ringing:服务器已经与被叫设备建立了连接,并且正在等待被叫设备响铃。
  • 183 Early Media:是指在SIP呼叫建立过程中,被叫端在来电振铃前就已经开始向呼叫端发送音视频数据。

最终响应包括2xx、3xx、4xx、5xx、6xx系列的状态码,用于表示请求已经被处理完成。常见的最终响应状态码有:

  • 200 OK:请求已经被成功处理。
  • 301 Moved Permanently:被请求的资源已经永久移动到新的位置。
  • 400 Bad Request:请求存在语法错误,服务器无法处理该请求。
  • 404 Not Found:被请求的资源没有找到。
  • 500 Internal Server Error:服务器内部出现错误,无法处理该请求。

示例:一个SIP响应的起始行

1
SIP/2.0 200 OK

头部

SIP头部域分为两类:必选头(Mandatory Headers)和可选头(Optional Headers)。必选头包括From、To、Call-ID、CSeq、Max-Forwards、Via等。可选头包括:Content-Type、Content-Length、User-Agent、Allow、Allow-Event等。SIP头部的字段(键值对)是允许重复的。

SIP协议中全部的必选头包括以下几项:

  1. From:指明发送请求的用户信息,包括发送请求的用户的显示名、sip URI,也可以包括tag参数,用于唯一标识这个用户。主叫

  2. To:指明接收请求的用户信息,包括接收请求的用户的显示名、sip URI,也可以包括tag参数,用于唯一标识这个用户。被叫,但是一般被叫号码在起始行的URI中取

  3. Call-ID:是一个唯一的标识符,用于标识整个会话。

  4. CSeq:包含一系列数字,起始数字由用户代理设定,之后每次SIP交互后该值加1,用于确定消息的顺序。区分事务

  5. Via:指定消息的传输路径,包括SIP消息从哪个地址发送出去以及接收SIP消息的地址,可以包含多个Via头。

  6. Max-Forwards:指明请求可以通过的最大跳数,以保证不会一直在网络中循环转发

这些必选头字段在SIP消息中是必须存在的,如果缺少其中任何一个必选头字段,那么该SIP消息将被认为是不合法的。

示例:一个SIP请求的头部

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Via: SIP/2.0/UDP 192.168.40.101:18627;branch=z9hG4bK7fc6.55001e62.0
Route: <sip;edge-in@192.168.40.101:18627;lr;received=sip:192.168.2.31:5060>
Max-Forwards: 69
From:“80003" <sip:80003@192.168.40.43>;tag=y20K6N39683vD
To: <sip:80003@1dd.com>
Call-ID: f92b77b6-142f-1238-3ebe-00505695d413
CSeq: 6304560 INVITE
Contact: <sip:192.168.40.98:18627;did=807.a80b1f81>
Call-Info: <Answer-After=0>
User-Agent: WMSWMS-mod sofia/1.4.26~64bit
Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,MESSAGE,INFO,UPDATE,REG]STER,REFER,NOT
Supported: timer, path, replaces
Allow-Events: talk, hold, conference, refer
Content-Type: application/sdp
Content-Disposition: session
Content-Length: 276
X-FS-Support: update_display,send info

正文

SIP消息的正文一般包含了媒体相关的描述信息或具体的数据,例如SDP(Session Description Protocol)等。SDP是一个文本格式的协议,主要用于描述多媒体会话的会话参数和媒体流相关的信息,例如媒体类型、编码方式、采样率、传输协议等。

在SIP中,请求消息和响应消息的正文格式都是一样的,一般分为两个部分:会话层描述和媒体层描述。会话层描述包含了会话相关的信息,例如会话的起始时间、结束时间、会话ID等,而媒体层描述则包含了媒体相关的信息,例如媒体类型、编码方式等。

举个例子,以下是一条基于SIP和SDP协议的呼叫请求消息正文的例子:

1
2
3
4
5
6
v=0
o=alice 2890844526 2890844526 IN IP4 atlanta.com
s=-
c=IN IP4 192.0.2.10
t=0 0
m=audio 49172 RTP/AVP 0

在这段SDP描述中,v为协议版本号、o为会话发起者信息、s为会话名称、c描述了使用IP协议的地址和端口、t为会话时间、m描述了音频媒体相关的信息。其中m中的audio表示媒体类型为音频,49172为媒体使用的端口号,RTP/AVP为传输协议类型,0为音频编码方式。

需要注意的是,SIP消息的正文不是必须的,根据需要可以不包含正文或只包含一个空白字符串作为正文。此外,SIP使用了SDP语法描述会话和媒体参数,但实际上支持其他的描述协议,例如XML等。

思考

  1. 主叫号码是哪个字段?
  2. 被叫号码是哪个字段?
  3. SIP终端在哪个头部字段可以查看?
  4. SIP消息头部字段重复会发生在什么情况下?
答案
1. From
2. 起始行或者TO
3. User-Agent
4. 消息需要通过多个代理传输:SIP协议在消息的传输过程中可能会经过许多中间代理,每个代理都可能会往消息中添加自己的“Via”头部字段,以标明消息经过的路由和传输方式。因此,SIP消息中的“Via”头部字段可能会重复出现多次。

事务Transaction

在SIP协议中,事务(Transaction)是指一组有序的请求和响应消息序列,用于实现SIP客户端和服务器之间的交互。每个事务包含了一个客户端发起的请求消息和一个或多个服务器返回的响应消息(即0或多个临时响应和0或多个最终响应)。事务的目的是确保SIP请求和响应消息能够可靠地到达对方,以及在一定时间内得到处理和响应。

SIP中的事务有两种类型:客户事务(Client Transaction)和服务器事务(Server Transaction)。客户事务是由SIP客户端发起的请求消息和对应的响应消息组成的序列;而服务器事务是由SIP服务器收到的请求消息和对应的响应消息组成的序列。

客户端事务由以下消息组成:

  • INVITE:邀请一个用户参与会话的事务。
  • ACK:确认收到一条2xx(成功)响应的事务。
  • BYE:结束呼叫会话的事务。
  • CANCEL:取消未完成的呼叫事务。

服务器事务由以下消息组成:

  • INVITE:表示服务器正在尝试与用户建立一个会话的事务。
  • 1xx:表示服务器接收到请求并正在处理它的事务。
  • 2xx:表示请求已被接受并成功处理的事务。
  • 3xx:表示请求被重定向的事务。
  • 4xx-6xx:表示请求失败的事务。

每个SIP事务都有一个唯一的标识符(Transaction Identifier),用于区分不同的事务。SIP事务的实现可以是在端点或代理服务器上实现的,各自的实现方式可能会有所不同,但是都必须遵循SIP协议的相关规定。

事务标识符的扩展
1. 标识符由请求方法、Call-ID和Branch参数。其中,Call-ID是一个由服务器生成的随机数,用于标识会话,而Branch参数则是由客户端生成的唯一字符串,用于标识该事务的分支。通过这三个参数的组合,可以唯一地标识一个SIP事务。
如果想查看一个SIP事务的唯一标识符,可以查看该事务的消息中的相关头部。例如,针对一个INVITE请求消息,其唯一标识符可以在以下头部中找到:
    - Call-ID: 用于标识会话的唯一ID值
    - CSeq: 包含请求的序列号和请求方法信息
    - Via: 用于识别消息经过的SIP代理服务器,其中包含分支参数(branch parameter)。
这些头部中的信息就可以唯一地标识一个SIP事务。可以通过查找这些头部来确定一个请求/响应消息是否属于同一个SIP事务。
2. 在实际应用中,SIP代理服务器通常会将事务存储在事务状态机中,并用CSeq号作为关键字来唯一标识每个事务。通过这种方式,代理服务器可以维护每个事务的状态,并确保请求和响应能够正确地匹配。

ACK事务

  1. 对于成功的响应,ACK算作单独的响应
  2. 对于失败的响应,ACK和INVITE算作相同的事务

对于SIP协议中的INVITE事务,如果收到成功的200 OK响应消息,那么在确认(ACK)这个响应时,ACK消息被视为独立的事务,即ACK和INVITE算作单独的两个事务。这是因为确认消息(ACK)是“终结”INVITE事务的最后一步,并且在确认消息中仅包含CSeq头部,没有INVITE消息中包含的其他头部。

然而,对于响应消息不是200 OK的INVITE请求,例如4xx错误响应消息或5xx服务器内部错误响应消息,ACK消息被视为和INVITE请求消息是同一个SIP事务。这是因为这些错误响应需要被重试,而ACK消息是这些重试请求的一部分。因此,整个过程被视为一个INVITE事务,其中包括原始的INVITE消息以及后续的ACK请求消息。

需要注意的是,对于其他的非INVITE请求事务,ACK消息会被视为独立的事务,因为这些请求与INVITE请求有不同的响应机制,并且在确认消息中可能包含响应消息中没有的其他头部。

思考

  1. 如何在信令图上区分不同的事务
答案
相同的CSeq值,即为相同的事务

对话Dialog

在SIP(Session Initiation Protocol)中,Dialog(对话)通常是由一系列事务(Transactions)组成的。每个事务由一组独立的请求和响应组成,而Dialog则是由一组在同一个Call-ID下发出的请求和响应消息所组成的。通过事务和Dialog,SIP可以管理呼叫和会话状态,同时还能够处理错误和异常情况。

Dialog通常由以下4个关键元素来定义:

  1. Call-ID:用于标识一个会话的唯一ID,所有的SIP消息都具有同一个Call-ID头部。
  2. From和To:描述SIP消息中的发送方和接收方的标识信息。在Dialog中,From和To头部的标识信息通常是相同的。
  3. CSeq:标识了一个请求的序列号和方法类型(如INVITE、ACK、BYE、CANCEL、OPTIONS等)。
  4. Dialog State:用于描述目前Dialog所处的状态,通常包含了Session Description Protocol(SDP)用于描述媒体传输相关的信息。

Proxy服务器

在SIP(Session Initiation Protocol)中,Proxy服务器是一种特殊的SIP节点,负责转发和处理请求消息。Proxy服务器可以扮演不同的角色,如SIP消费者的代理、SIP提供者的代理或者SIP地址解析服务器(Location Server),以提供多种服务。

SIP代理能够接受呼叫请求消息,并根据用户配置将其路由到合适的SIP代理或终端设备。此外,SIP代理还能够处理网络中的异常和错误情况,以保证呼叫和会话状态的可靠性和稳定性。

SIP代理有两种类型:

  1. Stateful Proxy:即有状态的代理。这种代理会维护会话状态和呼叫状态,并根据会话状态和指令来决定下一步的操作。这种代理常用于路由和负载均衡等场景。

  2. Stateless Proxy:即无状态的代理。这种代理只处理单个消息,并不维护会话状态和呼叫状态。这种代理常见于SIP解析器和SIP防火墙等场景。

Proxy服务器在SIP网络中非常重要,它们可以提供一些关键的功能,如隐藏用户的真实网络地址、提供负载均衡和路由选择等服务。同时,Proxy服务器还可以进行消息过滤、鉴权和记录等操作,以保证SIP网络的安全性和可靠性。

重定向服务器

在SIP(Session Initiation Protocol)中,重定向服务器(Redirect Server)是一种特殊的SIP节点。它我们可以将重定向服务器看作是一个通信的中转站,其主要功能是根据SIP协议规定的重定向机制,将来自用户代理或其他代理服务器的SIP消息转发到指定的资源或服务器。

重定向服务器与代理服务器有很大的相似之处,但其两者在功能上有所不同。代理服务器负责对收到的SIP消息进行路由和处理,但如果请求的目标地址发生了变化,代理服务器就无法处理该请求了,这时就需要使用重定向服务器来完成重定向。

当代理服务器无法找到请求的目标地址时,它会将SIP消息发送到重定向服务器。重定向服务器会查询某个资源的位置(如用户的IP地址或电话号码),并将查询到的位置信息通过SIP消息返回到请求客户端。请求客户端接收到重定向消息后,可以自行向查询到的位置发起新的SIP请求。

重定向服务器在SIP网络中非常重要,它可以帮助客户端快速找到目标资源或服务,同时也可以提高SIP网络的可扩展性和灵活性。

注册服务器

在SIP(Session Initiation Protocol)中,注册服务器(Registrar Server)是一种SIP节点,其主要功能是记录用户的信息和位置。当用户在SIP网络中注册时,他们会将自己的信息和位置注册到注册服务器上。(将AOR分机号与地址信息绑定)当其他用户或代理服务器需要与该用户通信时,就可以通过注册服务器来查找该用户的位置信息。

具体来说,当用户在SIP网络中注册时,它会向注册服务器发送REGISTER请求,该请求中包含了用户的SIP地址和相关信息。注册服务器接收到该请求后,会将该用户的信息和位置记录到数据库中。同时,注册服务器还会向其他代理服务器广播该用户的信息,以便其他用户和代理服务器可以找到该用户。

当其他用户或代理服务器需要与该用户通信时,它们会向注册服务器发送INVITE请求,该请求中包含了目标用户的SIP地址。注册服务器接收到该请求后,会根据已记录的信息找到目标用户的位置,并将INVITE请求转发到目标用户的位置进行处理。这样,用户之间就可以通过SIP网络进行通信了。

注册服务器记录了用户的信息和位置,并协调其他SIP节点之间的通信,从而实现了SIP网络中的会话和通信。

思考

  1. 分机不注册,能否打电话?
答案
可以打电话,不可以接电话。

B2BUA

image-20230512175207504

B2BUA

B2BUA(Back-to-Back User Agent)是指位于SIP(Session Initiation Protocol)网络中的一种特殊类型的代理服务器。B2BUA采用的是中介模式,即它在SIP网络中起到中介的作用,同时也充当了两端用户代理之间的服务代理。在呼叫过程中,B2BUA像两个代理服务器之间的中转站一样,使得两端用户代理之间的通信得以实现。

当SIP呼叫建立时,B2BUA作为第三方代理介入到两端之间。一旦通话建立,B2BUA就会将两端代理看做一个整体进而实现中间信令和媒体的转发。B2BUA可以处理INVITE、ACK、BYE、CANCEL等一系列SIP信令,同时它还可以对连接的参数进行操作,比如更改媒体编解码器和检测质量等。

B2BUA具有许多优点,能够提供更好的SIP服务,包括:

1.提供更多的安全功能:B2BUA可以检测和防止恶意攻击,包括僵尸网络和拨号蠕虫。

2.保持SIP呼叫的状态:B2BUA相对于其他代理服务器而言能够执行更高级别的通话处理,并可以指定更多的通话控制功能。

3.提高网络性能:B2BUA可以提供更好的媒体数据压缩和载荷管理功能,可以减少网络负载,提高网络性能。

Call-leg

在电话或网络通信中,Call Leg指的是呼叫通信路径中的一部分。具体来说,Call Leg是指从呼叫发起方到呼叫接收方的通信路径中的一段路径,可以是使用不同协议和传输媒介的链路上的一段。

在VoIP网络中,通常一个呼叫包含多个Call Leg。例如,从IP电话到被叫方的呼叫可以被看作是两个Call Leg,一个是从IP电话到VoIP网关的Call Leg,另一个是从VoIP网关到被叫方的Call Leg。因此,Call Leg是VoIP呼叫路径中非常重要的概念,它通常与会话描述协议(Session Description Protocol)相关联。

Call Leg的相关概念还包括“呼叫控制Leg”和“媒体Leg”。呼叫控制Leg是基于SIP(Session Initiation Protocol)等呼叫控制协议连接的呼叫路径,主要用于建立、修改和释放呼叫请求。媒体Leg则指呼叫路径上的用于传递语音和音频等媒体数据的链路。

FreeSWITCH

FreeSWITCH是一款自由、开放源代码、跨平台的电话软交换(PBX)平台,支持多种协议(包括SIP、H.323、WebRTC等)和多种音频、视频编解码格式,能够支持呼叫路由、交换和转移,提供了丰富的电话功能,例如语音信箱、呼叫转接、会议、语音识别、语音呼叫中心等。

FreeSWITCH通常作为基础架构,可用于构建各种应用程序,例如电话中心、IVR(Interactive Voice Response)解决方案、多方视频会议系统等。它还可以实现与传统电信网络的互操作性,允许在VoIP网络和公共交换电话网(PSTN)之间进行呼叫交换。

相较于其他电话软交换平台,FreeSWITCH有以下几个突出特点:

  • 灵活性:FreeSWITCH可以通过自定义脚本和模块进行扩展和定制,支持多种通信协议和音频、视频编解码格式的选择;
  • 可扩展性:FreeSWITCH支持集群部署,可通过多台服务器来实现负载均衡和高可用性;
  • 可编程性:FreeSWITCH支持Lua、Python、JavaScript等多种编程语言,可以通过API和事件钩子来实现各种复杂的呼叫控制逻辑;
  • 开放性:FreeSWITCH是一款自由、开放源代码的平台,可以自由使用、修改和分发。

总之,FreeSWITCH作为一款开源电话软交换平台,具有灵活性、可扩展性、可编程性和开放性等特点,为构建高质量、高性能的VoIP应用提供了有力的支持。