Module: sip-router Branch: master Commit: d01b11b0cbbbfb84ae3d10fb90c05aedf07c9ccc URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d01b11b0...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Fri Jan 4 19:26:21 2013 +0100
sl: new function sl_forward_reply(...)
- forward the received reply fron configuration, before it would be done by the core. It has the option to change the status code and reason phrase - the forwarding is statelessy, not affecting the tm states
---
modules/sl/README | 27 ++++++- modules/sl/doc/sl_functions.xml | 36 ++++++++++ modules/sl/sl.c | 147 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 205 insertions(+), 5 deletions(-)
diff --git a/modules/sl/README b/modules/sl/README index 9d5b29c..d15521a 100644 --- a/modules/sl/README +++ b/modules/sl/README @@ -19,6 +19,7 @@ Daniel-Constantin Mierla 4. sl_send_reply usage 5. send_reply usage 6. sl_reply_error usage + 7. send_reply usage
1. Overview
@@ -92,8 +93,9 @@ modparam("sl", "bind_tm", 0) # feature disabled 3.1. sl_send_reply(code, reason) 3.2. send_reply(code, reason) 3.3. sl_reply_error() + 3.4. sl_forward _reply([ code, [ reason ] ])
-3.1. sl_send_reply(code, reason) +3.1. sl_send_reply(code, reason)
For the current request, a reply is sent back having the given code and text reason. The reply is sent stateless, totally independent of the @@ -108,7 +110,7 @@ modparam("sl", "bind_tm", 0) # feature disabled sl_send_reply("404", "Not found"); ...
-3.2. send_reply(code, reason) +3.2. send_reply(code, reason)
For the current request, a reply is sent back having the given code and text reason. The reply is sent stateful or stateless, depending of the @@ -129,7 +131,7 @@ send_reply("404", "Not found"); send_reply("403", "Invalid user - $fU"); ...
-3.3. sl_reply_error() +3.3. sl_reply_error()
Sends back an error reply describing the nature of the last internal error. Usually this function should be used after a script function @@ -140,6 +142,25 @@ send_reply("403", "Invalid user - $fU"); sl_reply_error(); ...
+3.4. sl_forward _reply([ code, [ reason ] ]) + + Forward statelessy the current received SIP reply, with the option to + change the status code and reason text. The new code has to be in the + same class. The received reply is forwarded as well by core when the + config execution ended, unless it is dropped from config. + + Meaning of the parameters is as follows: + * code - Status code. + * reason - Reason phrase. + + This function can be used from ONREPLY_ROUTE. + + Example 7. send_reply usage +... +if(status=="408") + sl_forward_reply("404", "Not found"); +... + 4. Statistics
4.1. 1xx_replies diff --git a/modules/sl/doc/sl_functions.xml b/modules/sl/doc/sl_functions.xml index 63abcb6..bf58ce0 100644 --- a/modules/sl/doc/sl_functions.xml +++ b/modules/sl/doc/sl_functions.xml @@ -92,4 +92,40 @@ sl_reply_error(); </programlisting> </example> </section> + + <section id="sl_forward_reply"> + <title> + <function moreinfo="none">sl_forward _reply([ code, [ reason ] ])</function> + </title> + <para> + Forward statelessy the current received SIP reply, with the option to + change the status code and reason text. The new code has to be in the same + class. The received reply is forwarded as well by core when the config + execution ended, unless it is dropped from config. + </para> + <para>Meaning of the parameters is as follows:</para> + <itemizedlist> + <listitem> + <para><emphasis>code</emphasis> - Status code. + </para> + </listitem> + <listitem> + <para><emphasis>reason</emphasis> - Reason phrase. + </para> + </listitem> + </itemizedlist> + <para> + This function can be used from ONREPLY_ROUTE. + </para> + <example> + <title><function>send_reply</function> usage</title> + <programlisting format="linespecific"> +... +if(status=="408") + sl_forward_reply("404", "Not found"); +... +</programlisting> + </example> + </section> + </section> diff --git a/modules/sl/sl.c b/modules/sl/sl.c index eedb953..6d05569 100644 --- a/modules/sl/sl.c +++ b/modules/sl/sl.c @@ -62,6 +62,8 @@ #include "../../dprint.h" #include "../../error.h" #include "../../ut.h" +#include "../../data_lump.h" +#include "../../mod_fix.h" #include "../../script_cb.h" #include "../../mem/mem.h"
@@ -81,9 +83,12 @@ int _sl_filtered_ack_route = -1; /* default disabled */ static int sl_bind_tm = 1; static struct tm_binds tmb;
-static int w_sl_send_reply(struct sip_msg* msg, char* str, char* str2); +static int w_sl_send_reply(struct sip_msg* msg, char* str1, char* str2); static int w_send_reply(struct sip_msg* msg, char* str1, char* str2); -static int w_sl_reply_error(struct sip_msg* msg, char* str, char* str2); +static int w_sl_reply_error(struct sip_msg* msg, char* str1, char* str2); +static int w_sl_forward_reply0(sip_msg_t* msg, char* str1, char* str2); +static int w_sl_forward_reply1(sip_msg_t* msg, char* str1, char* str2); +static int w_sl_forward_reply2(sip_msg_t* msg, char* str1, char* str2); static int bind_sl(sl_api_t* api); static int mod_init(void); static int child_init(int rank); @@ -99,6 +104,12 @@ static cmd_export_t cmds[]={ REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE}, {"sl_reply_error", w_sl_reply_error, 0, 0, REQUEST_ROUTE}, + {"sl_forward_reply", w_sl_forward_reply0, 0, 0, + ONREPLY_ROUTE}, + {"sl_forward_reply", w_sl_forward_reply1, 1, fixup_spve_all, + ONREPLY_ROUTE}, + {"sl_forward_reply", w_sl_forward_reply2, 2, fixup_spve_all, + ONREPLY_ROUTE}, {"bind_sl", (cmd_function)bind_sl, 0, 0, 0}, {0,0,0,0,0} }; @@ -347,6 +358,138 @@ static int fixup_sl_reply(void** param, int param_no) return 0; }
+/** + * @brief forward SIP reply statelessy with different code and reason text + */ +static int w_sl_forward_reply(sip_msg_t* msg, str* code, str* reason) +{ + char oldscode[3]; + int oldncode; + int ret; + struct lump *ldel = NULL; + struct lump *ladd = NULL; + char *rbuf; + + if(msg->first_line.type!=SIP_REPLY) { + LM_ERR("invalid SIP message type\n"); + return -1; + } + if(code!=NULL) { + if(code->len!=3) { + LM_ERR("invalid reply code value %.*s\n", code->len, code->s); + return -1; + } + if(msg->first_line.u.reply.status.s[0]!=code->s[0]) { + LM_ERR("reply code class cannot be changed\n"); + return -1; + } + if(code->s[1]<'0' || code->s[1]>'9' + || code->s[2]<'0' || code->s[2]>'9') { + LM_ERR("invalid reply code value %.*s!\n", code->len, code->s); + return -1; + } + } + if(reason!=NULL && reason->len<=0) { + LM_ERR("invalid reply reason value\n"); + return -1; + } + if(code!=NULL) { + /* backup old values */ + oldscode[0] = msg->first_line.u.reply.status.s[0]; + oldscode[1] = msg->first_line.u.reply.status.s[1]; + oldscode[2] = msg->first_line.u.reply.status.s[2]; + oldncode = msg->first_line.u.reply.statuscode; + /* update status code directly in msg buffer */ + msg->first_line.u.reply.statuscode = (code->s[0]-'0')*100 + + (code->s[1]-'0')*10 + code->s[2]-'0'; + msg->first_line.u.reply.status.s[0] = code->s[0]; + msg->first_line.u.reply.status.s[1] = code->s[1]; + msg->first_line.u.reply.status.s[2] = code->s[2]; + + } + if(reason!=NULL) { + ldel = del_lump(msg, + msg->first_line.u.reply.reason.s - msg->buf, + msg->first_line.u.reply.reason.len, + 0); + if (ldel==NULL) { + LM_ERR("failed to add del lump\n"); + ret = -1; + goto restore; + } + rbuf = (char *)pkg_malloc(reason->len); + if (rbuf==NULL) { + LM_ERR("not enough memory\n"); + ret = -1; + goto restore; + } + memcpy(rbuf, reason->s, reason->len); + ladd = insert_new_lump_after(ldel, rbuf, reason->len, 0); + if (ladd==0) { + LOG(L_ERR, "failed to add reason lump: %.*s\n", + reason->len, reason->s); + pkg_free(rbuf); + ret = -1; + goto restore; + } + } + ret = forward_reply(msg); +restore: + if(reason!=NULL) { + if(ldel!=NULL) { + remove_lump(msg, ldel); + } + if(ladd!=NULL) { + remove_lump(msg, ladd); + } + } + if(code!=NULL) { + msg->first_line.u.reply.statuscode = oldncode; + msg->first_line.u.reply.status.s[0] = oldscode[0]; + msg->first_line.u.reply.status.s[1] = oldscode[1]; + msg->first_line.u.reply.status.s[2] = oldscode[2]; + } + return ret; +} + +/** + * @brief forward SIP reply statelessy + */ +static int w_sl_forward_reply0(sip_msg_t* msg, char* str1, char* str2) +{ + return w_sl_forward_reply(msg, NULL, NULL); +} + +/** + * @brief forward SIP reply statelessy with a new code + */ +static int w_sl_forward_reply1(sip_msg_t* msg, char* str1, char* str2) +{ + str code; + if(fixup_get_svalue(msg, (gparam_t*)str1, &code)<0) { + LM_ERR("cannot get the reply code parameter value\n"); + return -1; + } + return w_sl_forward_reply(msg, &code, NULL); +} + +/** + * @brief forward SIP reply statelessy with new code and reason text + */ +static int w_sl_forward_reply2(sip_msg_t* msg, char* str1, char* str2) +{ + str code; + str reason; + if(fixup_get_svalue(msg, (gparam_t*)str1, &code)<0) { + LM_ERR("cannot get the reply code parameter value\n"); + return -1; + } + if(fixup_get_svalue(msg, (gparam_t*)str2, &reason)<0) { + LM_ERR("cannot get the reply reason parameter value\n"); + return -1; + } + return w_sl_forward_reply(msg, &code, &reason); +}
/** * @brief bind functions to SL API structure