Hi,
I ran into a scenario with couple of serial forks where kamailio loops to itself and, due to the looping, the INVITE to a new branch happens before the CANCEL to an old branch. What I do at the moment is force rtpproxy in branch route, and stop rtpproxy in the failure route.
The problem with this scenario is that in rtpproxy_offer and unforce_rtpproxy, the rtpproxy module only passes the call-id and from-tag to rtpproxy (because there is no to-tag yet), which then in unforce_rtpproxy for a CANCEL deletes all calls related to it (because it can only match on from-tag and call-id, obviously). This means that when I do a subsequent rtpproxy_answer for my new branch, rtpproxy doesn't find the session anymore, since it has been removed with the CANCEL.
A fix I can think of is to also pass the branch of the top-most via to rtpproxy in order to perform a more fine-grained matching. Are there solutions to that out there somewhere, or is it something I should just introduce, eg. as a new param to offer/answer/unforce functions? Objections? Other approaches?
Andreas
Hello,
On 2/9/12 5:13 PM, Andreas Granig wrote:
Hi,
I ran into a scenario with couple of serial forks where kamailio loops to itself and, due to the looping, the INVITE to a new branch happens before the CANCEL to an old branch. What I do at the moment is force rtpproxy in branch route, and stop rtpproxy in the failure route.
The problem with this scenario is that in rtpproxy_offer and unforce_rtpproxy, the rtpproxy module only passes the call-id and from-tag to rtpproxy (because there is no to-tag yet), which then in unforce_rtpproxy for a CANCEL deletes all calls related to it (because it can only match on from-tag and call-id, obviously). This means that when I do a subsequent rtpproxy_answer for my new branch, rtpproxy doesn't find the session anymore, since it has been removed with the CANCEL.
A fix I can think of is to also pass the branch of the top-most via to rtpproxy in order to perform a more fine-grained matching. Are there solutions to that out there somewhere, or is it something I should just introduce, eg. as a new param to offer/answer/unforce functions? Objections? Other approaches?
if you do rtpproxy handling on an instance that received a parallel forked call, then it is better to add the condition on top via branch, I don't see other solution for now and I am not aware of an implementation for it. I would add a new flag to rtpproxy parameters to send the branch value, that will allow to use old rptproxy versions when the flag is not given.
Cheers, Daniel
Hello,
On Friday 10 of February 2012 14:02:08 Daniel-Constantin Mierla wrote:
Hello,
On 2/9/12 5:13 PM, Andreas Granig wrote:
Hi,
I ran into a scenario with couple of serial forks where kamailio loops to itself and, due to the looping, the INVITE to a new branch happens before the CANCEL to an old branch. What I do at the moment is force rtpproxy in branch route, and stop rtpproxy in the failure route.
The problem with this scenario is that in rtpproxy_offer and unforce_rtpproxy, the rtpproxy module only passes the call-id and from-tag to rtpproxy (because there is no to-tag yet), which then in unforce_rtpproxy for a CANCEL deletes all calls related to it (because it can only match on from-tag and call-id, obviously). This means that when I do a subsequent rtpproxy_answer for my new branch, rtpproxy doesn't find the session anymore, since it has been removed with the CANCEL.
A fix I can think of is to also pass the branch of the top-most via to rtpproxy in order to perform a more fine-grained matching. Are there solutions to that out there somewhere, or is it something I should just introduce, eg. as a new param to offer/answer/unforce functions? Objections? Other approaches?
if you do rtpproxy handling on an instance that received a parallel forked call, then it is better to add the condition on top via branch, I don't see other solution for now and I am not aware of an implementation for it. I would add a new flag to rtpproxy parameters to send the branch value, that will allow to use old rptproxy versions when the flag is not given.
I've experienced similar problem with no-answer forwarding. In my scenario call was torn down from rtpproxy in onreply_route when "487 Request terminated" was received from B phone (upon CANCEL). I am using Kamailio 3.2 default configuration with rtpproxy_manage() and workaround is to check if transaction is canceled for negative replies in onreply_route and only then call rtpproxy_manage().
Can anybody think of scenario when this workaround will not clean up RTP proxy session?
I checked rtpproxy_manage function and patch should be really simple:
--- a/modules/rtpproxy/rtpproxy.c +++ b/modules/rtpproxy/rtpproxy.c @@ -1736,8 +1736,12 @@ rtpproxy_manage(struct sip_msg *msg, char *flags, char *ip) (ip!=NULL)?1:0); } } else if(msg->first_line.type == SIP_REPLY) { - if(msg->first_line.u.reply.statuscode>=300) + if(msg->first_line.u.reply.statuscode>=300) { + if(tmb.t_gett!=NULL && tmb.t_gett()!=NULL + && !(tmb.t_gett()->flags & T_CANCELED)) + return -1; return unforce_rtp_proxy_f(msg, 0, 0); + } if(nosdp==0) { if(tmb.t_gett==NULL || tmb.t_gett()==NULL || tmb.t_gett()==T_UNDEFINED)
Cheers, Jan