[SR-Users] Branch variables in branch_failure_route

Anthony Joseph Messina amessina at messinet.com
Wed Sep 14 21:00:14 CEST 2016


On Wednesday, September 14, 2016 3:11:08 PM CDT Paul Smith wrote:
> Hi,
> I am struggling to figure out variable scope in branches and
> branch_failure_routes.  Is there a way to store a variable in a branch
> route so that I can then read it from the branch failure route if that
> branch fails?  Also does writing $ru in branch_failure_route append a
> branch?
> 
> For example I have multiple SIP devices registered to Kamailio on the same
> account credentials.  The devices are behind same NAT, so same public IP. 
> Some devices have SRTP required and some cannot use SRTP at all, Kamailio
> does not know in advance of the call whether the call will use SRTP or RTP.
> 
> When I send a call to that user Kamailio correctly parallel forks to all the
> registered devices.  I use rtpengine offer to send SDP with RTP/SAVP in the
> initial invites.
> 
> If one of the devices sends a 488 due to not being able to handle the
> RTP/SAVP I then want to run rtpengine_offer with RTP/AVP and send another
> invite to the same  device.
> 
> In the branch failure route I seem to have to read the current $ru and then
> write it back into $ru before calling t_relay() or I get Sep 14 14:56:06
> registrar-secure /usr/sbin/kamailio[10168]: ERROR: tm [t_fwd.c:1771]:
> t_forward_nonack(): ERROR: t_forward_nonack: no branches for forwarding
> 
> This code seems to work, but it feels like I’m doing something very wrong….
> in particular $avp(triedrtpout) is set for the transaction, I should be
> setting it separately for each branch. event_route[tm:branch-failure:SRTP]
> { # Handle failure response
>         xlog("L_INFO", "Handling $T_reply_code response to $rm to ru: <$ru>
> and du: $du\n");
> 
>         if(t_check_status("488") && is_method("INVITE")) {
>                 if ($avp(triedsrtpout)==1) {
>                         # set $ru seems to create a new branch ... even when
> we set it to its current value. # we want to generate a new SIP INVITE to
> the same AOR but with different SDP $avp(buffer)=$ru;
>                         $ru=$avp(buffer);
>                         xlog("L_INFO","488 caught. Resending to $ru");
>                         # try with unencrypted RTP/AVP
>                         rtpengine_delete();
>                         rtpengine_offer("to-tag trust-address replace-origin
> replace-session-connection ICE=force RTP/AVP"); if (!t_relay()) {
>                                 sl_reply_error();
>                         }
> 
>                 }
>         }
> }
> 
> 
> I am using kamailio 4.2 debian package for this registrar.
> 
> Sorry for the rambling question … I don’t understand enough to write the
> short version!
> 
> Paul

Paul, I had worked a while back on the exact same thing.  Unfortunately for 
me, most of my clients are using Zoiper which doesn't seem to handle the re-
invite properly.  However, the following worked for me with other clients.

I was already using hash tables to store variables since I have the first 
rtpengine_offer in the branch_route.

I use t_reuse_branch() and setbflag(FLB_RTPENGINE_FAILURE), catching the 
branch flag when it loops around again in manage_branch so I don't offer again 
from there.

I'm not sure all of the below is necessary, but it worked.  I'll also be 
studying your method as it seems simpler ;)


#!ifdef WITH_RTPENGINE
# Handle branch failure cases
event_route[tm:branch-failure:rtpengine] {
        if(t_check_status("415|488")) {
                # Ok, this all works, except that Zoiper doesn't recognize the 
change in
                # Via header (branch) in the updated re-offer branch as an 
update, and
                # replies with 482 Merged Request -- which fails.
                t_reuse_branch();
                setbflag(FLB_RTPENGINE_FAILURE);
                if($sht(rtpengine=>$ci::$T_branch_idx::offer)=~"RTP/AVP") {
                        $sht(rtpengine=>$ci::$T_branch_idx::offer)="via-
branch=extra replace-origin replace-session-connection reset RTP/SAVP";
                } else if($sht(rtpengine=>$ci::$T_branch_idx::offer)=~"RTP/
SAVP") {
                        $sht(rtpengine=>$ci::$T_branch_idx::offer)="via-
branch=extra replace-origin replace-session-connection reset RTP/AVP";
                }

                xlog("L_INFO", "event_route[branch-failure:rtpengine]: NEW: 
$sht(rtpengine=>$ci::$T_branch_idx::offer)\n");
                rtpengine_offer($sht(rtpengine=>$ci::$T_branch_idx::offer));

                # Reset destination URI and sending socket
                $du=$sht(rtpengine=>$ci::$T_branch_idx::du);
                $fs=$null;

                route(RELAY);
                exit;
        }
}
#!endif


On a side note, a lot of this could be mitigated if I could get $xavp(ulattrs) 
to work after a call to alias_db_lookup() followed by 
lookup_branches("location") -- the branch indexes get out of sync with those 
in the $xavp :(

-- 
Anthony - https://messinet.com/ - https://messinet.com/~amessina/gallery
F9B6 560E 68EA 037D 8C3D  D1C9 FF31 3BDB D9D8 99B6
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20160914/6c71470e/attachment.sig>


More information about the sr-users mailing list