2
0
Эх сурвалжийг харах

modules_k/msilo, lib/srdb1/schema: extra headers in MESSAGE requests can now be stored in the silo

- Allows extra information relating to a MESSAGE to be preserved when it is stored
- This enhancement was made by Hugh Waite at Crocodile RCS
- Also exported the msilo API so that it can be used in app_lua
pd 14 жил өмнө
parent
commit
d0b4bc91ea

+ 8 - 1
lib/srdb1/schema/silo.xml

@@ -9,7 +9,7 @@
 
 <table id="silo" xmlns:db="http://docbook.org/ns/docbook">
     <name>silo</name>
-    <version>5</version>
+    <version>6</version>
     <type db="mysql">&MYSQL_TABLE_TYPE;</type>
     <description>
         <db:para> This table us used by the msilo module to provide offline message storage More information about the msilo module can be found at: &KAMAILIO_MOD_DOC;msilo.html
@@ -96,6 +96,13 @@
         <description>Body of the message</description>
     </column>
 
+    <column>
+        <name>extra_hdrs</name>
+        <type>text</type>
+        <default/>
+        <description>iExtra headers that must be restored</description>
+    </column>
+
     <index>
         <name>account_idx</name>
         <colref linkend="username"/>

+ 151 - 48
modules_k/msilo/msilo.c

@@ -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

+ 2 - 2
utils/kamctl/db_berkeley/kamailio/silo

@@ -1,5 +1,5 @@
 METADATA_COLUMNS
-id(int) src_addr(str) dst_addr(str) username(str) domain(str) inc_time(int) exp_time(int) snd_time(int) ctype(str) body(str)
+id(int) src_addr(str) dst_addr(str) username(str) domain(str) inc_time(int) exp_time(int) snd_time(int) ctype(str) body(str) extra_hdrs(str)
 METADATA_KEY
 3 4 
 METADATA_READONLY
@@ -7,4 +7,4 @@ METADATA_READONLY
 METADATA_LOGFLAGS
 0
 METADATA_DEFAULTS
-NIL|''|''|''|''|0|0|0|'text/plain'|''
+NIL|''|''|''|''|0|0|0|'text/plain'|''|''

+ 1 - 1
utils/kamctl/db_berkeley/kamailio/version

@@ -91,7 +91,7 @@ rls_presentity|1
 rls_watchers|
 rls_watchers|1
 silo|
-silo|5
+silo|6
 sip_trace|
 sip_trace|3
 speed_dial|

+ 3 - 2
utils/kamctl/db_sqlite/msilo-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('silo','5');
+INSERT INTO version (table_name, table_version) values ('silo','6');
 CREATE TABLE silo (
     id INTEGER PRIMARY KEY NOT NULL,
     src_addr VARCHAR(128) DEFAULT '' NOT NULL,
@@ -9,7 +9,8 @@ CREATE TABLE silo (
     exp_time INTEGER DEFAULT 0 NOT NULL,
     snd_time INTEGER DEFAULT 0 NOT NULL,
     ctype VARCHAR(32) DEFAULT 'text/plain' NOT NULL,
-    body BYTEA DEFAULT '' NOT NULL
+    body BYTEA DEFAULT '' NOT NULL,
+    extra_hdrs TEXT DEFAULT '' NOT NULL
 );
 
 CREATE INDEX silo_account_idx ON silo (username, domain);

+ 1 - 1
utils/kamctl/dbtext/kamailio/silo

@@ -1 +1 @@
-id(int,auto) src_addr(string) dst_addr(string) username(string) domain(string) inc_time(int) exp_time(int) snd_time(int) ctype(string) body(string) 
+id(int,auto) src_addr(string) dst_addr(string) username(string) domain(string) inc_time(int) exp_time(int) snd_time(int) ctype(string) body(string) extra_hdrs(string) 

+ 1 - 1
utils/kamctl/dbtext/kamailio/version

@@ -40,7 +40,7 @@ purplemap:1
 re_grp:1
 rls_presentity:1
 rls_watchers:1
-silo:5
+silo:6
 sip_trace:3
 speed_dial:2
 subscriber:6

+ 3 - 2
utils/kamctl/mysql/msilo-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('silo','5');
+INSERT INTO version (table_name, table_version) values ('silo','6');
 CREATE TABLE silo (
     id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
     src_addr VARCHAR(128) DEFAULT '' NOT NULL,
@@ -9,7 +9,8 @@ CREATE TABLE silo (
     exp_time INT DEFAULT 0 NOT NULL,
     snd_time INT DEFAULT 0 NOT NULL,
     ctype VARCHAR(32) DEFAULT 'text/plain' NOT NULL,
-    body BLOB DEFAULT '' NOT NULL
+    body BLOB DEFAULT '' NOT NULL,
+    extra_hdrs TEXT DEFAULT '' NOT NULL
 ) ENGINE=MyISAM;
 
 CREATE INDEX account_idx ON silo (username, domain);

+ 3 - 2
utils/kamctl/oracle/msilo-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('silo','5');
+INSERT INTO version (table_name, table_version) values ('silo','6');
 CREATE TABLE silo (
     id NUMBER(10) PRIMARY KEY,
     src_addr VARCHAR2(128) DEFAULT '',
@@ -9,7 +9,8 @@ CREATE TABLE silo (
     exp_time NUMBER(10) DEFAULT 0 NOT NULL,
     snd_time NUMBER(10) DEFAULT 0 NOT NULL,
     ctype VARCHAR2(32) DEFAULT 'text/plain',
-    body BLOB DEFAULT ''
+    body BLOB DEFAULT '',
+    extra_hdrs CLOB DEFAULT ''
 );
 
 CREATE OR REPLACE TRIGGER silo_tr

+ 3 - 2
utils/kamctl/postgres/msilo-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('silo','5');
+INSERT INTO version (table_name, table_version) values ('silo','6');
 CREATE TABLE silo (
     id SERIAL PRIMARY KEY NOT NULL,
     src_addr VARCHAR(128) DEFAULT '' NOT NULL,
@@ -9,7 +9,8 @@ CREATE TABLE silo (
     exp_time INTEGER DEFAULT 0 NOT NULL,
     snd_time INTEGER DEFAULT 0 NOT NULL,
     ctype VARCHAR(32) DEFAULT 'text/plain' NOT NULL,
-    body BYTEA DEFAULT '' NOT NULL
+    body BYTEA DEFAULT '' NOT NULL,
+    extra_hdrs TEXT DEFAULT '' NOT NULL
 );
 
 CREATE INDEX silo_account_idx ON silo (username, domain);