分享

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

 gljin_cn 2014-03-16
处理4xx应答

某个特定的4xx应答需要特定的UA处理,而不依赖于请求的方法。

如果接收到一个401(Unauthorized)或者407(Proxy Authentication Required)应答,UAC应该按照授权处理流程(RFC3261第22.2节和22.3节)携带凭证再次尝试请求。

如果接收到一个413(请求实体过长)应答(RFC3261第21.4.11节),说明该请求包含的实体长于UAS限制的实体长度。如果可能,UAC应该忽略消息体或者使用更短的实体重新尝试请求。

如果接收到一个415(不支持的媒体类型)应答(RFC3261第21.4.13节),说明请求包含了UAS不支持的媒体类型。UAC应该仅仅使用在应答的Accept头域列出的类型,使用的编码在应答的Accept-Encoding头域列出,语言在应答的Accept-Language头域列出。

如果接收到一个416(不支持的URI模式)应答(RFC3261第21.4.14节),说明Request-URI使用了一个服务器不支持的URI模式。客户端应该使用SIP URI模式重新尝试。

如果接收到一个420(错误的扩展)应答(RFC3261第21.4.15节),说明请求在Require或Proxy-Require头域列出了一个不被代理或者UAS支持的扩展选项。UAC应该忽略在应答的Unsupported头域中列出的扩展并重新尝试。

在所有上述的情况中,请求被相应的进行修改并创建新的请求。这个新的请求创建一个新的事务,其中Call-ID, To, 和From头域与前一个请求一致,而CSeq头域应该包含一个大于原来的新的顺序号。

对于其它的4xx应答,是否尝试重新发送新的请求依赖于请求的方法和用例。

第二节 UAS行为

当一个对话外请求被一个UAS处理,有一系列要遵循的与请求方法无关的规则。RFC3261第12节对一个UAS如何对对话内或对话外请求进行应答做了指导。

注意,请求处理是自动进行的。如果一个请求被接受,与它相关的所有状态必须改变为接受。如果一个请求被拒绝,那么与它相关的所有状态必须改变为拒绝。

所有的UAS必须按照本节给出的步骤处理请求(即,从验证开始,然后检查方法、头域和其它所有本节提到的内容)。

方法检查

一但一个请求被验证(或者不需要验证),UAS必须检查请求的方法。如果UAS认识但不支持这个方法,他必须创建一个405应答(方法不被允许)。创建应答的方式在RFC3261第8.2.6节描述。UAS必须同事添加一个Allow头域到405应答。Allow头域必须列出UAS支持的方法。Allow头域在RFC3261第20.5节介绍。

如果请求的方法被服务器支持,则继续处理。

头域检查

如果UAS不能明白一个在请求中的头域(这说明,这个头域没有在这个手册或者其它扩展中定义),服务器必须忽略该头域并继续处理这个请求。UAS应该忽略任何处理该请求所不需要的头域。

To头域和Request-URI头域

To头域包含由From头域标识的发送者发送的请求的原始接收者。原始接收者可能是也可能不是要处理这个请求的UAS,因为会有呼叫转移或者其它代理操作。当一个请求的To头域与UAS不同时,UAS可能用任何策略来决定是否接受请求。尽管如此,UAS即使在To头域中是不认识URI模式(例如,一个tel的URI)或者To头域没有标识一个此UAS认识的或有效的用户,但是推荐接受该请求。如果UAS决定拒绝请求,它应该构造一个状态码是403(Forbidden)的应答,并且将该应答交给服务器的事务层去传输。虽然Request-URI头域标识处理请求的UAS。如果Request-URI使用一个UAS不支持的模式,它应该使用416(Unsupported URI Scheme)应答来拒绝该请求。如果Request-URI标识一个UAS不希望接受的地址,它应该使用404(Not Found)应答。一个UA使用REGISTER方法绑定它的address-of-record到一个特定的contact地址,将能够接收到Record-URI等于这个contact地址的请求。其它可接收到Request-URI的潜在的资源包括被UA用来建立或者刷新会话的请求或者应答的Contact头域。

合并请求

如果一个请求的To头域不包含tag,UAS必须检查当前事务上的请求。如果请求的From头域的tag标志、Call-ID和CSeq与被该请求的事务的这些项完全匹配,但是请求与这个事务不匹配(基本的匹配规则在RFC3261第17.2.3节介绍)。UAS内核应该构造一个482(Loop Detected)应答并传递给服务器的事务。

一个相同的请求从不同的路径被发送到UAS多次,这多因为有分支。UAS处理第一个接收到的请求并发送一个482(Loop Detected)应答来消除它们。

Require头域

假定UAS是合适处理这个请求的元素,如果有的话,检查Require头域。

Require头域被UAC用于告诉UAS关于SIP扩展的,这些扩展是UAC希望UAS为了能够正确地处理处理请求而支持的。它的格式在RFC3261第20.32节描述。如果UAS不认识一个在Require头域中列出的可选标记,它将创建并发送一个状态码为420(Bad Extension)的应答。这个UAS必须增加一个Unsupported头域,并且将它在Require头域中不认识的选项列在列出来。

注意,Require头域和Proxy-Require头域不能在一个SIP的CANCEL请求,或者一个对应于非2xx应答的ACK中使用。这些头域如果出现在这些请求中,那么必须被忽略。

一个对应于2xx应答的ACK必须只包含出现在初始请求中的Require头域和Proxy-Require的值。

例如:

      UAC->UAS:   INVITE sip:watson@bell-telephone.com SIP/2.0
                  Require: 100rel

      UAS->UAC:   SIP/2.0 420 Bad Extension
                  Unsupported: 100rel

这个行为是在所有选项都被双方认识时,保证客户端服务器可以无延时的交互。在选项不是全部都被双方认识(例如上面的例子)时会使交互减慢。对于一对匹配的客户端服务器对,相互交互非常快,因为保存了往返协商的过程。此外,这也消除了服务器不认识客户端扩展引起的含糊。一些特性只应用于特定的终端,例如呼叫管理域。

内容处理

如果UAS认识任何被客户端请求的扩展,UAS要检查消息体和消息的头域。如果有任何消息体的类型(由Content-Type标识),语言(由Content-Language标识)或者编码(由Content-Encoding标识)不被认识,并且这个消息体部分不是可选的(由Content-Disposition头域标识),UAS必须使用一个415(Unsupported Media Type)应答来拒绝请求。当请求包含的消息体类型有不被UAS所认识的时候,应答必须包含一个Accept头域,并列出所有它认识的消息体类型。如果消息体的编码不被UAS认识,应答必须包含一个Accept-Encoding头域列出能够被UAS识别的所有编码。如果请求包含的消息体的语言不能被UAS认识,应答必须包含一个Accept-Language头域指出UAS认识的语言。除了这些检查,消息体的处理还依赖于方法和类型。关于处理content-specific头域的信息请参看RFC3261第7.4节和第20.11节到20.15节。

应用扩展

能够应用扩展的UAS不能在产生应答的时候使用扩展,除非在请求的Supported头域说明支持此扩展。如果扩展是不被支持的,那么服务器必须只依赖标准的SIP或者客户端支持的扩展来构造应答。在一些特殊环境下,服务器不使用扩展就不能处理请求,那么服务器应该发送421(Extension Required)应答。这个应答说明如果不使用一个特定的扩展服务器就不能构造正确的应答。要被使用的扩展必须在421应答的Require头域中指定。这个处理是不被推荐的,因为这将破坏客户端与服务器间的相互工作。

任何应用于非421应答中的扩展必须列在应答的Require头域中。当然,服务器不能使用没有列在请求的Supported头域中的扩展。因此,应答中Require头域仅仅包含在标准RFC中的扩展。

处理请求

假设通过了前面各节描述的所有的检查,那么UAS下面的处理将根据不同的方法而不同。RFC3261第10节讲述REGISTER请求,第11节讲述OPTIONS请求,第13节讲述INVITE请求,第15节讲述BYE请求。

创建应答

当UAS要为一个请求构造应答时,它将按照下面各节讲述的一般创建过程来做。根据特定的应答状态码需要的特定的行为也是需要的,但它不在本章介绍。

发送一个临时应答

一个主要的与方法无关的创建应答的方针是,UAS不能向一个非INVITE请求发送临时应答。取而代之,UAS应该立即发送一个最终应答给非INVITE请求。

当创建了一个100(Trying)应答,任何在请求中出现的Timestamp头域必须拷贝到这个100(Trying)应答中。如果构造应答有延时,UAS应该在应答的Timestamp头域中加上这个延时。这个延时必须包含发送应答和接收请求的差值,以秒为单位。

头域和Tag

应答的From头域必须等于请求的From头域。应答的Call-ID头域必须等于请求的Call-ID头域。应答的CSeq头域必须等于请求的CSeq头域。应答的Via头域必须等于请求的Via头域,并且维持相同的顺序。

如果请求的To头域有tag标签,那么应答中的To头域必须等于请求中的To头域。尽管如此,如果请求中的To头域不包含tag标签,应答中To头域的URI必须等于请求中To头域的URI;此外,UAS必须向应答的To头域添加tag标签(100(Trying)应答是个例外,它可能已经有tag标签了)。服务器用此作为UAS正在应答的标志,它也是对话中对话ID的组成部分。对一个请求的所有应答,包括最终应答和临时应答(除了100(Trying)),必须使用相同的tag标签。创建tag标签定义在RFC3261第19.3节。

无状态UAS行为

一个无状态UAS是一个不维持事务状态的UAS。它一般对请求进行回复,但是在送了最终应答后,它将废弃所有在UAS保留的状态。如果一个无状态的UAS接收到一个重发的请求,它会重新创建应答并发送它,就像答复一个第一次发送的请求。除非对于请求的方法来说,相同的请求总是得到相同的应答,否则UAS不能是无状态的。这个规则使注册服务不能是无状态的。无状态UAS不使用事务层;它直接从传输层接收请求并直接把应答发送给传输层。

无状态UAS主要是处理无须验证的请求并且对这个请求的应答是可以预期确定的。如果不需要验证的请求被有状态的UAS处理,那么大量的不需要验证的请求将创建大量的事务将减慢或者完全使UAS停止处理。这就形成了拒绝服务环境。更多信息参看RFC3261第26.1.5节。

无状态UAS主要的行为是:

    o 一个无状态UAS必须不发送临时(1xx)应答。

    o 一个无状态UAS必须不重复传输应答。

    o 一个无状态UAS必须忽略ACK请求。

    o 一个无状态UAS必须忽略CANCEL请求。

    o 应答的To头域tag必须被构造为无状态方式 - 这种方式将为相同的请求构造相同的tag。构造tag的介绍请参看RFC3261第19.3节。

在所有其它方面,一个无状态的UAS的行为与有状态的UAS相同。一个UAS能够用有状态和无状态两种模式操作每一个新的请求。

  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多