SIP协议解析与实现(c和c++ 使用osip) 10

第七章 注册

第一节 总览

SIP提供了一种发现用户的能力。如果一个用户想与另外一个用户开启一个会话,SIP必须能够发现目标用户的当前主机。这种发现的过程常常由SIP网络元素使用,如代理服务器或重定向服务器,这些服务器能够接收一个请求,并根据用户的位置信息探测到将请求发送到哪里并发送。SIP网络元素考虑了一个位置服务。该服务支持对一个特定的域名进行地址绑定。这些地址绑定信息将收到的像sip:bob@biloxi.com的SIP或SIPS URI信息进行映射成一个或多个像sip:bob@engineering.biloxi.com这样对于用户来说更确切的SIP或SIPS URI。最终,一个代理将根据位置服务将接收到的URI映射成用当前使用户代理位置。

注册服务器为特定的域名下的位置服务创建绑定关系,这种绑定关系是指为一个AOR(address-of-record)URI绑定一个或多个可联系的地址。因此,当一个代理在当前域名下接收到一个请求,该请求的Request-URI与AOR相匹配,那么代理将该请求发送到注册在该AOR上的联系地址。通常,只有发送给这个AOR的请求能够被发送到AOR所在的域名下的时候,在一个域名下注册一个AOR才是有意义的。在大多数情况下,这意味着注册服务的域名需要与AOR的URI中的域名一致。

有许多方法使创建位置服务的内容。其中一种方法是后台管理。上面的例子中,通过读取公司数据库,获知Bob是众多工程部门中的一名员工。尽管如此,SIP提供一种使UA可以明确创建一个绑定的机制。这个机制就是注册服务。

注册服务必须发送一个REGISTER请求给一个特殊类型的UAS,这个UAS就是注册服务器。一个注册服务器是一个域名下的位置服务的前端,它根据REGISTER请求的内容读取和写入映射关系。这个位置服务通常为当前域名下代理服务器提供服务,而这个代理服务器为被路由到当前域名下的请求提供应答。

整个注册过程的流程图在图2中给出。注意注册服务器和代理服务器都是逻辑角色,它们可能是网络上的一个设备;为了清晰起见,在图中将这两部分分离开了。也要注意如果两个服务器是分离的元素,UA可能通过一个代理服务器发送请求到注册服务器。

SIP对位置服务的实现没有特殊的要求。唯一的要求是某些域名下的注册服务器必须能够读取和写入数据到位置服务,而在该域名下的代理服务器和重定向服务器必须也有能力读取这些数据。一些域名下的注册服务器可能与特定的SIP代理服务器被部署在一起。

第二节 构造REGISTER请求

REGISTER请求可以用来添加、删除和查询绑定信息。一个REGISTER请求能够为一个AOR和一个或多个联系地址创建一个新的绑定。注册服务器在第三方认证后,可以作为一个特殊的AOR。一个客户也能够删除早先的绑定也能够查询AOR当前的绑定。

除非特殊说明,REGISTER请求的结构和客户发送一个REGISTER请求的行为与在RFC3261第8.1和17.1节描述的UAC一般性行为一样。

一个REGISTER请求不建立对话。当有一个像RFC3261第8.1节描述的预先存在的路由集时,一个UAC可能在一个REGISTER请求中包含一个Route头域。在REGISTER请求或者应答中Record-Route头域没有意义,并且如果它存在必须忽略它。此外,UAC必须不基于一个对REGISTER请求的应答中,出现或者不出现的Record-Route头域,创建一个新的路由集。

下面的头域,除了Contact,必须被包含在REGISTER请求中。一个Contact头域可能被包含:

 Request-URI: 这个Request-URI指定当前位置服务的域名,这个位置服务是注册服务器所知道的(例如,"sip:chicago.com")。其中组成SIP URI的"userinfo"和"@"部分不能出现。
 To: To头域包括要被注册服务器创建、查询或者修改的的AOR。To头域由于格式中包含一个用户名,所以它和Request-URI头域不相同。这个AOR必须是一个SIP或者SIPS URI。
 From: From头域包含这个信息的用户的AOR。除非请求是一个第三方注册请求,否则这个值与To头域相同。
 Call-ID: 一个UAC所有的注册信息应该使用相同的Call-ID头域的值,以便注册信息发送到一个注册服务器。
     如果同一个客户使用不同的Call-ID,那么注册服务器不能探测REGISTER请求是否因为延时没有按照顺序接收。
 CSeq: CSeq头域的值保证REGISTER请求适当的顺序。对每个拥有相同Call-ID的REGISTER请求,UA必须为CSeq值增加一。
 Contact: REGISTER请求可能包含一个Contact头域,该头域中包含0或多个地址绑定的信息。

当UA没有接收到注册服务器发送的对前一个REGISTER请求的最终应答或者发送前一个请求还没有超时前前,它不能发送一个新的注册信息(也就是,包含新的Contact头域的值,而不是重发)

                                                 bob
                                               +----+
                                               | UA |
                                               |    |
                                               +----+
                                                  |
                                                  |3)INVITE
                                                  |   carol@chicago.com
         chicago.com        +--------+            V
         +---------+ 2)Store|Location|4)Query +-----+
         |Registrar|=======>| Service|<=======|Proxy|sip.chicago.com
         +---------+        +--------+=======>+-----+
               A                      5)Resp      |
               |                                  |
               |                                  |
     1)REGISTER|                                  |
               |                                  |
            +----+                                |
            | UA |<-------------------------------+
   cube2214a|    |                            6)INVITE
            +----+                    carol@cube2214a.chicago.com
             carol

                      Figure 2: REGISTER example

下面列出REGISTER请求中有特殊含义的Contact头域的参数:

action: "action"参数在RFC2543中是不建议使用的。所以UAC应该不使用"action"参数。
expires: "expires"参数指出UA希望当前绑定多长时间有效。这个值是一个以秒为单位的数字。如果这个参数没有被指定,那么这个值由Expires头域中的值代替。某些实现中大于2**32-1(4294967295秒或136年)的值视为等于2**32-1。不合法的值应该被视为等于3600.

添加绑定

REGISTER请求是向注册服务器发送包含联系地址的请求,联系地址是其它发送到该AOR上的SIP请求所要发送到的地址。AOR被包含在REGISTER请求的To头域。

请求中Contact头域的值通常由标识指定SIP终端(例如,"sip:carol@cube2214a.chicago.com")的SIP或SIPS URI组成,但是它们可能使用任何URI模式。例如,一个SIP UA能够决定注册电话号码(使用tel URI, REF2806[9])或者电子邮件地址(使用一个mailto URI, RFC2368[32])作为一个AOR的联系地址的Contact头域。

例如,Carol,使用的AOR是"sip:carol@chicago.com",将在chicago.com域名下的SIP注册服务器中注册。她的注册信息将被chicago.com域名下的代理服务器用来将发送给Carol的AOR上的请求路由到她的SIP终端。

一旦一个客户在注册服务器中创建了绑定,它可能发送一些后继的注册信息,这些后继的注册信息包括新的绑定或者对已存在的绑定的修改信息。对REGISTER请求的2xx应答要包含如下信息。在Contact头域需要包含在当前注册服务器中,对这个AOR已经被注册的完整的绑定信息列表。

如果REGISTER请求中To头域中的AOR是一个SIPS URI,请求中任何Contact头域的值都应该也是SIP URI。客户应该仅在使用其它方法确保联系地址安全的情况下,才能够使用非SIP URI注册在该客户的AOR下。这能用于处理在非TLS协议下,非SIP协议的URI或者非SIP的设备的安全问题。

注册信息不需要更新所有的绑定信息。通常一个UA只更新他自己的联系地址。

设置联系地址的有效期

当客户发送一个REGISTER请求,它可能提供一个建议的有效期,用来指出客户希望这个注册信息在多长时间内有效。(在RFC3261第10.3节描述注册服务器根据本地策略选择实际的间隔时间。)

用户可以使用两种方法为一个绑定设置有效期:通过一个Expires头域或者一个Contact头域的"expires"参数。后面这种方法可以在同一个REGISTER请求中有多个绑定信息的情况下,针对每个绑定信息设置有效期。而前一种方法为所有不包含"expires"参数的Contact头域的值统一设置有效期。

如果设置有效期的两种方式都没有使用,那么这表示客户希望有效期由服务器端决定。

多个联系地址间的优先级

如果在REGISTER请求中有多个Contact头域,这说明进行注册的UA希望将这些Contact头域的值都与To头域中的AOR进行绑定。可以在Contact头域中的列表中使用"q"参数来指定它们的优先级。"q"参数指出这个Contact头域的值与其它Contact头域的值针对当前的AOR的优先级。RFC3261第16.6节描述了一个代理服务器如何使用这个优先级。

移除绑定信息

注册信息是一个软状态,并且在不刷新的情况下会失效,但是它仍然可以被直接移除。客户能够调整RFC3261第10.2.1节描述的注册服务器上选择的有效期。UA通过REGISTER请求为一个联系地址指定"0"有效期来立即移除一个绑定信息。UA应该支持这种机制用来在一个绑定有效期到达之前移除掉这个绑定信息。

REGISTER指定Contact头域的值是"*"表示处理所有的注册信息,但是必须在Expires头域的值为"0"时才能使用它。

 使用"*"作为Contact头域的值允许一个已经注册的UA移除所有于这个AOR的绑定信息,但不用知道这些联系地址的值。

获取绑定信息

对任何REGISTER请求的成功应答都包含已经存在的绑定的完整列表,无论请求中是否包含Contact头域。如果一个REGISTER中没有Contact头域,那么绑定列表将不产生变化。

刷新绑定信息

每个UA都要对早先创建的绑定信息进行刷新。一个UA不应该刷新其它UA建立的绑定信息。

注册服务器发送的200(OK)应答的Contact头域中包含当前所有绑定信息的列表。UA通过RFC3261第19.1.4节描述的对比规则,对比每一个联系地址是否有效。如果有效,它要根据expires参数或者Expires头域来更新有效期。当到达有效期前,UA为每个绑定信息发送了一个REGISTER请求来更新有效期。也可能将一些更新请求合并到一个REGISTER请求。

UA应该在一个周期内使用相同的Call-ID发送注册信息。用于刷新的注册信息应该被发送到与原始注册信息相同网络地址,除非请求被重定向。

设置内部时钟

如果对一个REGISTER请求的应答包含一个Date头域,客户可能使用这个头域来设置当前时间从而设置所有内部时钟。

发现一个注册服务器

UA能够使用三种方法决定向哪个地址发送注册请求:通过配置,使用AOR,和使用广播。一个UA是能够通过配置获得注册服务器的地址,这种方法超出了本手册范围。如果没有配置注册服务器的地址,UA应该使用Request-URI中的AOR的主机名部分,并用一般的SIP服务器定位机制把请求发送到这里[4]。例如,"sip:carol@chicago.com"用户的UA将REGISTER请求定向到"sip:chicago.com"。

最后,一个UA能够使用配置好的广播。广播注册消息到已知的"所有的SIP服务器"的广播地址"sip.mcast.net"(IPv4的224.0.1.75)。IPv6的广播地址还没有被分配;当需要的时候这个地址将被单独的在文档中说明。SIP UA可能监听这个地址并且使用它获得本地的其它用户(见[33]);尽管如此,他们部队请求进行应答。
 广播注册信息可能不能使用在一些环境下,例如,如果多个商务应用共享同一个本地局域网。

传送一个请求

一旦REGISTER方法被构造,并且消息要发送的目标被确定,UAC按照在RFC3261第8.1.2节描述的程序将REGISTER消息转给事务层。

如果事务层因为REGISTER请求没有应答,并返回了一个超时错误,UAC应该不立即重新尝试向同一个注册服务器发送注册信息。
 立即重试很可能还是超时。因为超时情况的发生,而等待一个合理的时间间隔后再重试对降低不必要的网络负载是一个好的方法。这里没有规定这个等待时间间隔是多少。

错误应答

如果一个UA接收到一个423(Interval Too Brief)应答,它可能需要为REGISTER请求中所有的联系地址设置更大的有效期,新的有效期要大于或者等于423(Interval Too Brief)应答的Min-Expires头域的值。

处理REGISTER请求

一个注册服务器是一个UAS,该UAS应答REGISTER请求并且维护一个绑定列表,该绑定列表提供给在它管理域名范围内的代理服务器和重定向服务器使用。一个注册服务器根据RFC3261第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中指定的域名进行绑定。如果没有权限,并且如果该服务器也作为代理服务器,它应该将这个请求发送到那个域名下,按照RFC3261第16节介绍的方法代理发送消息。

 2. 为了保证代理服务器支持任何需要的扩展,注册服务器必须像在RFC3261第8.2.2节描述的那样处理Require头域的值。

 3. 一个注册服务器应该对UAC进行验证。对于SIP UA的验证机制在RFC3261第22节描述。注册行为不能超越SIP验证框架。如果没有验证机制,注册服务器能够得到From头域的地址作为验证的依据。

 4. 注册服务器应该决定是否验证后的用户有权修改它的AOR相关的注册信息。例如,一个注册服务器可能使用一个验证数据库,该验证数据库存储用户名和AOR列表的映射关系,那些拥有令牌的用户可以修改绑定信息。如果被验证过的用户没有被授权修改绑定信息,注册服务器必须返回一个403(Forbidden)应答并略过下面的步骤。

    在支持第三方注册的架构下,一个实体可能被授权来更新多个与它关联的AOR的注册信息。

 5. 注册服务器从请求的To头域解析出AOR。如果AOR在Request-URI指定的域名下不是有效的,注册服务器必须发送一个404(Not Found)应答并且略过剩下的步骤。然后URI必须立即被转换成一个规范的格式。所有的URI参数必须被移除掉(包括用户参数user-param),并且任何非法字符必须被转换成合法格式。最终作为绑定信息的索引使用。

 6. 注册服务器检查请求是否包含Contact头域。如果没有它将略过其它步骤而到最后一步。如果有Contact头域,注册服务器在Contact头域的值中检查是否包含特定的"*"和Expires头域。如果请求有而外的Contact头域或者一个不为零的有效期时间,那么这个请求是无效的,服务器必须返回400(Invalid Request)并且略过剩下的步骤。否则,注册服务器检查Call-ID的值是否每个绑定信息的值相符合。如果不符合,它将移除这个绑定。如果符合它仅仅移除绑定信息中CSeq的值小于请求的CSeq值的绑定信息。否则,更新必须终止并且请求失败。

 7. 注册服务器现在依次处理每一个在Contact头域中的联系地址。对于每一个地址,它按照下面的步骤决定有效期:
    - 如果头域的值有"expires"参数,这个值必须作为请求的有效期。
    - 如果没有这样的参数,但是请求有一个Expires头域,这个头域的值必须作为有效期。
    - 如果都没有,必须指定本地设置的默认值为有效期。
    注册服务器可能决定一个小于请求有效期的值。如果并且只有如果请求的有效期大于零并且小于一小时并且小于一个注册服务器配置的最小值的时候,注册服务器发送423(Interval Too Brief)应答来拒绝注册信息。这个应答必须包含一个Min-Expires头域,该头域的值是注册服务器期望的最小有效期。然后它略过剩下的步骤。
    在需要维持注册状态,并且注册信息会失效的时候,允许服务器设置注册信息的有效期可以避免频繁的刷新注册信息。注册信息的有效期经常在服务创建时使用。一个例子是当用户可能只在某个终端上停留很短的时间时的follow-me(跟随我)服务。因此,注册服务器应该接受有效期较短的注册信息;一个请求只有当刷新时间太短以至于会降低注册服务器性能时才会被拒绝。
    对于每一个地址,注册服务器使用URI的对比原则搜索当前绑定信息的列表。如果绑定信息不存在,它会尝试添加一个。如果绑定信息存在,注册服务器检查Call-ID的值。如果已存在的绑定信息的Call-ID的值与请求中Call-ID的值不相同,如果这个绑定信息的有效期是0则应该删除它,如果这个绑定信息的有效期不是0则更新它。如果Call-ID的值相同,注册服务器对比CSeq值。如果请求中CSeq的值比绑定信息中的值大,注册服务器必须像上面那样更新或者删除绑定信息。否则,不能进行更新并且返回失败应答。
    这是为确保从一个相同的UA发送的,但没有按正确时序接收到的请求被忽略的算法。
    每一个绑定记录从请求中记录Call-ID和CSeq的值。
    当且仅当所有的绑定都被更新并且附加操作的都成功后,绑定信息才必须被提交(提交也就是说,这个修改使代理服务器和重定向服务器可见)。如果有些操作失败了(例如,由于后台数据库提交失败),必须使用500(Server Error)应答请求,并且所有临时更新的绑定信息都必须被移除。

 8. 注册服务器返回一个200(OK)应答。这个应答必须包含列举所有当前绑定信息的Contact头域。每一个Contact头域的值必须给出一个"expires"参数,这个参数指出由注册服务器决定的有效期。这个应答应该包含一个Date头域。
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值