[sr-dev] git:master: sl: new function sl_forward_reply(...)
Daniel-Constantin Mierla
miconda at gmail.com
Fri Jan 4 20:47:43 CET 2013
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 <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at 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
More information about the sr-dev
mailing list