Hi Andrei
Thanks so much for the detailed information!
I will try the easy way as you suggested. :)
Try the latest code on master. It was more complex than I thought, but
now it should be possible to use t_reply() from both kinds of
onreply_routes, even from the script.
E.g.:
onreply_route{ # main/core onreply_route
if (some condition) {
t_reply("600", "Denied");
drop;
}
}
In this case you would still need your function to send the ack & bye.
It will work too in the tm onreply_routes, but not for 2xx replies.
If someone really needs to drop 2xx replies from tm onreply routes and
volunteers to do the heavy testing, we could try allowing it (along with
the stop timer changes it should work theoretically).
Andrei
-----Original Message-----
From: Andrei Pelinescu-Onciul [mailto:andrei@iptel.org]
Sent: Monday, February 22, 2010 5:21 AM
To: Min Wang
Cc: sr-dev(a)lists.sip-router.org
Subject: Re: [sr-dev] How to change the reply msg in the onreply_route
On Feb 19, 2010 at 18:24, Min Wang <wang(a)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