2011/8/9 Carl Wagner carl.wagner@verbalworld.com:
Hi,
I was looking at the 3261 again and have a question.
16.10 CANCEL Processing (Proxy Behavior) ... If a matching response context is found, the element MUST immediately return a 200 (OK) response to the CANCEL request. In this case, the element is acting as a user agent server as defined in Section 8.2. ...
So Kamailio is acting as a UAS when it receives a CANCEL
But it's still a proxy, and Kamailio has NOT previously generated *byitself* provisional non-100 responses for the UAC.
We will assume for now that Asterisk properly constructed the CANCEL.
9.2 Server Behavior (Canceling a Request) ...
Regardless of the method of the original request, as long as the CANCEL matched an existing transaction, the UAS answers the CANCEL request itself with a 200 (OK) response. This response is constructed following the procedures described in Section 8.2.6 noting that the To tag of the response to the CANCEL and the To tag in the response to the original request SHOULD be the same. ...
Who did construct the response (i.e. 180 Ringing) for the original request? the proxy? or the UA in the other side? This section 9.2 is just talking about the dialog endpoints, not about a proxy. Again: a proxy has NOT generated any response for the original request (INVITE), but just the mandatory 100 Trying.
By my reading of 9.2, the portion about the To tag, (In my case)
1) The Original request is the INVITE.
Right.
2) Response to the original request is a 180 Ringing
Generated by the remote endpoint/UA, and NOT by the proxy!
3) Response to the CANCEL is a 200 OK Therefore the To tag in the 180 Ringing must match the To tag in the 200 OK?
Is this right?
No. More comments below.
When 3261 says "the response to the original request" is that the last response?
Not at all. CANCEL is hop-by-hop. Let's shwo an example with parallel forking:
Alice Proxy Bob1 Bob2
INVITE ---------------------> INVITE -----------> INVITE ------------------------------------>
<---- 180 (Totag A) <----------------------------- 180 (Totag B) <----------- 180 (Totag A) <----------- 180 (Totag B)
CANCEL --------------------> <------------ 200 (Totag P)
CANCEL ----------> <--- 200 (Totag A) CANCEL --------------------------------------> <------------------------------- 200 (Totag B)
<--- 487 (Totag A) ACK -----------------> <------------------------------- 487 (Totag B) ACK -------------------------------------------->
<--------------- 487 (Totag A) ACK ---------------------------->
As you can see, when a real UAS (Bob1 and Bob2) receives a CANCEL (from the proxy) the Totag of the 200 for that CANCEL MUST have same Totag as the provisional non-100 responses sent by same UAS to the original request (INVITE). So Bob1 replies "200 Cancelled" with Totag A and Bob2 with Totag B.
But the proxy is not a UAS, it has not generated a provisional non-100 response for the INVITE (but just forwarded them upstream) so when a proxy receives a CANCEL it sets a random Totag (P in the example above) in the "200 Cancelled". That's all.
Later it occurs that the proxy *generates* a CANCEL for each pending branch (Bob1 and Bob2) and receives two 487 (for terminating the INVITE transaction). As a proxy, it chooses one of them (in the example above it chooses the first one coming from Bob1) and forwards the winning reply to the UAC. Of course, such winning reply has a Totag (A) different than the Totag P the proxy replied in the "200 Cancelled". How could be the same?? it's not possible, the proxy MUST reply "200 Cancelled" before habing a winning reply for the INVITE transaction!
Hope it's clear now.
Relevant portions of the log: SIP/2.0 180 Ringing. ... To: sip:SIP_CalledPartyNumber@kamailio_IP;tag=512af75a.
SIP/2.0 200 canceling. ... To: sip:SIP_CalledPartyNumber@kamailio_IP;tag=4ed8ab9f3ed29a77613bb14b3431ff43-2f34.
Not sure how this work with forking.
Because it's correct. Please don't waste more time thinking that what you say above is correct, this topic has been heavily discussed and explained in some lists like sip-implementors.
So to my eyes, this looks like a Kamailio bug?
It's NOT a bug. It's the correct behaviour.
Please tell me where I went wrong.
I hope the explanation with the example helps you.
Regards.
FYI in Asterisk it is dependent on the pedanticsipchecking being enabled. This is set in sip.conf: pedantic=yes
Right. If pedantic=yes, then Asterisk assumes the same wrong concept you have understood and fails to match a 200 "Cancelled" with different Totag (when coming from a proxy). It's a bug in *Asterisk*.