Skip to main content

10. 注册 (Registrations)

10.1 概述 (Overview)

SIP提供发现能力。如果用户想要与另一个用户发起会话, SIP必须发现目标用户当前可达的主机。此发现过程通常由SIP网络元素 (如代理服务器和重定向服务器) 完成, 这些元素负责接收请求, 根据用户位置的知识确定将其发送到何处, 然后将其发送到那里。为此, SIP网络元素查询称为位置服务 (Location Service) 的抽象服务, 该服务为特定域提供地址绑定。这些地址绑定将传入的SIP或SIPS URI (例如sip:bob@biloxi.com) 映射到一个或多个以某种方式"更接近"所需用户的URI (例如sip:bob@engineering.biloxi.com)。最终, 代理将查询位置服务, 该服务将接收到的URI映射到所需接收者当前所在的用户代理。

注册 (Registration) 在特定域的位置服务中创建绑定, 该绑定将记录地址URI (Address-of-Record URI) 与一个或多个联系地址 (Contact Address) 相关联。因此, 当该域的代理接收到Request-URI与记录地址匹配的请求时, 代理将请求转发到注册到该记录地址的联系地址。通常, 仅当对该记录地址的请求将被路由到该域时, 在域的位置服务注册记录地址才有意义。在大多数情况下, 这意味着注册的域需要与记录地址URI中的域匹配。

有许多方法可以建立位置服务的内容。一种方法是通过管理方式。在上面的示例中, 通过访问公司数据库已知Bob是工程部门的成员。然而, SIP提供了一种机制, 使UA能够显式创建绑定。这种机制称为注册。

注册需要向称为注册器 (Registrar) 的特殊类型的UAS发送REGISTER请求。注册器充当域的位置服务的前端, 根据REGISTER请求的内容读取和写入映射。然后, 通常由负责路由该域请求的代理服务器查询此位置服务。

图2给出了整个注册过程的说明。请注意, 注册器和代理服务器是可以由网络中的单个设备扮演的逻辑角色; 为了清楚起见, 在此说明中将两者分开。还要注意, 如果注册器和代理是单独的元素, UA可能通过代理服务器发送请求以到达注册器。

                                             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

图2: REGISTER示例

SIP不强制要求实现位置服务的特定机制。唯一的要求是某个域的注册器必须能够读取和写入位置服务的数据, 并且该域的代理或重定向服务器必须能够读取相同的数据。注册器可以与同一域的特定SIP代理服务器共置。


10.2 构造REGISTER请求 (Constructing the REGISTER Request)

REGISTER请求用于添加、删除和查询绑定。REGISTER请求可以在记录地址和一个或多个联系地址之间添加新绑定。特定记录地址的注册可以由适当授权的第三方执行。客户端还可以删除先前的绑定或查询以确定当前为记录地址建立了哪些绑定。

除非另有说明, REGISTER请求的构造和发送REGISTER请求的客户端行为与第8.1节和第17.1节中描述的通用UAC行为相同。

REGISTER请求不建立对话。UAC可以根据第8.1节中描述的预先存在的路由集, 在REGISTER请求中包含Route头字段。Record-Route头字段在REGISTER请求或响应中没有意义, 如果存在则必须忽略。特别是, UAC不得基于REGISTER请求的任何响应中Record-Route头字段的存在或不存在来创建新的路由集。

必需的头字段

除Contact外, 以下头字段必须包含在REGISTER请求中。Contact头字段可以包含:

Request-URI

Request-URI命名注册所针对的位置服务的域 (例如, "sip:chicago.com")。SIP URI的"userinfo"和"@"组件不得出现。

To

To头字段包含要创建、查询或修改其注册的记录地址。To头字段和Request-URI字段通常不同, 因为前者包含用户名。此记录地址必须是SIP URI或SIPS URI。

From

From头字段包含负责注册的人的记录地址。该值与To头字段相同, 除非请求是第三方注册。

Call-ID

来自UAC的所有注册应该对发送到特定注册器的注册使用相同的Call-ID头字段值。

如果同一客户端使用不同的Call-ID值, 注册器无法检测延迟的REGISTER请求是否可能无序到达。

CSeq

CSeq值保证REGISTER请求的正确排序。对于具有相同Call-ID的每个REGISTER请求, UA必须将CSeq值增加1。

Contact

REGISTER请求可以包含带有零个或多个包含地址绑定的值的Contact头字段。

重要约束

UA在收到注册器对前一个REGISTER请求的最终响应或前一个REGISTER请求超时之前, 不得发送新注册 (即包含新的Contact头字段值, 而不是重传)。

Contact头字段参数

以下Contact头参数在REGISTER请求中具有特殊含义:

action

RFC 2543中的"action"参数已弃用。UAC不应该使用"action"参数。

expires

"expires"参数指示UA希望绑定有效的时间长度。该值是表示秒数的数字。如果未提供此参数, 则改用Expires头字段的值。实现可以将大于2^32-1 (4294967295秒或136年) 的值视为等同于2^32-1。格式错误的值应该被视为等同于3600。


10.2.1 添加绑定 (Adding Bindings)

发送到注册器的REGISTER请求包括应将记录地址的SIP请求转发到的联系地址。记录地址包含在REGISTER请求的To头字段中。

请求的Contact头字段值通常由标识特定SIP端点的SIP或SIPS URI组成 (例如, "sip:carol@cube2214a.chicago.com"), 但它们可以使用任何URI方案。例如, SIP UA可以选择将电话号码 (使用tel URL, RFC 2806 [9]) 或电子邮件地址 (使用mailto URL, RFC 2368 [32]) 注册为记录地址的Contact。

例如, 记录地址为"sip:carol@chicago.com"的Carol将向域chicago.com的SIP注册器注册。然后, chicago.com域中的代理服务器将使用她的注册来将Carol的记录地址的请求路由到她的SIP端点。

一旦客户端在注册器建立了绑定, 它可以根据需要发送包含新绑定或对现有绑定的修改的后续注册。对REGISTER请求的2xx响应将在Contact头字段中包含在此注册器为此记录地址注册的绑定的完整列表。

如果REGISTER请求的To头字段中的记录地址是SIPS URI, 则请求中的任何Contact头字段值也应该是SIPS URI。客户端应该仅在联系地址所代表的资源的安全性由其他方式保证时, 才在SIPS记录地址下注册非SIPS URI。这可能适用于调用SIP以外的协议的URI, 或由TLS以外的协议保护的SIP设备。

注册不需要更新所有绑定。通常, UA仅更新其自己的联系地址。


10.2.1.1 设置联系地址的过期间隔 (Setting the Expiration Interval of Contact Addresses)

当客户端发送REGISTER请求时, 它可以建议一个过期间隔, 指示客户端希望注册有效的时间长度。(如第10.3节所述, 注册器根据其本地策略选择实际时间间隔。)

客户端可以通过两种方式建议绑定的过期间隔: 通过Expires头字段或"expires" Contact头参数。后者允许在单个REGISTER请求中给出多个绑定时, 在每个绑定的基础上建议过期间隔, 而前者为不包含"expires"参数的所有Contact头字段值建议过期间隔。

如果REGISTER中既没有用于表达建议的过期时间的机制, 则客户端指示其希望服务器选择。


10.2.1.2 联系地址之间的优先级 (Preferences among Contact Addresses)

如果在REGISTER请求中发送多个Contact, 则注册UA打算将这些Contact头字段值中的所有URI与To字段中存在的记录地址相关联。可以使用Contact头字段中的"q"参数对此列表进行优先级排序。"q"参数指示与此记录地址的其他绑定相比, 特定Contact头字段值的相对偏好。第16.6节描述了代理服务器如何使用此偏好指示。


10.2.2 删除绑定 (Removing Bindings)

注册是软状态, 除非刷新否则会过期, 但也可以显式删除。客户端可以尝试影响注册器选择的过期间隔, 如第10.2.1节所述。UA通过在REGISTER请求中为该联系地址指定过期间隔"0"来请求立即删除绑定。UA应该支持此机制, 以便可以在绑定的过期间隔过去之前删除绑定。

REGISTER特定的Contact头字段值"*"适用于所有注册, 但它不得使用, 除非Expires头字段存在且值为"0"。

使用"*" Contact头字段值允许注册UA删除与记录地址关联的所有绑定, 而无需知道它们的精确值。


10.2.3 获取绑定 (Fetching Bindings)

对任何REGISTER请求的成功响应都包含现有绑定的完整列表, 无论请求是否包含Contact头字段。如果REGISTER请求中不存在Contact头字段, 则绑定列表保持不变。


10.2.4 刷新绑定 (Refreshing Bindings)

每个UA负责刷新其先前建立的绑定。UA不应该刷新由其他UA设置的绑定。

来自注册器的200 (OK) 响应包含一个Contact字段列表, 列举所有当前绑定。UA比较每个联系地址, 使用第19.1.4节中的比较规则查看是否创建了该联系地址。如果是, 它根据expires参数更新过期时间间隔, 或者如果不存在, 则使用Expires字段值。然后, UA在过期间隔过去之前为其每个绑定发出REGISTER请求。它可以将多个更新组合到一个REGISTER请求中。

UA应该在单个引导周期期间对所有注册使用相同的Call-ID。注册刷新应该发送到与原始注册相同的网络地址, 除非被重定向。


10.2.5 设置内部时钟 (Setting the Internal Clock)

如果REGISTER请求的响应包含Date头字段, 客户端可以使用此头字段来了解当前时间以设置任何内部时钟。


10.2.6 发现注册器 (Discovering a Registrar)

UA可以使用三种方式来确定要向其发送注册的地址: 通过配置、使用记录地址和多播。

  1. 配置方式: UA可以通过超出本规范范围的方式配置注册器地址。
  2. 使用记录地址: 如果没有配置的注册器地址, UA应该使用记录地址的主机部分作为Request-URI, 并使用正常的SIP服务器位置机制 [4] 将请求寻址到那里。例如, 用户"sip:carol@chicago.com"的UA将REGISTER请求寻址到"sip:chicago.com"。
  3. 多播: UA可以配置为使用多播。多播注册被寻址到众所周知的"所有SIP服务器"多播地址"sip.mcast.net" (IPv4为224.0.1.75)。尚未分配众所周知的IPv6多播地址; 当需要时, 将单独记录此类分配。SIP UA可以监听该地址并使用它来了解其他本地用户的位置 (参见 [33]); 但是, 它们不响应请求。

在某些环境中, 多播注册可能不合适, 例如, 如果多个企业共享同一局域网。


10.2.7 传输请求 (Transmitting a Request)

一旦构造了REGISTER方法并识别了消息的目的地, UAC遵循第8.1.2节中描述的程序将REGISTER交给事务层。

如果事务层返回超时错误 (因为REGISTER没有产生响应), UAC不应该立即重新尝试向同一注册器注册。

立即重新尝试也可能超时。等待一些合理的时间间隔以纠正导致超时的条件可以减少网络上不必要的负载。没有强制要求特定的间隔。


10.2.8 错误响应 (Error Responses)

如果UA收到423 (Interval Too Brief) 响应, 它可以在使REGISTER请求中所有联系地址的过期间隔等于或大于423 (Interval Too Brief) 响应的Min-Expires头字段中的过期间隔后重试注册。


10.3 处理REGISTER请求 (Processing REGISTER Requests)

注册器是响应REGISTER请求并维护可供其管理域内的代理服务器和重定向服务器访问的绑定列表的UAS。注册器根据第8.2节和第17.2节处理请求, 但它仅接受REGISTER请求。注册器不得生成6xx响应。

注册器可以根据需要重定向REGISTER请求。一个常见用法是监听多播接口的注册器使用302 (Moved Temporarily) 响应将多播REGISTER请求重定向到其自己的单播接口。

如果REGISTER请求中包含Record-Route头字段, 注册器必须忽略它。注册器不得在对REGISTER请求的任何响应中包含Record-Route头字段。

注册器可能会收到遍历代理的请求, 该代理将REGISTER视为未知请求并添加了Record-Route头字段值。

注册器必须知道 (例如, 通过配置) 它为其维护绑定的域集。REGISTER请求必须由注册器按接收顺序处理。REGISTER请求还必须原子地处理, 这意味着特定的REGISTER请求要么完全处理, 要么根本不处理。每个REGISTER消息必须独立于任何其他注册或绑定更改进行处理。

注册器处理步骤

当接收到REGISTER请求时, 注册器遵循以下步骤:

步骤1: 检查Request-URI

注册器检查Request-URI以确定它是否有权访问Request-URI中标识的域的绑定。如果没有, 并且如果服务器也充当代理服务器, 服务器应该将请求转发到寻址的域, 遵循第16节中描述的代理消息的一般行为。

步骤2: 处理Require头字段

为了保证注册器支持任何必要的扩展, 注册器必须按照第8.2.2节中为UAS描述的方式处理Require头字段值。

步骤3: 认证UAC

注册器应该对UAC进行身份验证。SIP用户代理的身份验证机制在第22节中描述。注册行为不会以任何方式覆盖SIP的通用身份验证框架。如果没有可用的身份验证机制, 注册器可以将From地址作为请求发起者的声明身份。

步骤4: 授权检查

注册器应该确定经过身份验证的用户是否被授权修改此记录地址的注册。例如, 注册器可能会查询授权数据库, 该数据库将用户名映射到该用户有权修改绑定的记录地址列表。如果经过身份验证的用户未被授权修改绑定, 注册器必须返回403 (Forbidden) 并跳过其余步骤。

在支持第三方注册的架构中, 一个实体可能负责更新与多个记录地址关联的注册。

步骤5: 提取和验证记录地址

注册器从请求的To头字段中提取记录地址。如果记录地址对Request-URI中的域无效, 注册器必须发送404 (Not Found) 响应并跳过其余步骤。然后必须将URI转换为规范形式。为此, 必须删除所有URI参数 (包括user-param), 并且必须将任何转义字符转换为其未转义形式。结果用作绑定列表的索引。

步骤6: 处理Contact头字段

注册器检查请求是否包含Contact头字段。如果没有, 它跳到最后一步。如果存在Contact头字段, 注册器检查是否有一个Contact字段值包含特殊值"*"和Expires字段。如果请求具有其他Contact字段或过期时间不是零, 则请求无效, 服务器必须返回400 (Invalid Request) 并跳过其余步骤。如果不是, 注册器检查Call-ID是否与为每个绑定存储的值一致。如果不一致, 它必须删除绑定。如果一致, 它仅在请求中的CSeq高于为该绑定存储的值时才必须删除绑定。否则, 必须中止更新并且请求失败。

步骤7: 处理每个联系地址

注册器现在依次处理Contact头字段中的每个联系地址。对于每个地址, 它确定过期间隔如下:

  • 如果字段值具有"expires"参数, 则必须将该值作为请求的过期时间。
  • 如果没有此类参数, 但请求具有Expires头字段, 则必须将该值作为请求的过期时间。
  • 如果两者都没有, 则必须将本地配置的默认值作为请求的过期时间。

注册器可以选择小于请求的过期间隔的过期时间。当且仅当请求的过期间隔大于零且小于一小时且小于注册器配置的最小值时, 注册器可以使用423 (Interval Too Brief) 响应拒绝注册。此响应必须包含Min-Expires头字段, 该字段说明注册器愿意接受的最小过期间隔。然后它跳过其余步骤。

允许注册器设置注册间隔可以保护它免受过于频繁的注册刷新的影响, 同时限制它需要维护的状态并减少注册过时的可能性。注册的过期间隔经常用于创建服务。例如follow-me服务, 用户可能仅在短时间内在终端上可用。因此, 注册器应该接受简短的注册; 仅当间隔太短以至于刷新会降低注册器性能时, 才应拒绝请求。

对于每个地址, 注册器然后使用URI比较规则搜索当前绑定列表。如果绑定不存在, 则暂时添加它。如果绑定确实存在, 注册器检查Call-ID值。如果现有绑定中的Call-ID值与请求中的Call-ID值不同, 则如果过期时间为零, 必须删除绑定, 否则更新。如果它们相同, 注册器比较CSeq值。如果该值高于现有绑定的值, 则必须如上所述更新或删除绑定。如果不是, 则必须中止更新并且请求失败。

此算法确保忽略来自同一UA的无序请求。

每个绑定记录都记录请求中的Call-ID和CSeq值。

绑定更新必须提交 (即, 对代理或重定向服务器可见), 当且仅当所有绑定更新和添加都成功时。如果其中任何一个失败 (例如, 因为后端数据库提交失败), 请求必须以500 (Server Error) 响应失败, 并且必须删除所有暂时的绑定更新。

步骤8: 返回200 OK响应

注册器返回200 (OK) 响应。响应必须包含列举所有当前绑定的Contact头字段值。每个Contact值必须具有"expires"参数, 指示注册器选择的其过期间隔。响应应该包含Date头字段。


注册流程总结

UA发送REGISTER

构造请求
├─ Request-URI: 域名 (如sip:chicago.com)
├─ To: 记录地址 (如sip:[email protected])
├─ Contact: 联系地址 (如sip:[email protected])
└─ Expires: 过期时间

注册器处理
├─ 1. 检查域授权
├─ 2. 检查Require扩展
├─ 3. 认证用户
├─ 4. 授权检查
├─ 5. 提取记录地址
├─ 6. 处理Contact (添加/删除/查询)
├─ 7. 确定过期间隔
└─ 8. 返回200 OK (包含所有绑定)

位置服务更新

代理使用绑定路由请求

本章小结:

第10章详细描述了SIP的注册机制, 这是SIP提供位置独立性和移动性支持的关键。通过注册, 用户代理可以告诉网络它们当前在哪里, 以便可以接收发送到其记录地址的请求。注册器维护这些绑定并使它们对网络中的代理服务器可用, 从而实现灵活的呼叫路由。