[OpenSIPS-Users] FW: CANCELs with no transaction

Juri Nysschen juri at greydotelecom.com
Wed Feb 16 07:32:33 CET 2011


Hi Dave,

It worked! The CDRs are perfect. Thanks for the help.

Here's the code in case anyone else has the same issue:

rout{

    ......

    # handle cancel and re-transmissions
	if (is_method("CANCEL") ) {
		xlog("L_INFO","CANCEL [$fd/$fu/$rd/$ru/$si/]\n");
		setflag(3); # start db accounting
		setflag(5); # log failed transactions
		route(5); # disconnect media proxy
		if (t_check_trans()){
			t_relay();
			exit;
		}
		xlog("L_INFO","CANCEL Generated [$fd/$fu/$rd/$ru/$si/]\n"); 
		# send a CANCEL downstream
		exec_msg("/usr/sbin/opensipsctl fifo t_uac_cancel $ci $cs");

		# send a ACK upstream for cdr purposes.
		sl_send_reply("200","OK");
		exit;
	}

}

Regards
Juri Nysschen
-----Original Message-----
From: users-bounces at lists.opensips.org
[mailto:users-bounces at lists.opensips.org] On Behalf Of Dave Singer
Sent: Tuesday, February 15, 2011 8:28 PM
To: OpenSIPS users mailling list
Subject: Re: [OpenSIPS-Users] FW: CANCELs with no transaction

Juri,

You should be able to get to it with
  $(hdr(via){param.value,branch})
But forcing it on the outbound cancel would probably be quite a trick
since opensips wants to add It's via header automatically and that top
via is what the next hop is counting on for matching the call.
I think your best bet is to use the MI t_uac_cancel command as
described last time. With it you don't have to same anything from the
INVITE. You just use the callid and cseq from the CANCEL to pass to
the MI command t_uac_cancel.
Be aware you may have linux and selinux permissions conflicts for
executing opensipsctl from inside opensips. I posted in a thread a
thing about dealing with selinux in the last couple months that makes
it quite easy if selinux is a problem and to see if it is the problem.
Your command would be something like:
exec("/usr/local/opensips/sbin/opensipsctl  fifo t_uac_cancel $ci $cs");
Don't forget to make sure the source canceling the call gets the
response they are looking for so they don't keep sending you cancels
and you keep doing the exec over and over.

Dave

On Tue, Feb 15, 2011 at 5:52 AM, Juri Nysschen <juri at greydotelecom.com>
wrote:
> Hi Dave
>
> I have used wireshark to review the cancel message on a call timeout
(which
> works) and when received from the UA.
>
> The difference is in the branch= value as you predicted.
>
> How can I save the branch value on the INVITE and then change it on the
> CANCEL?
> I've tried all sorts of combinations for $branch but the vales are always
> NULL
>
>
> Regards
> Juri Nysschen
>
> -----Original Message-----
> From: users-bounces at lists.opensips.org
> [mailto:users-bounces at lists.opensips.org] On Behalf Of Dave Singer
> Sent: Monday, February 14, 2011 10:16 PM
> To: OpenSIPS users mailling list
> Subject: Re: [OpenSIPS-Users] FW: CANCELs with no transaction
>
> Juri,
>
> This was gnawing at me so I searched and found the "official" answer
> of what a CANCEL should look like.
> Go to
> http://www.ietf.org/rfc/rfc3261.txt
> and search for "9 Canceling a Request"
> From what I read it basically says that the CANCEL should be nearly
> identical to the INVITE it is canceling (without some headers that
> aren't useful in a cancel like Supported)
> It seems that the "branch=...." , a "Magic Cookie", on the top most
> via line is a turbo lookup to finding the transaction. That matches
> the original INVITE and all is well. If it is not there then it has to
> compare all the pertinent headers between invite and cancel.
>
> So if you can't get them to send the proper stuff, you could modify
> the previous hack to store the branch=... that opensips put in the via
> header it added (probably can't see it when sending the invite but it
> is in the 1xx response to your invite.
> Actually I just found one better I think. Use the exec module to
> execute MI command t_uac_cancel
> (http://www.opensips.org/html/docs/modules/1.6.x/tm.html#id294623)
> All it needs are callid and cseq num, which I hope at least they are
> the same as the INVITE, which you can use the CANCEL's parsed vars for
> the params. I you will probably need to send back a negative response
> to the bad CANCEL like 400 Bad Message (look up appropriate
> code/message). And I think the t_uac_cancel will also push into
> failure_route a 487 response, which if you don't choose anything else
> specifically, will be sent back to the originator.
> You will want to verify it with packet captures and see how it affects
> your cdrs.
>
> Let me know the outcome.
>
> Dave
>
> On Mon, Feb 14, 2011 at 11:05 AM, Dave Singer <dave.singer at wideideas.com>
> wrote:
>> I was half expecting that kind of result.
>> I don't know what exactly opensips uses to match transactions. I
>> believe Call-id and CSeq headers being the same but I'm quite sure
>> there is more like maybe from tag? I don't know.
>>
>> Can anyone else chime in on what opensips is checking to match a
> transaction.
>>
>> Dave.
>>
>> On Sun, Feb 13, 2011 at 11:36 PM, Juri Nysschen <juri at greydotelecom.com>
> wrote:
>>> Hi Dave,
>>>
>>> Thanks this method is very successful in delivering the CANCEL
> downstream,
>>> over multiple hops, unfortunately the PSTN also doesn't see the
> transaction
>>> id and therefore the call keeps ringing.
>>> The key is finding the reason why the transaction id disappears or at
> least
>>> be able to put it back when delivering the CANCEL downstream.
>>>
>>> Regards
>>> Juri Nysschen
>>>
>>> -----Original Message-----
>>> From: users-bounces at lists.opensips.org
>>> [mailto:users-bounces at lists.opensips.org] On Behalf Of Dave Singer
>>> Sent: Monday, February 14, 2011 9:03 AM
>>> To: tyler at fonality.com; OpenSIPS users mailling list
>>> Subject: Re: [OpenSIPS-Users] FW: CANCELs with no transaction
>>>
>>> Juri,
>>>
>>> You say it only happens after a do_routing(). To be clear, you mean
>>> that you used do_routing on the invite and not that you already tried
>>> do_routing for the cancel earlier in the script. (I'm not sure it
>>> would make any difference)
>>>
>>> The hack to store the destination in a variable is one you would want
>>> to strongly avoid. But sometimes hacks are unavoidable and a stop gap
>>> until you can really resolve the problem.
>>> I believe $avp's are retained per transaction and if the
>>> t_check_trans() fails then the $avp created in the reply would also
>>> not be available.
>>> $var also would not work most of the time since it is persistent per
>>> process.  You would need to use core functions cache_store and
>>> cache_fetch using either local_cache or memcached backend depending if
>>> you need persistant between opensips reboot.
>>> Example:
>>>
>>> route{
>>>
>>> .....
>>>
>>>      if (is_method("CANCEL") ) {
>>>
>>>            route(5); # drop media proxy
>>>
>>>            if (t_check_trans()){ # this always fails after a
do_routing()
>>>
>>>                  xlog("L_INFO","CANCEL
>>> Transaction[$fd/$fu/$rd/$ru/$si/]\n");
>>>
>>>                  t_relay();
>>>
>>>                  exit;
>>>
>>>            } else {
>>>
>>>                 if ( cache_fetch("local", "tran_dest_$ci",
>>> "$avp(s:next_hop)") ) {
>>>                      $rd = $avp(s:next_hop);
>>>                      t_relay();
>>>                 }
>>>            exit;
>>>
>>>      }
>>>
>>> }
>>>
>>>
>>> on_reply[main] {
>>>    cache_store("local", "tran_dest_$ci", "$si", 500);
>>> }
>>>
>>> Dave
>>>
>>> On Sun, Feb 13, 2011 at 5:15 AM, Tyler Merritt <tyler at fonality.com>
> wrote:
>>>>
>>>> Why not use an $avp and grab the Call ID header on the inbound packet
> and
>>> then create some routing logic that checks the $avp against the return
>>> packet Call ID header to validate it's the same thing?  $avps can be
made
>>> available onreply with a modparam though forgive me if it's a bit late
at
>>> night and I don't have the link handy.
>>>> An avp can store more than a single value but they index in reverse
> order
>>> as written if I recall correctly.
>>>>
>>>> On Sat, Feb 12, 2011 at 5:05 AM, Russell Bierschbach
>>> <rbierschbach at telepointglobal.com> wrote:
>>>>>
>>>>> I have a similar problem, but not solution, my probably is actually
>>> occurring because the originating UA is ignoring a contact header that
is
>>> sent back during a 183 progress message.  OpenSIPS uses information from
>>> that contact header to figure out where to relay the incoming message
> (BYE
>>> in my case, CANCEL in yours).  It seems like it would be possible for
>>> OpenSIPS to use a call-id or tag to determine where to relay the message
>>> though.
>>>>>
>>>>>
>>>>>
>>>>> Russell Bierschbach
>>>>>
>>>>> em: rbierschbach at telepointglobal.com, im: rbierschbach at hotmail.com
>>>>>
>>>>>
>>>>>
>>>>> From: users-bounces at lists.opensips.org
>>> [mailto:users-bounces at lists.opensips.org] On Behalf Of Juri Nysschen
>>>>> Sent: Friday, February 11, 2011 7:44 AM
>>>>> To: users at lists.opensips.org
>>>>> Subject: [OpenSIPS-Users] FW: CANCELs with no transaction
>>>>>
>>>>>
>>>>>
>>>>> Hi All,
>>>>>
>>>>>
>>>>>
>>>>> Need help with a nagging issue:
>>>>>
>>>>>
>>>>>
>>>>> UA->Opensips 1->Opensips 2->PSTN
>>>>>
>>>>>
>>>>>
>>>>> UA sends an invite on Opensips 1, and is routed via do_routing() to
>>> Opensips 2, Opensips 2 uses do_routing to get to the PSTN, call starts
>>> ringing.
>>>>>
>>>>>
>>>>>
>>>>> UA cancels call before answer, but now t_check_trans fails and the
> CANCEL
>>> is not passed onto the PSTN, with the result that the call rings forever
> and
>>> can only be terminated by the remote answering and dropping the call or
>>> through a timeout.
>>>>>
>>>>>
>>>>>
>>>>> The scripts on Opensips 1 & Opensips 2 is virtuall identical:
>>>>>
>>>>>
>>>>>
>>>>> How do I get the CANCEL to the PSTN ?
>>>>>
>>>>>
>>>>>
>>>>> route{
>>>>>
>>>>> .....
>>>>>
>>>>>       if (is_method("CANCEL") ) {
>>>>>
>>>>>             route(5); # drop media proxy
>>>>>
>>>>>             if (t_check_trans()){ # this always fails after a
>>> do_routing()
>>>>>
>>>>>                   xlog("L_INFO","CANCEL
>>> Transaction[$fd/$fu/$rd/$ru/$si/]\n");
>>>>>
>>>>>                   t_relay();
>>>>>
>>>>>                   exit;
>>>>>
>>>>>             };
>>>>>
>>>>>             exit;
>>>>>
>>>>>       }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> route[4] {
>>>>>
>>>>>       xlog("L_INFO","Route4 [$fd/$fu/$rd/$ru/$si/]\n");
>>>>>
>>>>>
>>>>>
>>>>>       $avp(i:102)=1; # Default dr-group
>>>>>
>>>>>       route(10); # Do custom stuff
>>>>>
>>>>>       t_on_failure("4");
>>>>>
>>>>>       if (do_routing("$avp(i:102)")){
>>>>>
>>>>>             xlog("L_INFO","Route4 Route to Dyna Group:
>>> $avp(i:102)[$fd/$fu/$rd/$ru/$si/]\n");
>>>>>
>>>>>             t_newtran();
>>>>>
>>>>>             route(1);
>>>>>
>>>>>             exit;
>>>>>
>>>>>       };
>>>>>
>>>>>       xlog("L_INFO","Route4 No Route to
Host[$fd/$fu/$rd/$ru/$si/]\n");
>>>>>
>>>>>       sl_reply_error();
>>>>>
>>>>>       exit;
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> Regards
>>>>>
>>>>> Juri Nysschen
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Users mailing list
>>>>> Users at lists.opensips.org
>>>>> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Users mailing list
>>>> Users at lists.opensips.org
>>>> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
>>>>
>>>
>>> _______________________________________________
>>> Users mailing list
>>> Users at lists.opensips.org
>>> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
>>>
>>>
>>> _______________________________________________
>>> Users mailing list
>>> Users at lists.opensips.org
>>> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
>>>
>>
>
> _______________________________________________
> Users mailing list
> Users at lists.opensips.org
> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
>
>
> _______________________________________________
> Users mailing list
> Users at lists.opensips.org
> http://lists.opensips.org/cgi-bin/mailman/listinfo/users
>

_______________________________________________
Users mailing list
Users at lists.opensips.org
http://lists.opensips.org/cgi-bin/mailman/listinfo/users




More information about the Users mailing list