[SR-Users] rtpengine_manage() in async tasks

Alex Balashov abalashov at evaristesys.com
Tue Jan 15 02:36:13 CET 2019


Hi,

I've run into an issue with handling reinvites in async task
workers--which I need to do in order to introduce a small delay to avoid
a UA race condition--in which some state that is necessary for
rtpengine_manage() to do the right thing seems to be lost.

Specifically, if I do this:

--
loadmodule "mqueue"
loadmodule "rtimer"

...

modparam("rtimer", "timer", "name=reinvite_q1;interval=10000u;mode=1;")
modparam("rtimer", "exec", "timer=reinvite_q1;route=REINVITE_DEQUEUE")

modparam("mqueue", "mqueue", "name=reinvite_q");

...

route {
   ...

   if(has_totag()) {
      if(loose_route()) {
         ...

	 if(is_method("INVITE")) {
	    if(!t_suspend()) {
	       sl_send_reply("500", "Server Internal Error");
               exit;
            }

            mq_add("reinvite_q", "$T(id_index):$T(id_label)", "");
         } else 
	    route(IN_DLG_REQ);
	
      exit;
   }

   ...
}

route[REINVITE_DEQUEUE] {
   while(mq_fetch("reinvite_q")) {
      $var(id) = $(mqk(reinvite_q){s.select,0,:}{s.int});
      $var(label) = $(mqk(reinvite_q){s.select,1,:}{s.int});

      t_continue("$var(id)", "$var(label)", "IN_DLG_REQ");
   }
}

route[IN_DLG_REQ] {
   handle_ruri_alias();

   if(is_method("BYE"))
      rtpengine_manage();
   else if(is_method("INVITE") && sdp_content()) 
      rtpengine_manage("replace-origin replace-session-connection ICE=remove")

   t_on_reply("MAIN_REPLY");

   if(!t_relay())
      sl_reply_error();
}

onreply_route[MAIN_REPLY] {
   if(is_method("INVITE") && sdp_content()) 
      rtpengine_manage("replace-origin replace-session-connection ICE=remove");
}
--

What I find is that if I generate a reinvite from either side,
rtpengine_manage() passes through the SDP offer in the reinvite
unadulterated, although the answer returns properly adulterated by
RTPEngine.

The same thing occurs if I use 'async', which as I gather is just a
wrapper of convenience around t_suspend/t_continue() anyway. That module
won't do for my purposes because I need a millisecond-level delay
resolution rather than second-level, anyhow.

Anyway, surely enough, this is because the execution context is one that
insinuates a stream deletion. When the reinvite offer comes across and I
call rtpengine_manage(), the command sent is 'delete':

--
Jan 14 20:24:23 staccato.evaristesys.com rtpengine[33830]: INFO: [c94347dcf92e7ccc10dee84c4e0d1c8a]: Received command 'delete' from 209.51.167.66:39788
--

The RTPEngine module documentation actually warns about this:

https://kamailio.org/docs/modules/5.2.x/modules/rtpengine.html#rtpengine.f.rtpengine_manage

But this insight is buried in the fourth bullet point:

   "If BYE or CANCEL, or called within a FAILURE_ROUTE[], then call 
    rtpengine_delete(). Be careful with calling this function after 
    resuming a suspended transaction (e.g., after t_continue()), 
    because the context of executed route is FAILURE ROUTE (in other 
    words, rtpengine_manage() in the route block of t_continue() 
    does the same as in failure_route)."

This would lead one to believe that it applies only in the context of
handling a BYE or CANCEL in a resumed transaction, when in fact it seems
to hold true of non-BYE/CANCEL and non-failure contexts as well, as can
be clearly seen with the reinvite. 

The behaviour is exactly as expected if I don't use rtpengine_manage()
and instead manually call rtpengine_offer()/rtpengine_answer(). And
expected behaviour comes from rtpengine_manage() if I don't handle the
request in a resumed transaction context. 

This yields the fundamental question:

Is there any way to have my cake and eat it too? I really want to use
rtpengine_manage() because I need to handle a potential SDP offer-in-ACK
scenario and don't want to do a bunch of state-keeping in order to use
the correct choice of rtpengine_{offer|answer}() in the right context,
which is a problem rtpengine_manage() solves beautifully. At the same
time, I absolutely need the slight reinvite delay that can be
accomplished via async processing; a UA on this side has a nasty habit
of sending a reinvite almost simultaneously to the 2xx answer for the
INVITE transaction, leading to indeterminate egress velocity for those
respective messages out of Kamailio worker threads.

Many thanks in advance!

-- Alex

-- 
Alex Balashov | Principal | Evariste Systems LLC

Tel: +1-706-510-6800 / +1-800-250-5920 (toll-free) 
Web: http://www.evaristesys.com/, http://www.csrpswitch.com/



More information about the sr-users mailing list