10. 注册 (Registrations)
10 注册 (Registrations)
10.1 概述 (Overview)
SIP 提供发现能力. 如果一个用户想与另一个用户发起会话, SIP 必须发现目的用户当前可达的主机. 此发现过程经常由 SIP 网络元素完成, 例如 proxy server 和 redirect server; 它们负责接收请求, 基于对用户位置的了解确定将请求发送到哪里, 然后把请求发送到那里. 为此, SIP 网络元素查询一种称为 location service 的抽象服务, 该服务为特定域提供地址绑定. 这些地址绑定把传入的 SIP 或 SIPS URI (例如 sip:[email protected]) 映射到一个或多个以某种方式更 "closer" 于期望用户的 URI (例如 sip:[email protected]). 最终, proxy 会查询一个 location service, 将收到的 URI 映射到期望接收者当前所在的 user agent.
注册会在特定域的 location service 中创建绑定, 把 address-of-record URI 与一个或多个 contact address 关联起来. 因此, 当该域的 proxy 收到 Request-URI 与 address-of-record 匹配的请求时, proxy 会将请求转发到为该 address-of-record 注册的 contact address. 一般而言, 只有当发往某个 address-of-record 的请求会被路由到某个域时, 在该域的 location service 中注册该 address-of-record 才有意义. 在多数情况下, 这意味着注册所在的域需要与 address-of-record 的 URI 中的域匹配.
location service 的内容可以通过许多方式建立. 一种方式是管理配置. 在上面的示例中, 通过访问公司数据库可知 Bob 是工程部门成员. 然而, SIP 提供一种机制, 让 UA 显式创建绑定. 此机制称为注册.
注册涉及向一种称为 registrar 的特殊 UAS 发送 REGISTER 请求. registrar 作为某个域的 location service 的前端, 基于 REGISTER 请求的内容读取和写入映射. 此 location service 随后通常由负责路由该域请求的 proxy server 查询.
Figure 2 给出整体注册过程的图示. 注意, registrar 和 proxy server 是逻辑角色, 可以由网络中的单个设备扮演; 为清晰起见, 图中将二者分开. 还要注意, 如果 UA 和 registrar 是分离元素, UA 可以通过 proxy server 发送请求以到达 registrar.
SIP 不强制规定实现 location service 的特定机制. 唯一要求是, 某个域的 registrar MUST 能够向 location service 读取和写入数据, 且该域的 proxy 或 redirect server MUST 能够读取同一数据. registrar MAY 与同一域的特定 SIP proxy server 位于同一位置.
10.2 构造 REGISTER 请求 (Constructing the REGISTER Request)
REGISTER 请求添加, 移除和查询绑定. REGISTER 请求可以在 address-of-record 与一个或多个 contact address 之间添加新绑定. 可由具有适当授权的第三方代表特定 address-of-record 执行注册. client 还可以移除先前绑定, 或查询以确定某个 address-of-record 当前有哪些绑定.
除另有说明外, REGISTER 请求的构造以及发送 REGISTER 请求的 client 行为, 与 Section 8.1 和 Section 17.1 中描述的一般 UAC 行为相同.
REGISTER 请求不建立 dialog. UAC MAY 基于 Section 8.1 中描述的预先存在 route set, 在 REGISTER 请求中包含 Route header field. Record-Route header field 在 REGISTER 请求或响应中没有意义, 如果存在 MUST 被忽略. 特别地, UAC MUST NOT 基于任何 REGISTER 请求响应中是否存在 Record-Route header field 来创建新的 route set.
除 Contact 外, 以下 header field MUST 包含在 REGISTER 请求中. Contact header field MAY 包含:
Request-URI: Request-URI 命名该注册所针对的 location service 的域 (例如 "sip:chicago.com"). SIP URI 的 "userinfo" 和 "@" 组件 MUST NOT 存在.
To: To header field 包含要创建, 查询或修改其注册的 address of record. To header field 与 Request-URI field 通常不同, 因为前者包含 user name. 此 address-of-record MUST 是 SIP URI 或 SIPS URI.
From: From header field 包含对注册负责的人的 address-of-record. 除非该请求是 third-party registration, 否则其值与 To header field 相同.
Call-ID: UAC 发往特定 registrar 的所有注册 SHOULD 使用相同的 Call-ID header field value.
如果同一 client 使用不同的 Call-ID value, registrar 将无法检测延迟的 REGISTER 请求是否可能乱序到达.
CSeq: CSeq 值保证 REGISTER 请求的正确排序. 对具有相同 Call-ID 的每个 REGISTER 请求, UA MUST 将 CSeq 值递增一.
Contact: REGISTER 请求 MAY 包含 Contact header field, 其中有零个或多个包含地址绑定的值.
在收到 registrar 对前一个注册的最终响应之前, 或在前一个 REGISTER 请求超时之前, UA MUST NOT 发送新的注册 (即包含新 Contact header field value 的注册, 与重传相对).
bob
+----+
| UA |
| |
+----+
|
|3)INVITE
| [email protected]
chicago.com +--------+ V
+---------+ 2)Store|Location|4)Query +-----+
|Registrar|=======>| Service|<=======|Proxy|sip.chicago.com
+---------+ +--------+=======>+-----+
A 5)Resp |
| |
| |
1)REGISTER| |
| |
+----+ |
| UA |<-------------------------------+
cube2214a| | 6)INVITE
+----+ [email protected]
carol
Figure 2: REGISTER example
以下 Contact header 参数在 REGISTER 请求中具有特殊含义:
action: RFC 2543 中的 "action" 参数已被弃用. UAC SHOULD NOT 使用 "action" 参数.
expires: "expires" 参数指示 UA 希望绑定有效多久. 该值是表示秒数的数字. 如果未提供此参数, 则改用 Expires header field 的值. 实现 MAY 将大于 2**32-1 (4294967295 秒或 136 年) 的值视为等价于 2**32-1. 格式错误的值 SHOULD 被视为等价于 3600.
10.2.1 添加绑定 (Adding Bindings)
发送给 registrar 的 REGISTER 请求包含 contact address, 发往该 address-of-record 的 SIP 请求应被转发到这些地址. address-of-record 包含在 REGISTER 请求的 To header field 中.
请求的 Contact header field value 通常由标识特定 SIP 端点的 SIP 或 SIPS URI 组成 (例如 "sip:[email protected]"), 但它们 MAY 使用任何 URI scheme. 例如, SIP UA 可以选择为某个 address-of-record 注册电话号码 (使用 tel URL, RFC 2806 [9]) 或电子邮件地址 (使用 mailto URL, RFC 2368 [32]) 作为 Contact.
例如, address-of-record 为 "sip:[email protected]" 的 Carol 会向 chicago.com 域的 SIP registrar 注册. 她的注册随后会由 chicago.com 域中的 proxy server 使用, 以把发往 Carol 的 address-of-record 的请求路由到她的 SIP 端点.
一旦 client 在 registrar 处建立了绑定, 它 MAY 根据需要发送后续注册, 其中包含新绑定或对现有绑定的修改. REGISTER 请求的 2xx 响应将在 Contact header field 中包含该 registrar 处已为此 address-of-record 注册的完整绑定列表.
如果 REGISTER 请求的 To header field 中的 address-of-record 是 SIPS URI, 则请求中的任何 Contact header field value SHOULD 也为 SIPS URI. client 只有在 contact address 所表示资源的安全性通过其他方式得到保证时, 才应在 SIPS address-of-record 下注册非 SIPS URI. 这可能适用于调用 SIP 以外协议的 URI, 或由 TLS 以外协议保护的 SIP 设备.
注册不需要更新所有绑定. 通常, UA 只更新自己的 contact address.
10.2.1.1 设置 Contact Address 的过期间隔 (Setting the Expiration Interval of Contact Addresses)
当 client 发送 REGISTER 请求时, 它 MAY 建议一个过期间隔, 指示 client 希望注册有效多久. (如 Section 10.3 所述, registrar 基于其本地策略选择实际时间间隔.)
client 可通过两种方式为绑定建议过期间隔: 通过 Expires header field 或通过 "expires" Contact header 参数. 当单个 REGISTER 请求中给出多个绑定时, 后者允许按每个绑定建议过期间隔; 前者则为所有不包含 "expires" 参数的 Contact header field value 建议过期间隔.
如果 REGISTER 中不存在任何表示建议过期时间的机制, client 表示希望 server 选择.
10.2.1.2 Contact Address 之间的偏好 (Preferences among Contact Addresses)
如果 REGISTER 请求中发送了多个 Contact, 注册 UA 意图把这些 Contact header field value 中的所有 URI 都与 To field 中存在的 address-of-record 关联起来. 此列表可通过 Contact header field 中的 "q" 参数进行优先级排序. 与此 address-of-record 的其他绑定相比, "q" 参数指示特定 Contact header field value 的相对偏好. Section 16.6 描述 proxy server 如何使用此偏好指示.
10.2.2 移除绑定 (Removing Bindings)
注册是软状态, 除非刷新, 否则会过期, 但也可以被显式移除. client 可尝试如 Section 10.2.1 所述影响 registrar 选择的过期间隔. UA 通过在 REGISTER 请求中为该 contact address 指定过期间隔 "0", 请求立即移除绑定. UA SHOULD 支持此机制, 以便在绑定的过期间隔过去之前移除绑定.
REGISTER 专用的 Contact header field value "*" 适用于所有注册, 但除非 Expires header field 存在且值为 "0", 否则 MUST NOT 使用它.
使用 "*" Contact header field value 允许注册 UA 在不知道精确值的情况下移除与某个 address-of-record 关联的所有绑定.
10.2.3 获取绑定 (Fetching Bindings)
对任何 REGISTER 请求的成功响应都会包含现有绑定的完整列表, 不管该请求是否包含 Contact header field. 如果 REGISTER 请求中没有 Contact header field, 绑定列表保持不变.
10.2.4 刷新绑定 (Refreshing Bindings)
每个 UA 负责刷新它先前建立的绑定. UA SHOULD NOT 刷新其他 UA 设置的绑定.
registrar 的 200 (OK) 响应包含一个 Contact field 列表, 枚举所有当前绑定. UA 使用 Section 19.1.4 中的比较规则比较每个 contact address, 以查看该 contact address 是否由自己创建. 如果是, 它根据 expires 参数或在其缺失时根据 Expires field value 更新过期时间间隔. 然后 UA 在过期间隔流逝之前为其每个绑定发出 REGISTER 请求. 它 MAY 将若干更新组合到一个 REGISTER 请求中.
UA SHOULD 在单个启动周期内对所有注册使用相同的 Call-ID. 除非被重定向, registration refresh SHOULD 发送到与原始注册相同的网络地址.
10.2.5 设置内部时钟 (Setting the Internal Clock)
如果 REGISTER 请求的响应包含 Date header field, client MAY 使用此 header field 获知当前时间, 以设置任何内部时钟.
10.2.6 发现 Registrar (Discovering a Registrar)
UA 可以使用三种方式确定发送注册的地址: 通过配置, 使用 address-of-record, 以及 multicast. UA 可以用超出本规范范围的方式配置 registrar 地址. 如果没有配置 registrar 地址, UA SHOULD 使用 address-of-record 的 host 部分作为 Request-URI, 并使用普通 SIP server location 机制 [4] 将请求寻址到那里. 例如, 用户 "sip:[email protected]" 的 UA 将 REGISTER 请求寻址到 "sip:chicago.com".
最后, UA 可以被配置为使用 multicast. multicast 注册被寻址到众所周知的 "all SIP servers" multicast address "sip.mcast.net" (IPv4 为 224.0.1.75). 尚未分配众所周知的 IPv6 multicast address; 需要时将另行记录此类分配. SIP UA MAY 监听该地址并用它获知其他本地用户的位置 (见 [33]); 然而, 它们不响应该请求.
multicast 注册在某些环境中可能不合适, 例如多个企业共享同一局域网时.
10.2.7 传输请求 (Transmitting a Request)
一旦 REGISTER 方法已构造且消息目的地已识别, UAC 遵循 Section 8.1.2 中描述的过程, 将 REGISTER 交给事务层.
如果事务层由于 REGISTER 未产生响应而返回 timeout error, UAC SHOULD NOT 立即向同一 registrar 重新尝试注册.
立即重新尝试也很可能超时. 等待一段合理时间, 让导致超时的条件被纠正, 可减少网络上的不必要负载. 没有强制规定具体间隔.
10.2.8 错误响应 (Error Responses)
如果 UA 收到 423 (Interval Too Brief) 响应, 它 MAY 在把 REGISTER 请求中所有 contact address 的过期间隔设置为大于或等于 423 (Interval Too Brief) 响应的 Min-Expires header field 中的过期间隔后, 重试注册.
10.3 处理 REGISTER 请求 (Processing REGISTER Requests)
registrar 是响应 REGISTER 请求并维护绑定列表的 UAS, 该绑定列表可由其管理域内的 proxy server 和 redirect server 访问. registrar 按 Section 8.2 和 Section 17.2 处理请求, 但只接受 REGISTER 请求. registrar MUST NOT 生成 6xx 响应.
registrar MAY 适当地重定向 REGISTER 请求. 一种常见用法是, 监听 multicast interface 的 registrar 以 302 (Moved Temporarily) 响应把 multicast REGISTER 请求重定向到自己的 unicast interface.
如果 REGISTER 请求中包含 Record-Route header field, registrar MUST 忽略它. registrar MUST NOT 在对 REGISTER 请求的任何响应中包含 Record-Route header field.
registrar 可能收到经过某个 proxy 的请求, 该 proxy 将 REGISTER 视为未知请求并添加了 Record-Route header field value.
registrar 必须知道 (例如通过配置) 它为哪些域维护绑定. REGISTER 请求 MUST 由 registrar 按接收顺序处理. REGISTER 请求也 MUST 以原子方式处理, 这意味着特定 REGISTER 请求要么完全处理, 要么完全不处理. 每个 REGISTER 消息 MUST 独立于任何其他注册或绑定变更进行处理.
收到 REGISTER 请求时, registrar 遵循以下步骤:
1. registrar 检查 Request-URI, 以确定它是否能访问 Request-URI 所标识域的绑定. 如果不能, 且 server 也充当 proxy server, server SHOULD 按 Section 16 中描述的 proxy 消息的一般行为, 将请求转发到被寻址的域.
2. 为保证 registrar 支持任何必要扩展, registrar MUST 按 Section 8.2.2 中 UAS 的描述处理 Require header field value.
3. registrar SHOULD 认证 UAC. SIP user agent 的认证机制在 Section 22 中描述. 注册行为绝不覆盖 SIP 的通用认证框架. 如果没有可用认证机制, registrar MAY 将 From address 作为请求发起者的断言身份.
4. registrar SHOULD 确定已认证用户是否被授权修改此 address-of-record 的注册. 例如, registrar 可以查询一个授权数据库, 该数据库将用户名映射到一个 address-of-record 列表, 用户被授权修改这些 address-of-record 的绑定. 如果已认证用户未被授权修改绑定, registrar MUST 返回 403 (Forbidden) 并跳过剩余步骤.
在支持 third-party registration 的体系结构中, 一个实体可能负责更新与多个 address-of-record 关联的注册.
5. registrar 从请求的 To header field 提取 address-of-record. 如果 address-of-record 对 Request-URI 中的域无效, registrar MUST 发送 404 (Not Found) 响应并跳过剩余步骤. 随后 URI MUST 转换为 canonical form. 为此, 所有 URI 参数 MUST 被移除 (包括 user-param), 且任何 escaped character MUST 转换为其 unescaped form. 结果作为绑定列表的索引.
6. registrar 检查请求是否包含 Contact header field. 如果没有, 它跳到最后一步. 如果存在 Contact header field, registrar 检查是否有一个 Contact field value 包含特殊值 "*" 且存在 Expires field. 如果请求有额外 Contact field 或非零过期时间, 则请求无效, server MUST 返回 400 (Invalid Request) 并跳过剩余步骤. 否则, registrar 检查 Call-ID 是否与每个绑定存储的值一致. 如果不一致, 它 MUST 移除该绑定. 如果一致, 只有当请求中的 CSeq 高于该绑定存储的值时, 它才 MUST 移除该绑定. 否则, 更新 MUST 中止且请求失败.
7. registrar 现在依次处理 Contact header field 中的每个 contact address. 对每个地址, 它按如下方式确定过期间隔:
- 如果 field value 有 "expires" 参数, 该值 MUST 被视为请求的过期时间.
- 如果没有这样的参数, 但请求有 Expires header field, 该值 MUST 被视为请求的过期时间.
- 如果两者都没有, 本地配置的默认值 MUST 被视为请求的过期时间.
registrar MAY 选择小于所请求过期间隔的过期时间. 当且仅当所请求过期间隔大于零 AND 小于一小时 AND 小于 registrar 配置的最小值时, registrar MAY 用 423 (Interval Too Brief) 响应拒绝注册. 此响应 MUST 包含 Min-Expires header field, 声明 registrar 愿意接受的最小过期间隔. 然后它跳过剩余步骤.
允许 registrar 设置注册间隔, 可以保护它免受过于频繁的注册刷新影响, 同时限制它需要维护的状态, 并降低注册变 stale 的可能性. 注册的过期间隔经常用于创建服务. 一个示例是 follow-me service, 其中用户可能只在短时间内可通过某终端可用. 因此, registrar 应接受短时注册; 只有当间隔短到刷新会降低 registrar 性能时, 才应拒绝请求.
然后, 对每个地址, registrar 使用 URI 比较规则搜索当前绑定列表. 如果绑定不存在, 则暂时添加. 如果绑定存在, registrar 检查 Call-ID 值. 如果现有绑定中的 Call-ID 值不同于请求中的 Call-ID 值, 则当过期时间为零时该绑定 MUST 被移除, 否则被更新. 如果二者相同, registrar 比较 CSeq 值. 如果该值高于现有绑定的值, 它 MUST 如上更新或移除绑定. 如果不是, 更新 MUST 中止且请求失败.
此算法确保来自同一 UA 的乱序请求被忽略.
每个绑定记录都会记录请求中的 Call-ID 和 CSeq 值.
当且仅当所有绑定更新和添加都成功时, 绑定更新 MUST 被提交 (即对 proxy 或 redirect server 可见). 如果其中任何一个失败 (例如因为后端数据库提交失败), 请求 MUST 以 500 (Server Error) 响应失败, 且所有暂定绑定更新 MUST 被移除.
8. registrar 返回 200 (OK) 响应. 响应 MUST 包含 Contact header field value, 枚举所有当前绑定. 每个 Contact value MUST 带有 "expires" 参数, 指示 registrar 选择的过期间隔. 响应 SHOULD 包含 Date header field.