Hi
I have following scenario:
u1---> p1 --> u2
u1 calling u2, u2 reply with 200 OK,
The p1 need to check something, and decide to send ACK/Bye to u2, and 488 to u1:
onreply_route[1] { if (my_function_check("")) { release_call_onreply(""); }
}
The question is : How to do implement release_call_onreply correctly?
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?
Or should the Data lumps function be used here to modify the 200 reply msg instead of using t_reply here?
Kind Regards
Min Wang
On Feb 19, 2010 at 17:33, Min Wang wang@basis-audionet.com wrote:
Hi
I have following scenario:
u1---> p1 --> u2
u1 calling u2, u2 reply with 200 OK,
The p1 need to check something, and decide to send ACK/Bye to u2, and 488 to u1:
onreply_route[1] { if (my_function_check("")) { release_call_onreply(""); }
}
The question is : How to do implement release_call_onreply correctly?
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).
Anyway you would need to modify t_reply, or it won't work from the onreply_route (at least not in sr 3.*).
Or should the Data lumps function be used here to modify the 200 reply msg instead of using t_reply here?
No, you won't be able to change the reply code that way.
Andrei
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.)
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; }
What is the good reason for checking msg_status<200 there?
Kind regards
Min Wang
Or should the Data lumps function be used here to modify the 200
reply
msg instead of using t_reply here?
No, you won't be able to change the reply code that way.
Andrei
On Feb 19, 2010 at 18:24, Min Wang wang@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
Hi Andrei
Thanks so much for the detailed information!
I will try the easy way as you suggested. :)
Kind Regards
Min Wang
-----Original Message----- From: Andrei Pelinescu-Onciul [mailto:andrei@iptel.org] Sent: Monday, February 22, 2010 5:21 AM To: Min Wang Cc: sr-dev@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@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
On Feb 22, 2010 at 16:36, Min Wang wang@basis-audionet.com wrote:
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@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@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
Hi Andrei:
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.
Thanks again! I will try it.
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).
It would be great to be able to drop 2xx in the tm onreply!
I can try to do the test.
What kind of test cases are needed?
I am not sure how much time is needed for these tests, is it better to put this change on a test branch? (ps: I do not want to block the master branch because of my test schedule. :) )
Kind Regards
Min Wang
Andrei
Hi Andrei:
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; } }
I did some tests on both main and tm onreply_route for 180 msg from scripts, it works!!
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).
Is the changes to drop 2xx in git repo?
My prefered way is to be able to drop 2xx in tm onreply_routes, otherwise my_function_check in the main onreply_route seems will get complicated. (am I a little lazy :)? )
Thanks.
Kind Regards
Min Wang
On Feb 24, 2010 at 21:20, Min Wang wang@basis-audionet.com wrote:
Hi Andrei:
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; } }
I did some tests on both main and tm onreply_route for 180 msg from scripts, it works!!
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).
Is the changes to drop 2xx in git repo?
It is know. You have to define TM_ONREPLY_FINAL_DROP_OK or else it won't be compiled. E.g.: make cfg extra_defs=-DTM_ONREPLY_FINAL_DROP_OK; make all or re-compiling only tm: make -C modules/tm extra_defs=-DTM_ONREPLY_FINAL_DROP_OK.
You'll get a compile time warning when active.
My prefered way is to be able to drop 2xx in tm onreply_routes, otherwise my_function_check in the main onreply_route seems will get complicated. (am I a little lazy :)? )
Andrei
Hi Andrei
that's great. thanks a lot.
I'll try it on Monday.
Have a nice weekend!
Kind Regards
Min Wang
Is the changes to drop 2xx in git repo?
It is know. You have to define TM_ONREPLY_FINAL_DROP_OK or else it won't be compiled. E.g.: make cfg extra_defs=-DTM_ONREPLY_FINAL_DROP_OK; make all or re-compiling only tm: make -C modules/tm extra_defs=-DTM_ONREPLY_FINAL_DROP_OK.
You'll get a compile time warning when active.
Hi Andrei
Is the changes to drop 2xx in git repo?
It is know. You have to define TM_ONREPLY_FINAL_DROP_OK or else it won't be compiled. E.g.: make cfg extra_defs=-DTM_ONREPLY_FINAL_DROP_OK; make all or re-compiling only tm: make -C modules/tm extra_defs=-DTM_ONREPLY_FINAL_DROP_OK.
You'll get a compile time warning when active.
I did some tests on this, it works ( at least from the sniffed packets)!!! Thanks a lot.
Does the modparam make sense ( instead of using extra_defs to compile ) ? modparam("tm", "TM_ONREPLY_FINAL_DROP_OK", 0) ( default is off)
Is there any other special test/log need to check?
In my scenario the ACK seems not being replayed, but I guess it may due to the ACK/BYE msg not being constructed correctly. To separate the issue, I will post a new thread.
Kind Regards
Min Wang
Andrei