现在的位置: 首页 > 综合 > 正文

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

2013年08月24日 ⁄ 综合 ⁄ 共 2384字 ⁄ 字号 评论关闭

第六章 取消一个请求

前面一章介绍了UA对所有方法创建请求和处理请求生成应答的一般性行为。这一章我们讨论一个有目的方法,叫做CANCEL。

CANCEL请求与它名字暗示的一样,用来取消一个客户端先前发送的请求。详细的说,它使UAS终止对这个请求的处理并为这个请求构造一个错误应答。CANCEL请求对已经发送了最终应答的请求无效,所以经常对那些需要服务器长时间处理的请求使用CANCEL。这样,对于需要用很长时间应答的INVITE请求来说,非常合适使用CANCEL请求来取消它。一个接收到取消INVITE的CANCEL请求且还没有发送最终应答的UAS将“停止响铃”,并且立即对这个INVITE请求发送一个特定错误代码(487)的应答。

CANCEL请求可以被代理或UAC创建和发送。RFC3261第15节讨论在什么情况下UAC将CANCEL一个INVITE请求。RFC3261第16.1节讨论代理服务器的CANCEL请求。

有状态的代理服务器要对CANCEL进行应答,而不是简单的转发从网络流中下一个元素收到的应答。因此,CANCEL是一个“逐跳式”的请求,也就是每一个有状态的代理都需要对它进行应答。

第一节 客户端行为

一个CANCEL请求不应该被用来取消一个非INVITE请求。

 因为非INVITE请求都是立即被应答,为非INVITE请求发送CANCEL会引起竞争(非INVITE和CANCEL谁先被处理)。

下面的流程用来构造CANCEL请求。CANCEL请求的Request-URI, Call-ID, To, CSeq的数字部分和From头域以及这些头域中的标记都要与要被取消的请求一样。一个由客户端构造的CANCEL请求必须只包含一个Via头域值,这个值与要被取消的请求的Via头域中顶部的值一致。让CANCEL中这些头域的值与要被取消的请求头域值保持一致,是为了匹配需要取消的请求(RFC3261第9.2节介绍如何匹配)。尽管如此,CSeq头域的方法名部分必须是CANCEL,这是为了作为一个事务来正确的标识和处理CANCEL请求(RFC3261第17节)。

如果要被取消的请求包含Route头域。CANCEL也必须包含Route头域并保证值一致。

 这是为了无状态代理服务器能够适当的路由CANCEL请求。
 
CANCEL请求必须不包含任何Require或Proxy-Require头域。

一旦CANCEL请求被构造完成,客户端应该检查是否收到对要被取消的消息的应答(临时应答和最终应答)(以后成要被取消的请求为原始请求)。

如果没有接收到临时应答,不能发送CANCEL请求。客户端在发送CANCEL请求前必须等待接收到一个临时应答。如果接收到了一个最终应答,那么不能发送CANCEL请求。因为此时对一个已经发送了最终应答的原始请求发送CANCEL请求是无效操作。当客户端决定发送CANCEL请求,它连同目标地址和端口为CANCEL请求创建一个客户事务并进行传输。目标地址、端口和传输方式必须与发送原始请求时一致。
 
 如果允许在接收到临时应答前发送CANCEL请求,那么服务器端可能在接收到原始请求前就接收到CANCEL请求。
 
注意,CANCEL请求的事务和原始请求的事务必须完全独立。无论如何,一个UAC不能依赖于接收到一个对原始请求的487(Request Terminated)应答来取消该原始请求,因为RFC 2543中的UAS永远不会创建这样的应答。如果在64*T1秒(T1在RFC3261第17.1.1.1节中定义)内没有收到最终应答,客户端应该取消原始的事务并应该删除处理原始请求的事务。

第二节 服务器行为

CANCEL方法的请求在服务器端TU中取消一个未抉择的事务。TU收到CANCEL请求表示要取消一个事务,而这个事务的方法不能是CANCEL或ACK。然后TU根据RFC3261第17.2.3节描述的事务匹配方法找到的所匹配的事务就是要被取消的事务。

在服务器端处理一个CANCEL请求的过程依赖于服务器类型。无状态代理服务器将会向前传递该CANCEL请求。有状态代理服务器会对CANCEL请求进行应答,并创建一些它自己的CANCEL请求,这些CANCEL请求由UAS来应答。RFC3261第16.10节介绍代理服务器如何处理CANCEL请求。

一个UAS先按照RFC3261第8.2节描述的一般过程来处理CANCEL请求。然而,虽然CANCEL请求是逐跳传输的,并且它不能被多次提交,但服务器端不能为了获得适当的凭证在Authorization头域对它进行挑战。注意,CANCEL请求也不能包含Require头域。

如果UAS根据以上的处理过程不能够找到CANCEL请求所要取消的事务,它应该为CANCEL请求发送481(Call Leg/Transaction Does Not Exist)应答。如果原始请求的事务存在,那么UAS接收到CANCEL请求后的行为依赖于它是否发送了最终应答。如果已经发送了最终应答,那么CANCEL请求对原始请求的处理,对会话状态以及对原始请求应答的构造都没有任何影响。如果UAS没有发送最终应答,它的行为依赖于原始请求的方法。如果原始请求是INVITE方法,UAS应该立即为这个INVITE请求发送应答487(Request Terminated)。本手册中没有定义收到CANCEL请求后如何处理其它方法的事务。

无论要取消的原始请求的方法是什么,只要CANCEL请求匹配到了一个现存的事务,UAS发送200(OK)应答。这个应答的构造遵循RFC3261第8.2.6节描述的过程。值得注意的是,对CANCEL请求的应答中的To头域的tag应该与对原始请求的应答中的To头域的tag保持一致。对CANCEL请求的应答被传送到服务器事务中进行传输。

 

 

 

 

 

 

抱歉!评论已关闭.