[sr-dev] How to change the reply msg in the onreply_route

Andrei Pelinescu-Onciul andrei at iptel.org
Mon Feb 22 11:20:54 CET 2010


On Feb 19, 2010 at 18:24, Min Wang <wang at basis-audionet.com> wrote:
> 
> Hi Andrei:
> 
> Thanks for the quick response.
> 
> > >
> > > The pseudo codes is like:
> > >
> > > t=tmb.t_gett();
> > > send_request(method_ACK);
> > > send_request(method_BYE);
> > > reason_code = 488
> > > tmb.t_reply(t->uas.request,reason_code,reason_text);
> > > (Not sure if t_reply can be called here or not.)
> > 
> > >
> > > The ACK/Bye is sent to U2, 488 is sent to U1,
> > >
> > > But the issue is it seems the original 200 OK is forwarded to U1 as
> > > well.
> > >
> > > How to avoid it?
> > 
> > You need either to DROP the reply (add drop in the script after your
> > function), or use the generic onreply_route ( [0] or unnamed).
> 
> So:
> onreply_route[1]
> {
>       if (my_function_check("")) {
>              release_call_onreply("");
> 			Drop;
>       }
> 
> }
> 
> > 
> > Anyway you would need to modify t_reply, or it won't work from the
> > onreply_route (at least not in sr 3.*).
> 
> I guess what you mean is : even with drop, this function seems need to
> be modified ( since the reply is 200 OK.)

Yes, you're right.
> 
> In the tm/t_reply.c->reply_received:
>                 run_top_route(onreply_rt.rlist[t->on_reply], p_msg,
> &ctx);
>                 if ((ctx.run_flags&DROP_R_F)  && (msg_status<200)) {
>                         if (unlikely(replies_locked)) {
>                                 replies_locked = 0;
>                                 UNLOCK_REPLIES( t );
>                         }
>                         goto done;
>                 }
> 

Sorry, I forgot about this.

> 
> What is the good reason for checking msg_status<200 there?

A final reply cannot be dropped. The timers are already stopped and if
this is the only active branch, dropping the reply might leave it
forever in memory (the code expects that either relay_reply() or
local_reply() is always called for a final reply).
Dropping 200 would also not make much sense for a sip proxy.

You could try changing reply_received:
- replace stop_rb_timer(&uac->request) in  if (msg_status >= 200) with
  stop_rb_retr(&uac->request)
- add if (msg_status>=200) stop_rb_timer(&uac_request) after the
  execution of the reply route (if (t->on_reply) {...} <here> ).

Note however that you might run into other problems and you would need a
lot of testing.

An easier way is to use the on_reply[0] route. This is executed by the
core prior to tm's reply_received and tm on_reply routes. If you drop a
reply from here, tm won't see it at all. You still need to modify
w_t_reply_wrp (w_t_reply()) which right now can be executed only from
request or on failure routes. If you are going to execute it from the main
onreply_route (onreply_route[0]{} or onreply_route{}), you would need to
call t_reply() like for a request route and not t_reply_unsafe().
This is different from the case where you would want to execute
t_reply/w_t_reply() from the onreply_route[ != 0] (in this case you
would need t_reply_unsafe(), since the transaction is already locked).

The script will look like:

onreply_route {
      if (my_function_check("")) {
              release_call_onreply("");
              Drop;
       }
}

and release_call_onreply(""):

 if (tmb.t_check(msg, &branch)>0){
    send_request(method_ACK);
    send_request(method_BYE);
    reason_code = 488
    tmb.t_reply(t->uas.request,reason_code,reason_text); # where
    # tmb.t_reply is the modified version that calls t_reply()
    # internally
 }


Andrei



More information about the sr-dev mailing list