Module: sip-router
Branch: master
Commit: d01b11b0cbbbfb84ae3d10fb90c05aedf07c9ccc
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d01b11b0cbbbfb84ae3d10fb90c05aedf07c9ccc

Author: Daniel-Constantin Mierla <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
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


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to