|
@@ -68,20 +68,22 @@
|
|
|
|
|
|
#include "ms_msg_list.h"
|
|
|
#include "msfuncs.h"
|
|
|
+#include "api.h"
|
|
|
|
|
|
#define MAX_DEL_KEYS 1
|
|
|
-#define NR_KEYS 10
|
|
|
-
|
|
|
-static str sc_mid = str_init("id"); /* 0 */
|
|
|
-static str sc_from = str_init("src_addr"); /* 1 */
|
|
|
-static str sc_to = str_init("dst_addr"); /* 2 */
|
|
|
-static str sc_uri_user = str_init("username"); /* 3 */
|
|
|
-static str sc_uri_host = str_init("domain"); /* 4 */
|
|
|
-static str sc_body = str_init("body"); /* 5 */
|
|
|
-static str sc_ctype = str_init("ctype"); /* 6 */
|
|
|
-static str sc_exp_time = str_init("exp_time"); /* 7 */
|
|
|
-static str sc_inc_time = str_init("inc_time"); /* 8 */
|
|
|
-static str sc_snd_time = str_init("snd_time"); /* 9 */
|
|
|
+#define NR_KEYS 11
|
|
|
+
|
|
|
+static str sc_mid = str_init("id"); /* 0 */
|
|
|
+static str sc_from = str_init("src_addr"); /* 1 */
|
|
|
+static str sc_to = str_init("dst_addr"); /* 2 */
|
|
|
+static str sc_uri_user = str_init("username"); /* 3 */
|
|
|
+static str sc_uri_host = str_init("domain"); /* 4 */
|
|
|
+static str sc_body = str_init("body"); /* 5 */
|
|
|
+static str sc_ctype = str_init("ctype"); /* 6 */
|
|
|
+static str sc_exp_time = str_init("exp_time"); /* 7 */
|
|
|
+static str sc_inc_time = str_init("inc_time"); /* 8 */
|
|
|
+static str sc_snd_time = str_init("snd_time"); /* 9 */
|
|
|
+static str sc_extra_hdrs = str_init("extra_hdrs"); /* 10 */
|
|
|
|
|
|
#define SET_STR_VAL(_str, _res, _r, _c) \
|
|
|
if (RES_ROWS(_res)[_r].values[_c].nul == 0) \
|
|
@@ -108,7 +110,7 @@ static str sc_snd_time = str_init("snd_time"); /* 9 */
|
|
|
|
|
|
MODULE_VERSION
|
|
|
|
|
|
-#define S_TABLE_VERSION 5
|
|
|
+#define S_TABLE_VERSION 6
|
|
|
|
|
|
/** database connection */
|
|
|
static db1_con_t *db_con = NULL;
|
|
@@ -157,11 +159,16 @@ str msg_type = str_init("MESSAGE");
|
|
|
static int mod_init(void);
|
|
|
static int child_init(int);
|
|
|
|
|
|
-static int m_store(struct sip_msg*, char*, char*);
|
|
|
-static int m_dump(struct sip_msg*, char*, char*);
|
|
|
+static int m_store(struct sip_msg*, str*);
|
|
|
+static int m_dump(struct sip_msg*, str*);
|
|
|
+
|
|
|
+static int m_store_2(struct sip_msg*, char*, char*);
|
|
|
+static int m_dump_2(struct sip_msg*, char*, char*);
|
|
|
|
|
|
static void destroy(void);
|
|
|
|
|
|
+static int bind_msilo(msilo_api_t* api);
|
|
|
+
|
|
|
void m_clean_silo(unsigned int ticks, void *);
|
|
|
void m_send_ontimer(unsigned int ticks, void *);
|
|
|
|
|
@@ -169,16 +176,18 @@ int ms_reset_stime(int mid);
|
|
|
|
|
|
int check_message_support(struct sip_msg* msg);
|
|
|
|
|
|
+
|
|
|
/** TM callback function */
|
|
|
static void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps);
|
|
|
|
|
|
static cmd_export_t cmds[]={
|
|
|
- {"m_store", (cmd_function)m_store, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE},
|
|
|
- {"m_store", (cmd_function)m_store, 1, fixup_spve_null, 0,
|
|
|
+ {"m_store", (cmd_function)m_store_2, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE},
|
|
|
+ {"m_store", (cmd_function)m_store_2, 1, fixup_spve_null, 0,
|
|
|
REQUEST_ROUTE | FAILURE_ROUTE},
|
|
|
- {"m_dump", (cmd_function)m_dump, 0, 0, 0, REQUEST_ROUTE},
|
|
|
- {"m_dump", (cmd_function)m_dump, 1, fixup_spve_null, 0,
|
|
|
+ {"m_dump", (cmd_function)m_dump_2, 0, 0, 0, REQUEST_ROUTE},
|
|
|
+ {"m_dump", (cmd_function)m_dump_2, 1, fixup_spve_null, 0,
|
|
|
REQUEST_ROUTE},
|
|
|
+ {"bind_msilo",(cmd_function)bind_msilo, 1, 0, 0, ANY_ROUTE},
|
|
|
{0,0,0,0,0,0}
|
|
|
};
|
|
|
|
|
@@ -208,6 +217,7 @@ static param_export_t params[]={
|
|
|
{ "sc_exp_time", STR_PARAM, &sc_exp_time.s },
|
|
|
{ "sc_inc_time", STR_PARAM, &sc_inc_time.s },
|
|
|
{ "sc_snd_time", STR_PARAM, &sc_snd_time.s },
|
|
|
+ { "sc_extra_hdrs", STR_PARAM, &sc_extra_hdrs.s },
|
|
|
{ "snd_time_avp", STR_PARAM, &ms_snd_time_avp_param.s },
|
|
|
{ "add_date", INT_PARAM, &ms_add_date },
|
|
|
{ "max_messages", INT_PARAM, &ms_max_messages },
|
|
@@ -254,6 +264,16 @@ struct module_exports exports= {
|
|
|
child_init /* per-child init function */
|
|
|
};
|
|
|
|
|
|
+static int bind_msilo(msilo_api_t* api)
|
|
|
+{
|
|
|
+ if (!api) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ api->m_store = m_store;
|
|
|
+ api->m_dump = m_dump;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* init module function
|
|
|
*/
|
|
@@ -470,6 +490,42 @@ static int child_init(int rank)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * get_non_mandatory_headers
|
|
|
+ * Extracts additional headers into the given buffer for storing alongside the message
|
|
|
+ * returns the length of the created data
|
|
|
+ *
|
|
|
+ * It is assumed that all headers have been parsed at this point
|
|
|
+ */
|
|
|
+static int get_non_mandatory_headers(struct sip_msg *msg, char *buf, int buf_len)
|
|
|
+{
|
|
|
+ struct hdr_field *hdrs;
|
|
|
+ int len = 0;
|
|
|
+
|
|
|
+ for (hdrs = msg->headers; hdrs != NULL; hdrs = hdrs->next)
|
|
|
+ {
|
|
|
+ switch (hdrs->type) {
|
|
|
+ case HDR_OTHER_T:
|
|
|
+ case HDR_PPI_T:
|
|
|
+ case HDR_PAI_T:
|
|
|
+ case HDR_PRIVACY_T:
|
|
|
+ if (buf_len <= hdrs->len)
|
|
|
+ {
|
|
|
+ LM_ERR("Insufficient space to store headers in silo\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ memcpy(buf, hdrs->name.s, hdrs->len);
|
|
|
+ len += hdrs->len;
|
|
|
+ buf += hdrs->len;
|
|
|
+ buf_len -= hdrs->len;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return len;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* store message
|
|
|
* mode = "0" -- look for outgoing URI starting with new_uri
|
|
@@ -477,12 +533,15 @@ static int child_init(int rank)
|
|
|
* = "2" -- look for outgoing URI only at to header
|
|
|
*/
|
|
|
|
|
|
-static int m_store(struct sip_msg* msg, char* owner, char* s2)
|
|
|
+static int m_store(struct sip_msg* msg, str *owner_s)
|
|
|
{
|
|
|
str body, str_hdr, ctaddr;
|
|
|
struct to_body *pto, *pfrom;
|
|
|
struct sip_uri puri;
|
|
|
- str duri, owner_s;
|
|
|
+ str duri;
|
|
|
+#define EXTRA_HDRS_BUF_LEN 1024
|
|
|
+ static char extra_hdrs_buf[EXTRA_HDRS_BUF_LEN];
|
|
|
+ str extra_hdrs;
|
|
|
db_key_t db_keys[NR_KEYS-1];
|
|
|
db_val_t db_vals[NR_KEYS-1];
|
|
|
db_key_t db_cols[1];
|
|
@@ -538,19 +597,14 @@ static int m_store(struct sip_msg* msg, char* owner, char* s2)
|
|
|
|
|
|
/* get the owner */
|
|
|
memset(&puri, 0, sizeof(struct sip_uri));
|
|
|
- if(owner)
|
|
|
+ if(owner_s != NULL)
|
|
|
{
|
|
|
- if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
|
|
|
- {
|
|
|
- LM_ERR("invalid owner uri parameter");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- if(parse_uri(owner_s.s, owner_s.len, &puri)!=0)
|
|
|
+ if(parse_uri(owner_s->s, owner_s->len, &puri)!=0)
|
|
|
{
|
|
|
LM_ERR("bad owner SIP address!\n");
|
|
|
goto error;
|
|
|
} else {
|
|
|
- LM_DBG("using user id [%.*s]\n", owner_s.len, owner_s.s);
|
|
|
+ LM_DBG("using user id [%.*s]\n", owner_s->len, owner_s->s);
|
|
|
}
|
|
|
} else { /* get it from R-URI */
|
|
|
if(msg->new_uri.len <= 0)
|
|
@@ -646,16 +700,16 @@ static int m_store(struct sip_msg* msg, char* owner, char* s2)
|
|
|
nr_keys++;
|
|
|
|
|
|
/* add the message's body in SQL query */
|
|
|
-
|
|
|
+
|
|
|
db_keys[nr_keys] = &sc_body;
|
|
|
-
|
|
|
+
|
|
|
db_vals[nr_keys].type = DB1_BLOB;
|
|
|
db_vals[nr_keys].nul = 0;
|
|
|
db_vals[nr_keys].val.blob_val.s = body.s;
|
|
|
db_vals[nr_keys].val.blob_val.len = body.len;
|
|
|
|
|
|
nr_keys++;
|
|
|
-
|
|
|
+
|
|
|
lexpire = ms_expire_time;
|
|
|
/* add 'content-type' -- parse the content-type header */
|
|
|
if ((mime=parse_content_type_hdr(msg))<1 )
|
|
@@ -695,7 +749,7 @@ static int m_store(struct sip_msg* msg, char* owner, char* s2)
|
|
|
|
|
|
/* current time */
|
|
|
val = (int)time(NULL);
|
|
|
-
|
|
|
+
|
|
|
/* add expiration time */
|
|
|
db_keys[nr_keys] = &sc_exp_time;
|
|
|
db_vals[nr_keys].type = DB1_INT;
|
|
@@ -728,6 +782,23 @@ static int m_store(struct sip_msg* msg, char* owner, char* s2)
|
|
|
}
|
|
|
nr_keys++;
|
|
|
|
|
|
+ /* add the extra headers in SQL query */
|
|
|
+ extra_hdrs.s = extra_hdrs_buf;
|
|
|
+ extra_hdrs.len = get_non_mandatory_headers(msg, extra_hdrs_buf, EXTRA_HDRS_BUF_LEN);
|
|
|
+ if (extra_hdrs.len < 0)
|
|
|
+ {
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ db_keys[nr_keys] = &sc_extra_hdrs;
|
|
|
+
|
|
|
+ db_vals[nr_keys].type = DB1_BLOB;
|
|
|
+ db_vals[nr_keys].nul = 0;
|
|
|
+ db_vals[nr_keys].val.blob_val.s = extra_hdrs.s;
|
|
|
+ db_vals[nr_keys].val.blob_val.len = extra_hdrs.len;
|
|
|
+
|
|
|
+ nr_keys++;
|
|
|
+
|
|
|
if(msilo_dbf.insert(db_con, db_keys, db_vals, nr_keys) < 0)
|
|
|
{
|
|
|
LM_ERR("failed to store message\n");
|
|
@@ -822,25 +893,42 @@ error:
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * store message
|
|
|
+ */
|
|
|
+static int m_store_2(struct sip_msg* msg, char* owner, char* s2)
|
|
|
+{
|
|
|
+ str owner_s;
|
|
|
+ if (owner != NULL)
|
|
|
+ {
|
|
|
+ if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
|
|
|
+ {
|
|
|
+ LM_ERR("invalid owner uri parameter");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ return m_store(msg, &owner_s);
|
|
|
+ }
|
|
|
+ return m_store(msg, NULL);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* dump message
|
|
|
*/
|
|
|
-static int m_dump(struct sip_msg* msg, char* owner, char* str2)
|
|
|
+static int m_dump(struct sip_msg* msg, str* owner_s)
|
|
|
{
|
|
|
struct to_body *pto = NULL;
|
|
|
db_key_t db_keys[3];
|
|
|
db_key_t ob_key;
|
|
|
db_op_t db_ops[3];
|
|
|
db_val_t db_vals[3];
|
|
|
- db_key_t db_cols[6];
|
|
|
+ db_key_t db_cols[7];
|
|
|
db1_res_t* db_res = NULL;
|
|
|
- int i, db_no_cols = 6, db_no_keys = 3, mid, n;
|
|
|
+ int i, db_no_cols = 7, db_no_keys = 3, mid, n;
|
|
|
static char hdr_buf[1024];
|
|
|
static char body_buf[1024];
|
|
|
struct sip_uri puri;
|
|
|
- str owner_s;
|
|
|
uac_req_t uac_r;
|
|
|
- str str_vals[4], hdr_str, body_str, extra_hdrs_str;
|
|
|
+ str str_vals[5], hdr_str, body_str, extra_hdrs_str;
|
|
|
time_t rtime;
|
|
|
|
|
|
/* init */
|
|
@@ -859,6 +947,7 @@ static int m_dump(struct sip_msg* msg, char* owner, char* str2)
|
|
|
db_cols[3]=&sc_body;
|
|
|
db_cols[4]=&sc_ctype;
|
|
|
db_cols[5]=&sc_inc_time;
|
|
|
+ db_cols[6]=&sc_extra_hdrs;
|
|
|
|
|
|
|
|
|
LM_DBG("------------ start ------------\n");
|
|
@@ -889,19 +978,14 @@ static int m_dump(struct sip_msg* msg, char* owner, char* str2)
|
|
|
|
|
|
/* get the owner */
|
|
|
memset(&puri, 0, sizeof(struct sip_uri));
|
|
|
- if(owner)
|
|
|
+ if(owner_s)
|
|
|
{
|
|
|
- if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
|
|
|
- {
|
|
|
- LM_ERR("invalid owner uri parameter");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- if(parse_uri(owner_s.s, owner_s.len, &puri)!=0)
|
|
|
+ if(parse_uri(owner_s->s, owner_s->len, &puri)!=0)
|
|
|
{
|
|
|
LM_ERR("bad owner SIP address!\n");
|
|
|
goto error;
|
|
|
} else {
|
|
|
- LM_DBG("using user id [%.*s]\n", owner_s.len, owner_s.s);
|
|
|
+ LM_DBG("using user id [%.*s]\n", owner_s->len, owner_s->s);
|
|
|
}
|
|
|
} else { /* get it from To URI */
|
|
|
if(parse_uri(pto->uri.s, pto->uri.len, &puri)!=0)
|
|
@@ -959,11 +1043,12 @@ static int m_dump(struct sip_msg* msg, char* owner, char* str2)
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- memset(str_vals, 0, 4*sizeof(str));
|
|
|
+ memset(str_vals, 0, 5*sizeof(str));
|
|
|
SET_STR_VAL(str_vals[0], db_res, i, 1); /* from */
|
|
|
SET_STR_VAL(str_vals[1], db_res, i, 2); /* to */
|
|
|
SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */
|
|
|
SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */
|
|
|
+ SET_STR_VAL(str_vals[4], db_res, i, 6); /* stored hdrs */
|
|
|
rtime =
|
|
|
(time_t)RES_ROWS(db_res)[i].values[5/*inc time*/].val.int_val;
|
|
|
|
|
@@ -982,7 +1067,7 @@ static int m_dump(struct sip_msg* msg, char* owner, char* str2)
|
|
|
hdr_str.len = 1024;
|
|
|
if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/,
|
|
|
str_vals[0]/*from*/, rtime /*Date*/,
|
|
|
- extra_hdrs_str /*extra_hdrs*/) < 0)
|
|
|
+ str_vals[4] /*stored_hdrs*/) < 0)
|
|
|
{
|
|
|
LM_ERR("headers building failed [%d]\n", mid);
|
|
|
if (msilo_dbf.free_result(db_con, db_res) < 0)
|
|
@@ -1036,6 +1121,24 @@ error:
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * dump message
|
|
|
+ */
|
|
|
+static int m_dump_2(struct sip_msg* msg, char* owner, char* s2)
|
|
|
+{
|
|
|
+ str owner_s;
|
|
|
+ if (owner != NULL)
|
|
|
+ {
|
|
|
+ if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
|
|
|
+ {
|
|
|
+ LM_ERR("invalid owner uri parameter");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ return m_dump(msg, &owner_s);
|
|
|
+ }
|
|
|
+ return m_dump(msg, NULL);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* - cleaning up the messages that got reply
|
|
|
* - delete expired messages from database
|