跳到主要内容

4. 操作概述 (Overview of Operation)

4 操作概述 (Overview of Operation)

本节通过简单示例介绍 SIP 的基本操作. 本节具有教程性质, 不包含任何规范性声明.

第一个示例展示 SIP 的基本功能: 定位端点, 表达通信意愿, 协商会话参数以建立会话, 以及在会话建立后拆除会话.

Figure 1 展示 Alice 和 Bob 两个用户之间 SIP 消息交换的典型示例. (每条消息都用字母 "F" 和一个数字标记, 便于正文引用.) 在此示例中, Alice 使用其 PC 上的 SIP 应用 (称为 softphone) 通过 Internet 呼叫 Bob 的 SIP phone. 图中还显示两个 SIP proxy server, 它们分别代表 Alice 和 Bob 行动, 以协助建立会话. 这种典型布局通常称为 "SIP trapezoid", 如 Figure 1 中虚线的几何形状所示.

Alice 使用 Bob 的 SIP 身份 "calls" Bob, 该身份是一种称为 SIP URI 的 Uniform Resource Identifier (URI). SIP URI 在 Section 19.1 中定义. 它的形式类似电子邮件地址, 通常包含 username 和 host name. 在此例中, 它是 sip:[email protected], 其中 biloxi.com 是 Bob 的 SIP 服务提供商的域. Alice 的 SIP URI 是 sip:[email protected]. Alice 可能手工输入了 Bob 的 URI, 也可能点击了超链接或地址簿中的条目. SIP 还提供一种安全 URI, 称为 SIPS URI. 示例为 sips:[email protected]. 向 SIPS URI 发起的呼叫保证使用安全的加密传输 (即 TLS), 将所有 SIP 消息从主叫方传送到被叫方的域. 从那里开始, 请求会安全地发送给被叫方, 但具体安全机制取决于被叫方域的策略.

SIP 基于类似 HTTP 的 request/response 事务模型. 每个事务由一个请求和至少一个响应组成, 该请求在服务器上调用特定 method 或 function. 在此示例中, 事务从 Alice 的 softphone 发送一个寻址到 Bob 的 SIP URI 的 INVITE 请求开始. INVITE 是 SIP method 的一个示例, 指定请求者 (Alice) 希望服务器 (Bob) 采取的动作. INVITE 请求包含若干 header field. header field 是命名属性, 提供关于消息的附加信息. INVITE 中存在的 header field 包括呼叫的唯一标识符, 目的地址, Alice 的地址, 以及 Alice 希望与 Bob 建立的会话类型信息. INVITE (Figure 1 中的消息 F1) 可能如下所示:

                 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 |
|------------------------------------------------->|
| |

Figure 1: SIP session setup example with SIP trapezoid

INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob `<sip:[email protected]>`
From: Alice `<sip:[email protected]>`;tag=1928301774
Call-ID: [email protected]
CSeq: 314159 INVITE
Contact: `<sip:[email protected]>`
Content-Type: application/sdp
Content-Length: 142

(Alice's SDP not shown)

该文本编码消息的第一行包含 method name (INVITE). 后续行是 header field 列表. 此示例包含所需的最小集合. 这些 header field 简述如下:

Via 包含 Alice 期望接收此请求响应的地址 (pc33.atlanta.com). 它还包含一个标识此事务的 branch 参数.

To 包含 display name (Bob) 和该请求最初指向的 SIP 或 SIPS URI (sip:[email protected]). display name 在 RFC 2822 [3] 中描述.

From 也包含 display name (Alice) 和 SIP 或 SIPS URI (sip:[email protected]), 指示该请求的发起者. 此 header field 还包含一个 tag 参数, 其中有 softphone 添加到 URI 的随机字符串 (1928301774). 它用于标识目的.

Call-ID 包含此呼叫的全局唯一标识符, 由随机字符串与 softphone 的 host name 或 IP 地址组合生成. To tag, From tag 和 Call-ID 的组合完整定义 Alice 和 Bob 之间的 peer-to-peer SIP 关系, 称为 dialog.

CSeq 或 Command Sequence 包含一个整数和一个 method name. dialog 内每个新请求都会递增 CSeq number, 它是传统的序列号.

Contact 包含一个 SIP 或 SIPS URI, 表示联系 Alice 的直接路由, 通常由 fully qualified domain name (FQDN) 上的 username 组成. 虽然首选 FQDN, 但许多终端系统没有注册域名, 因此允许使用 IP 地址. Via header field 告诉其他元素将响应发送到哪里, 而 Contact header field 告诉其他元素将未来请求发送到哪里.

Max-Forwards 用于限制请求在到达目的地途中可经过的跳数. 它由一个整数构成, 每经过一跳减一.

Content-Type 包含 message body (未显示) 的描述.

Content-Length 包含 message body 的 octet (byte) 计数.

完整 SIP header field 集合在 Section 20 中定义.

会话细节, 例如媒体类型, codec 或 sampling rate, 并不使用 SIP 描述. 相反, SIP 消息的 body 包含一个会话描述, 该描述以其他协议格式编码. 一种这样的格式是 Session Description Protocol (SDP) (RFC 2327 [1]). 此 SDP 消息 (示例中未显示) 由 SIP 消息承载, 其方式类似电子邮件消息承载文档附件, 或 HTTP 消息承载网页.

由于 softphone 不知道 Bob 的位置, 也不知道 biloxi.com 域中的 SIP server, softphone 将 INVITE 发送给服务 Alice 域 atlanta.com 的 SIP server. atlanta.com SIP server 的地址可能已经配置在 Alice 的 softphone 中, 也可能通过 DHCP 等方式发现.

atlanta.com SIP server 是一种称为 proxy server 的 SIP server. proxy server 接收 SIP 请求并代表请求者转发它们. 在此示例中, proxy server 接收 INVITE 请求, 并向 Alice 的 softphone 返回 100 (Trying) 响应. 100 (Trying) 响应表示已收到 INVITE, 且 proxy 正在代表她把 INVITE 路由到目的地. SIP 中的响应使用三位代码后跟描述性短语. 此响应包含与 INVITE 相同的 To, From, Call-ID, CSeq 以及 Via 中的 branch 参数, 使 Alice 的 softphone 能够把该响应与已发送的 INVITE 关联起来. atlanta.com proxy server 定位 biloxi.com 处的 proxy server, 可能通过执行特定类型的 DNS (Domain Name Service) 查询来找到服务 biloxi.com 域的 SIP server. 这在 [4] 中描述. 因此, 它获得 biloxi.com proxy server 的 IP 地址, 并把 INVITE 请求转发, 或 proxy, 到那里. 在转发请求之前, atlanta.com proxy server 添加一个额外的 Via header field value, 其中包含自己的地址 (INVITE 已经在第一个 Via 中包含 Alice 的地址). biloxi.com proxy server 收到 INVITE, 并向 atlanta.com proxy server 返回 100 (Trying) 响应, 表示它已经收到 INVITE 并正在处理该请求. proxy server 查询一个数据库, 一般称为 location service, 其中包含 Bob 的当前 IP 地址. (下一节会看到如何填充此数据库.) biloxi.com proxy server 向 INVITE 再添加一个含自身地址的 Via header field value, 并把它 proxy 到 Bob 的 SIP phone.

Bob 的 SIP phone 收到 INVITE, 并提醒 Bob 有来自 Alice 的来电, 以便 Bob 决定是否接听, 即 Bob 的电话振铃. Bob 的 SIP phone 通过 180 (Ringing) 响应指示这一点, 该响应沿相反方向通过两个 proxy 路由回来. 每个 proxy 使用 Via header field 确定将响应发送到哪里, 并从顶部移除自己的地址. 因此, 虽然路由初始 INVITE 需要 DNS 和 location service 查询, 但 180 (Ringing) 响应可以无需查询, 也无需 proxy 保持状态, 就返回给主叫方. 这还具有一个理想属性: 看到 INVITE 的每个 proxy 也会看到该 INVITE 的所有响应.

当 Alice 的 softphone 收到 180 (Ringing) 响应时, 它把此信息传递给 Alice, 可能通过播放回铃音或在 Alice 屏幕上显示消息.

在此示例中, Bob 决定接听呼叫. 当他拿起听筒时, 他的 SIP phone 发送 200 (OK) 响应, 表示呼叫已被应答. 200 (OK) 包含 message body, 其中是 Bob 愿意与 Alice 建立的会话类型的 SDP media description. 因此, 发生了两个阶段的 SDP 消息交换: Alice 向 Bob 发送一个, Bob 向 Alice 发送一个. 这种两阶段交换提供基本协商能力, 并基于简单的 SDP 交换 offer/answer model. 如果 Bob 不想接听呼叫或正在忙于另一个呼叫, 则会发送错误响应而不是 200 (OK), 结果不会建立媒体会话. SIP response code 的完整列表见 Section 21. Bob 发送出的 200 (OK) (Figure 1 中的消息 F9) 可能如下所示:

  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:[email protected]>`;tag=a6c85cf
From: Alice `<sip:[email protected]>`;tag=1928301774
Call-ID: [email protected]
CSeq: 314159 INVITE
Contact: `<sip:[email protected]>`
Content-Type: application/sdp
Content-Length: 131

(Bob's SDP not shown)

响应的第一行包含 response code (200) 和 reason phrase (OK). 其余行包含 header field. Via, To, From, Call-ID 和 CSeq header field 从 INVITE 请求复制而来. (共有三个 Via header field value - 一个由 Alice 的 SIP phone 添加, 一个由 atlanta.com proxy 添加, 一个由 biloxi.com proxy 添加.) Bob 的 SIP phone 向 To header field 添加了 tag 参数. 此 tag 将由两个端点纳入 dialog, 并包含在此呼叫未来的所有请求和响应中. Contact header field 包含一个 URI, Bob 可在其 SIP phone 处直接通过该 URI 到达. Content-Type 和 Content-Length 指向包含 Bob 的 SDP media 信息的 message body (未显示).

除此示例所示的 DNS 和 location service 查询外, proxy server 可以做出灵活的 "routing decisions" 来决定将请求发送到哪里. 例如, 如果 Bob 的 SIP phone 返回 486 (Busy Here) 响应, biloxi.com proxy server 可以把 INVITE proxy 到 Bob 的 voicemail server. proxy server 还可以同时向多个位置发送 INVITE. 这种并行搜索称为 forking.

在此情况下, 200 (OK) 通过两个 proxy 路由返回, 并由 Alice 的 softphone 接收, 后者随后停止回铃音并指示呼叫已被应答. 最后, Alice 的 softphone 向 Bob 的 SIP phone 发送确认消息 ACK, 以确认收到最终响应 (200 (OK)). 在此示例中, ACK 直接从 Alice 的 softphone 发送到 Bob 的 SIP phone, 绕过两个 proxy. 这是因为端点已经通过 INVITE/200 (OK) 交换从 Contact header field 获知彼此地址, 而这些地址在发送初始 INVITE 时并不知道. 两个 proxy 执行的查询不再需要, 因此 proxy 退出呼叫流. 这完成了用于建立 SIP 会话的 INVITE/200/ACK 三次握手. 会话建立的完整细节见 Section 13.

Alice 和 Bob 的媒体会话现在已经开始, 他们使用在 SDP 交换中达成一致的格式发送媒体 packet. 通常, 端到端媒体 packet 采用与 SIP signaling message 不同的路径.

在会话期间, Alice 或 Bob 都可能决定改变媒体会话的特征. 这是通过发送包含新媒体描述的 re-INVITE 完成的. 此 re-INVITE 引用现有 dialog, 使对方知道它是要修改现有会话, 而不是建立新会话. 对方发送 200 (OK) 接受该变更. 请求者以 ACK 响应 200 (OK). 如果对方不接受该变更, 则发送错误响应, 例如 488 (Not Acceptable Here), 该响应也会收到 ACK. 然而, re-INVITE 失败不会导致现有呼叫失败 - 会话继续使用先前协商的特征. 会话修改的完整细节见 Section 14.

在呼叫结束时, Bob 首先断开 (挂断) 并生成 BYE 消息. 此 BYE 直接路由到 Alice 的 softphone, 再次绕过 proxy. Alice 以 200 (OK) 响应确认收到 BYE, 这会终止会话和 BYE 事务. 不发送 ACK - ACK 只在响应 INVITE 请求的响应时发送. 稍后会讨论 INVITE 这种特殊处理的原因, 它与 SIP 中的可靠性机制, 振铃电话可能需要较长时间才能接听, 以及 forking 有关. 因此, SIP 中的请求处理通常被分类为 INVITE 或 non-INVITE, 后者指除 INVITE 以外的所有方法. 会话终止的完整细节见 Section 15.

Section 24.2 完整描述 Figure 1 中显示的消息.

在某些情况下, SIP signaling path 中的 proxy 在会话持续期间看到端点之间的所有消息可能很有用. 例如, 如果 biloxi.com proxy server 希望在初始 INVITE 之后继续留在 SIP messaging path 中, 它会向 INVITE 添加一个必需的 routing header field, 称为 Record-Route, 其中包含一个可解析为该 proxy 的 hostname 或 IP 地址的 URI. 此信息会由 Bob 的 SIP phone 和 Alice 的 softphone 接收 (因为 Record-Route header field 会在 200 (OK) 中传回), 并在 dialog 持续期间保存. biloxi.com proxy server 随后会接收并 proxy ACK, BYE 以及对 BYE 的 200 (OK). 每个 proxy 都可以独立决定是否接收后续消息, 而这些消息会经过所有选择接收它的 proxy. 此能力常用于提供 mid-call feature 的 proxy.

注册是 SIP 中另一种常见操作. 注册是 biloxi.com server 获知 Bob 当前位置的一种方式. 在初始化时以及周期性间隔, Bob 的 SIP phone 向 biloxi.com 域中称为 SIP registrar 的 server 发送 REGISTER 消息. REGISTER 消息把 Bob 的 SIP 或 SIPS URI (sip:[email protected]) 与他当前登录的机器关联起来 (在 Contact header field 中作为 SIP 或 SIPS URI 传送). registrar 将此关联, 也称为 binding, 写入名为 location service 的数据库, 该数据库可由 biloxi.com 域中的 proxy 使用. 通常, 一个域的 registrar server 与该域的 proxy 位于同一位置. 一个重要概念是, SIP server 类型之间的区别是逻辑的, 不是物理的.

Bob 不限于从单个设备注册. 例如, 他家中的 SIP phone 和办公室中的 SIP phone 都可以发送注册. 此信息一起存储在 location service 中, 使 proxy 能执行多种搜索来定位 Bob. 类似地, 多个用户也可以同时注册在单个设备上.

location service 只是一个抽象概念. 它通常包含一些信息, 使 proxy 能够输入一个 URI 并收到零个或多个 URI 的集合, 这些 URI 告诉 proxy 将请求发送到哪里. 注册是创建此信息的一种方式, 但不是唯一方式. 管理员可以自行配置任意映射函数.

最后, 需要注意, 在 SIP 中, 注册用于路由传入 SIP 请求, 对授权传出请求没有作用. 在 SIP 中, 授权和认证要么基于每个请求通过 challenge/response 机制处理, 要么使用 Section 26 中讨论的较低层方案处理.

此注册示例的完整 SIP 消息细节见 Section 24.1.

SIP 中的其他操作, 例如使用 OPTIONS 查询 SIP server 或 client 的能力, 或使用 CANCEL 取消挂起请求, 将在后续章节中介绍.