Summary:ASTERISK-19358: Failed to CANCEL a call in ringing state (SIP) in
Reporter:Karsten Wemheuer (kwemheuer)Labels:regression
Date Opened:2012-02-14 12:20:15.000-0600Date Closed:2012-02-17 13:02:19.000-0600
Versions: Frequency of
must be completed before resolvingASTERISK-19128 Asterisk 1.8.10 Blockers
must be completed before resolvingASTERISK-19129 Asterisk 10.2.0 Blockers
is the original version of this clone:ASTERISK-19937 Still not working - Failed to CANCEL a call in ringing state (SIP) in, 1.8.11,
Environment:Debian Squeeze, Asterisk, OpenSIPSAttachments:( 0) ASTERISK-19358.patch
( 1) ASTERISK-19358.patch
( 2) ngrep-commented_multiple-phones.txt
( 3) ngrep-commented_working-patch.txt
( 4) ngrep-commented.txt
Description:I got a problem with asterisk The same scenario is working fine in

Asterisk calls a SIP phone via a proxy, proxy phone and asterisk are on the same LAN, no NAT.

Asterisk sends the INVITE to the proxy, the proxy sends INVITE to the phone. The phone sends 180 RINGING back to the proxy. The proxy sends 180 RINGING to asterisk. So far so good. If the calling side decides to cancel the call, asterisk sends the CANCEL directly to the phone. The phone doesn't find the call and answers 404. In asterisk asterisk sends the CANCEL to the proxy, which sends the CANCEL to the
phone and all is fine.

I _think_ it might be the code in function handle_response_invite(), where the lines
parse_ok_contact(p, req);
if (!reinvite) {
  build_route(p, req, 1);
were inserted for handling provisional SIP response.
I attach a commented SIP trace (ngrep).
Comments:By: Karsten Wemheuer (kwemheuer) 2012-02-14 12:21:35.666-0600

Trace generated with ngrep, stripped down to the (hopefully) relevant things, commented.

By: Mark Michelson (mmichelson) 2012-02-14 13:24:32.723-0600

Relevant notes from RFC 3261, section 9.1:

"The Request-URI, Call-ID, To, the numeric part of the CSeq, and From header fields in the CANCEL request MUST be identical to those in the request being cancelled, including tags."

"The destination address, port, and transport for the CANCEL MUST be identical to those used to send the original request."

So, the fact that Asterisk did not include a To-tag in the CANCEL seems like correct behavior. However, not sending to the proxy appears to be incorrect behavior.

By: Mark Michelson (mmichelson) 2012-02-14 14:07:41.523-0600

I'm uploading ASTERISK-19358.patch on this issue. I'm not able to test easily since I don't have a proxy. However, I think this should do the trick. Please let us know if it works.

By: Karsten Wemheuer (kwemheuer) 2012-02-14 14:39:06.915-0600

The patch seems to work. I attached a new commented ngrep trace. The CANCEL ist directed to the proxy and the behavior seems to be as in earlier versions. I'll do some more testing and let keep You informed. Thanks for the fast solution.

By: Mark Michelson (mmichelson) 2012-02-15 16:13:28.896-0600

Okay, I'm going to go ahead and commit the contents of the patch. I'll leave this issue open until you tell me I should close it though.

By: Karsten Wemheuer (kwemheuer) 2012-02-16 04:00:47.106-0600

While doing some tests with ringing multiple phones and connecting and cancelling calls, I found the following misbehaviour.

Asterisk sends the INVITE to the proxy, the proxy sends INVITE to the phone. In this case there are two phones. Both phones are sending provisional messages 180 Ringing. Asterisk stores information for first phone. If the call is answered by second phone, asterisk sends ACK to first phone. In this case the phone which gets connection will never get the ACK and will terminate about 30 seconds later. I attach a new commented ngrep trace (ngrep-commented_multiple-phones.txt). I think, the section where asterisk sends the ACK for 200 OK should not rely on the stored information from the provisional response (180 ringing). Instead asterisk should use the information contained in the 200 OK instead. But may be wrong.

By: Karsten Wemheuer (kwemheuer) 2012-02-16 04:02:13.375-0600

Call of asterisk via proxy to two phones, call terminates after 30 seconds. Asterisk sends ACK to the wrong phone.

By: Karsten Wemheuer (kwemheuer) 2012-02-16 04:47:50.633-0600

In the log I can see this message:
{noformat}build_route: Retaining previous route: <sip:arthur@>{noformat}
when receiving 200 OK from phone2.

I _think_, but I am not sure, that in case of 200 OK the route set should be updated with data of the real connected party.

By: Walter Doekes (wdoekes) 2012-02-16 06:07:19.409-0600

Confirmed. Sipp scenario to test it: http://fpaste.org/4Grj/
Stefan Schmidts believes he broke it.
{quote}12:22 < schmidts> damn my patch that asterisk will build the right contact even on a provisional response has broke some stuff{quote}

By: Stefan Schmidt (schmidts) 2012-02-16 06:22:54.086-0600

if this is related to the original change i added to honor a record route even in a provisional response then it was my fault.
i have basically the same setup and iam trying to reproduce this issue but i wasnt able to do this.

i will try the sipp scenario from walter.

By: Stefan Schmidt (schmidts) 2012-02-16 08:05:48.474-0600

the problem with this change i brought in to also honor route sets from a provisional response was, that asterisk not only stores the route set, it doesnt change it later. this patch solves this problem by making the route set not persistant so it will be replaced with the information from a 200 ok.
This will not solve the Cancel problem but it will save the problems with the wrong ACKs.

i will put this patch to reviewboard to get this into the source quick.

By: Karsten Wemheuer (kwemheuer) 2012-02-16 08:33:20.224-0600

The patch from Mark, published on 14/Feb/12 2:07 PM works for the CANCEL issue. I think, from looking at the source, that a combination of both patches will fix the issues I had. I'll check that and keep You informed.

By: Karsten Wemheuer (kwemheuer) 2012-02-17 08:28:41.987-0600

I just checked with a combination of the last patch published in the reviewboard and the patch from Mark from 14/Feb/12 2:37 PM and it solves both, the original issue with sending CANCEL to the wrong destination and the additional issue where the ACK gets the wrong way.