[Home]

Summary:ASTERISK-11026: With "pedantic=yes" Asterisk shouldn't match To tag if the dialog is not established
Reporter:Iñaki Baz Castillo (ibc)Labels:
Date Opened:2007-12-13 06:58:10.000-0600Date Closed:2009-04-09 15:09:16
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Channels/chan_sip/Interoperability
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) 11536.patch
( 1) 11536v2.patch
( 2) asterisk_pedantic_CANCEL_fails.SIP
( 3) canceltags.diff
( 4) debug-Asterisk-pedatic-CANCEL-fails.log
Description:Asterisk in SIP pedantic mode.

- Asterisk calls to an external SIP user in OpenSer proxy.
- After "Ringing" Asterisk sends CANCEL.
- OpenSer replies with "200 canceling" but Asterisk doesn't recognize it so resends the CANCEL.

I've a theory of why it fails:

The "180 Ringing" contains a "To" tag:
 To: <sip:ibc@aliax.net>;tag=veuje

When Asterisk sends CANCEL OpenSer replies with:
 SIP/2.0 200 canceling
 To: <sip:ibc@aliax.net>;tag=373b8885156114ecb2c4bd665f9faf0b-f9aa

So Asterisk asumes wrong To tag (because it's different as the received one) and discards it.

Of course, OpenSer proxy behaviour is correct: there could be many "180 Ringing" each one with different To tag in case of forking scenario, so the To tag in the "200 canceling" from OpenSer *shouldn't* match any previous "To" tag received in any provisional response.

About it I opened a thread in Sip-implementators mailist in which this issue is explained:
 https://lists.cs.columbia.edu/pipermail/sip-implementors/2007-October/017668.html


IMHO the solution would be:
Asterisk shouldn't try to match a To tag if the dialog is not yet established. And Asterisk should assume that it can receive multiples To tag in provisional responses in case of forking scenarios (there are more SIP in the world than just single phones registered in Asterisk XD).
Comments:By: Olle Johansson (oej) 2007-12-15 05:07:31.000-0600

Asterisk's support of non-stateful forking SIp proxys doesn't even exist.

And in this case, you are of course right. Until the dialog is established, we should *not* lock on a To: tag at all, just accept whatever hits us.

By: Iñaki Baz Castillo (ibc) 2007-12-15 16:19:41.000-0600

And is there aim for fixing it? Most SIP UAC's support it correctly, why Asterisk no? ;)

By: Olle Johansson (oej) 2007-12-15 16:22:28.000-0600

I don't know why Asterisk doesn't support it. As you see, there's a long list of bugs to fix, so please have some patience. We'll get to it.

By: Iñaki Baz Castillo (ibc) 2007-12-15 19:26:02.000-0600

Sure, I'll be patient ;)
And thanks a lot for all your work improving SIP stack in Asterisk.

By: Olle Johansson (oej) 2008-02-12 02:11:18.000-0600

[Dec 13 13:35:37] DEBUG[26331] chan_sip.c: Invalid SIP message - rejected , no callid, len 350

??? That's weird.

By: Iñaki Baz Castillo (ibc) 2008-02-12 03:57:15.000-0600

Oej, I've set now debug to 6 (I inspected the code and level 6 is requiered for some logging). I think the issue cause could be cleared with the following capture:


** Asterisk:
INVITE
From: tag=as6dd87ea3

** Openser:
180 Ringing
From: tag=as6dd87ea3
To:  tag=fcpfa

** Asterisk:
CANCEL
From: tag=as6dd87ea3
To:  tag=<none>

** OpenSer:
200 canceling
From: tag=as6dd87ea3
To: tag=373b8885156114ecb2c4bd665f9faf0b-6802
(this To_tag is completely correct according to RFC3261, read the link to sip-implementators maillist in the original report).

** OpenSer:
487 Request Terminated
From: tag=as6dd87ea3
To:  tag=fcpfa

** Asterisk:
ACK
From: tag=as6dd87ea3
To:  tag=fcpfa

--CANCEL again--

** Asterisk:
CANCEL
From: tag=as6dd87ea3
To:  tag=<none>

** OpenSer:
200 canceling
From: tag=as6dd87ea3
To: tag=373b8885156114ecb2c4bd665f9faf0b-6802

** Asterisk:
CANCEL
From: tag=as6dd87ea3
To:  tag=<none>

** OpenSer:
200 canceling
From: tag=as6dd87ea3
To: tag=373b8885156114ecb2c4bd665f9faf0b-6802

...



And this is the bug of Asterisk:

------------------------------------------------------------------------
DEBUG[3691] chan_sip.c: = Looking for  Call ID: 1fd718815516a0a635618ebd747aa53a@88.99.0.111 (Checking To) --From tag as6dd87ea3 --To-tag 373b8885156114ecb2c4bd665f9faf0b-6802  

DEBUG[3691] chan_sip.c: = No match Their Call ID: 1fd718815516a0a635618ebd747aa53a@88.99.0.111 Their Tag fcpfa Our tag: as6dd87ea3

DEBUG[3691] chan_sip.c: That's odd...  Got a response on a call we dont know about. Callid 1fd718815516a0a635618ebd747aa53a@88.99.0.111

DEBUG[3691] chan_sip.c: Invalid SIP message - rejected , no callid, len 351
------------------------------------------------------------------------



I see in the code:


line 5707:
---------------------------------------------------------------------
for (p = dialoglist; p; p = p->next) {
/* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
int found = FALSE;
if (ast_strlen_zero(p->callid))
continue;
if (req->method == SIP_REGISTER)
found = (!strcmp(p->callid, callid));
else
found = (!strcmp(p->callid, callid) &&
(!pedanticsipchecking || !tag || ast_strlen_zero(p->theirtag) || !strcmp(p->theirtag, tag))) ;

ast_debug(5, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag);
---------------------------------------------------------------------


line 5871:
---------------------------------------------------------------------
/* We do not respond to responses for dialogs that we don't know about,
  we just drop the session quickly */
if (intended_method == SIP_RESPONSE)
ast_debug(2, "That's odd...  Got a response on a call we dont know about. Callid %s\n", callid ? callid : "<unknown>");

return p;  <-- "p" is initialized NULL
---------------------------------------------------------------------

By: Iñaki Baz Castillo (ibc) 2008-02-12 04:21:11.000-0600

The problem is in this match:

 found = ... || !strcmp(p->theirtag, tag)

p-theirtag => fcpfa  (The "To_tag" og the first "Ringing" UAC)
tag => as6dd87ea3  (The "From_tag" set by Asterisk in INVITE)

Of course they are not equal so found = FALSE.
But, why the f*** is it matching the From_tag with the first received To_tag???

By: Tilghman Lesher (tilghman) 2008-06-20 11:43:28

I think the response you received on the SIP Implementors list was incorrect.  The section that he cites says this:

<pre>
  While a CANCEL request is handled in a stateful proxy by its own
  server transaction, a new response context is not created for it.
  Instead, the proxy layer searches its existing response contexts for
  the server transaction handling the request associated with this
  CANCEL.  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.  Furthermore, the element MUST generate CANCEL requests
  for all pending client transactions in the context as described in
  Section 16.7 step 10.
</pre>

Note the phrase "the element is acting as a user agent server".  That means that the proxy is acting as a user agent server, and since the RFC refers to an element, ANY element, including a proxy, must act the same way.  In this case, I think that Asterisk is behaving correctly, and it is the proxy which is misbehaving.

By: Iñaki Baz Castillo (ibc) 2008-06-23 02:46:14

No, you are wrong. The proxy behaviour for an incoming CANCEL request is a UAS behaviour since CANCEL is sent **hop by hop**. This is:
If Asterisk (the UAC) sends a CANCEL to a proxy, the proxy tries to match the CANCEL to any existing server transaction (the previous INVITE from Asterisk). If it matches then the proxy (acting as a UAS) MUST reply a 200 OK for that CANCEL. After the 200 OK, the proxy MUST generate CANCEL for all pending client transactions generated by the initial INVITE from Asterisk.
CANCEL is "hop by hop", not "end to end" as INVITE.

Please, believe me that Asterisk is completely wrong in this bug.

By: Iñaki Baz Castillo (ibc) 2008-06-23 07:22:59

Also note that "8.2 UAS Behavior" just talks about it, about the behaviour of a UAS when receiving a request. But note that, in fact, a proxy becomes a UAS when receives a CANCEL and also becomes a UAC when sending the CANCEL to all the pending clients (forking scenario).

This is: a proxy does proxing for an INVITE and doesn't generate a positive reply (2XX) for it. It must be the UAS (or UAS's) the responsible SIP elements that create the 2XX and the proxy will forward it upstream to the UAC.
But when a proxy receives a CANCEL for a previous INVITE it must generate by itself the 200 reply and send it quickly to the UAC, and later send the CANCEL to the pending called UAS's.

This is the RFC3261 behaviour, and this is the behaviour of the proxy I use (OpenSer). The problem is that Asterisk acting as UAC doesn't recognize the 200 reply from OpenSer after the CANCEL. And Asterisk doesn't recognize it because it expects to match the To "tag" with the previous To "tag" in 1XX responses, but here Asterisk fails (as Oej has said above) since Asterisk doesn't understand parallel forking and a 200 OK sent by a proxy.

By: Olle Johansson (oej) 2008-07-01 07:50:27

This is indeed a bug in Asterisk that needs fixing.

By: Mark Michelson (mmichelson) 2008-08-08 15:58:35

I have uploaded a patch which addresses this issue.

The way it works is that sip_pvt structures now have a new flag which tells if a dialog has been established. A dialog is determined to be established if it has reached the "confirmed" state as defined by RFC3261 (as opposed to the "early" state).

Using this patch, Aterisk will set the flag as a UAC when
- It receives a 200 OK in response to an INVITE
- It receives a 200 OK in response to a SUBSCRIBE

Asterisk will set the flag as a UAS when
- It sends a 200 OK in response to an INVITE
- It sends a 200 OK in response to a SUBSCRIBE

Asterisk will clear the flag as a UAC when
- It sends a BYE request

Asterisk will clear the flag as a UAS when
- It sends a 200 OK in response to a BYE

Asterisk will only compare its local tag to the remote tag of the far-end UA if the dialog has been established.

Please test this out. It worked for me in my small test setup, but as with all things SIP-related, I feel it's best for it to receive some wider testing before committing the patch.



By: Mark Michelson (mmichelson) 2008-08-18 16:16:00

It turns out that I misinterpreted section 15.1.1 of RFC 3261 with regards to when a UAC should consider a dialog to be dissolved. The section states that media sessions should be considered closed as soon as a UAC sends a BYE request. I also took this to mean that the dialog between the two UAs should also be closed. This, however, is incorrect, so I have modified the patch to clear the flag as a UAC when a 200 OK is received in response to a BYE. This patch has been uploaded as 11536v2.patch and is ready for testing.

By: Mark Michelson (mmichelson) 2008-09-08 15:59:57

I've given this plenty of time to be tested. My local tests have worked fine and I haven't heard any complaints about the patch yet. I will go ahead and commit this.

By: Digium Subversion (svnbot) 2008-09-08 16:00:42

Repository: asterisk
Revision: 141809

U   branches/1.4/channels/chan_sip.c

------------------------------------------------------------------------
r141809 | mmichelson | 2008-09-08 16:00:42 -0500 (Mon, 08 Sep 2008) | 14 lines

Fix pedantic mode of chan_sip to only check the
remote tag of an endpoint once a dialog has
been confirmed. Up until that point, it is possible
and legal for the far-end to send provisional
responses with a different To: tag each time. With
this patch applied, these provisional messages
will not cause a matching problem.

(closes issue ASTERISK-11026)
Reported by: ibc
Patches:
     11536v2.patch uploaded by putnopvut (license 60)


------------------------------------------------------------------------

http://svn.digium.com/view/asterisk?view=rev&revision=141809

By: Digium Subversion (svnbot) 2009-04-09 15:09:14

Repository: asterisk
Revision: 187554

_U  branches/1.6.0/
U   branches/1.6.0/channels/chan_sip.c

------------------------------------------------------------------------
r187554 | mmichelson | 2009-04-09 15:09:14 -0500 (Thu, 09 Apr 2009) | 34 lines

Merged revisions 141810,141868 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk

................
 r141810 | mmichelson | 2008-09-08 16:18:49 -0500 (Mon, 08 Sep 2008) | 22 lines
 
 Merged revisions 141809 via svnmerge from
 https://origsvn.digium.com/svn/asterisk/branches/1.4
 
 ........
 r141809 | mmichelson | 2008-09-08 16:10:10 -0500 (Mon, 08 Sep 2008) | 14 lines
 
 Fix pedantic mode of chan_sip to only check the
 remote tag of an endpoint once a dialog has
 been confirmed. Up until that point, it is possible
 and legal for the far-end to send provisional
 responses with a different To: tag each time. With
 this patch applied, these provisional messages
 will not cause a matching problem.
 
 (closes issue ASTERISK-11026)
 Reported by: ibc
 Patches:
       11536v2.patch uploaded by putnopvut (license 60)
 
 
 ........
................
 r141868 | mmichelson | 2008-09-08 17:14:40 -0500 (Mon, 08 Sep 2008) | 4 lines
 
 Um, apparently I didn't actually finish merging before committing.
 Bad bad bad
................

------------------------------------------------------------------------

http://svn.digium.com/view/asterisk?view=rev&revision=187554