123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608 |
- /*
- * $Id$
- *
- * MSILO module
- *
- * Copyright (C) 2001-2003 FhG Fokus
- *
- * This file is part of Kamailio, a free SIP server.
- *
- * Kamailio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * Kamailio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * History
- * -------
- *
- * 2003-01-23: switched from t_uac to t_uac_dlg (dcm)
- * 2003-02-28: protocolization of t_uac_dlg completed (jiri)
- * 2003-03-11: updated to the new module interface (andrei)
- * removed non-constant initializers to some strs (andrei)
- * 2003-03-16: flags parameter added (janakj)
- * 2003-04-05: default_uri #define used (jiri)
- * 2003-04-06: db_init removed from mod_init, will be called from child_init
- * now (janakj)
- * 2003-04-07: m_dump takes a parameter which sets the way the outgoing URI
- * is computed (dcm)
- * 2003-08-05 adapted to the new parse_content_type_hdr function (bogdan)
- * 2004-06-07 updated to the new DB api (andrei)
- * 2006-09-10 m_dump now checks if registering UA supports MESSAGE method (jh)
- * 2006-10-05 added max_messages module variable (jh)
- * 2011-10-19 added storage of extra SIP headers (hpw)
- * 2011-12-07 added storage of extra SIP headers from AVP (jh)
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <time.h>
- #include "../../sr_module.h"
- #include "../../dprint.h"
- #include "../../ut.h"
- #include "../../timer.h"
- #include "../../mem/shm_mem.h"
- #include "../../lib/srdb1/db.h"
- #include "../../parser/parse_from.h"
- #include "../../parser/parse_content.h"
- #include "../../parser/contact/parse_contact.h"
- #include "../../parser/parse_allow.h"
- #include "../../parser/parse_methods.h"
- #include "../../resolve.h"
- #include "../../usr_avp.h"
- #include "../../mod_fix.h"
- #include "../../modules/tm/tm_load.h"
- #include "ms_msg_list.h"
- #include "msfuncs.h"
- #include "api.h"
- #define MAX_DEL_KEYS 1
- #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_stored_hdrs = str_init("extra_hdrs"); /* 10 */
- #define SET_STR_VAL(_str, _res, _r, _c) \
- if (RES_ROWS(_res)[_r].values[_c].nul == 0) \
- { \
- switch(RES_ROWS(_res)[_r].values[_c].type) \
- { \
- case DB1_STRING: \
- (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.string_val; \
- (_str).len=strlen((_str).s); \
- break; \
- case DB1_STR: \
- (_str).len=RES_ROWS(_res)[_r].values[_c].val.str_val.len; \
- (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.str_val.s; \
- break; \
- case DB1_BLOB: \
- (_str).len=RES_ROWS(_res)[_r].values[_c].val.blob_val.len; \
- (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.blob_val.s; \
- break; \
- default: \
- (_str).len=0; \
- (_str).s=NULL; \
- } \
- }
- MODULE_VERSION
- #define S_TABLE_VERSION 7
- /** database connection */
- static db1_con_t *db_con = NULL;
- static db_func_t msilo_dbf;
- /** precessed msg list - used for dumping the messages */
- msg_list ml = NULL;
- /** TM bind */
- struct tm_binds tmb;
- /** parameters */
- static str ms_db_url = str_init(DEFAULT_DB_URL);
- static str ms_db_table = str_init("silo");
- str ms_reminder = {NULL, 0};
- str ms_outbound_proxy = {NULL, 0};
- char* ms_from = NULL; /*"sip:[email protected]";*/
- char* ms_contact = NULL; /*"Contact: <sip:[email protected]>\r\n";*/
- char* ms_extra_hdrs = NULL; /*"X-foo: bar\r\nX-bar: foo\r\n";*/
- char* ms_content_type = NULL; /*"Content-Type: text/plain\r\n";*/
- char* ms_offline_message = NULL; /*"<em>I'm offline.</em>"*/
- void** ms_from_sp = NULL;
- void** ms_contact_sp = NULL;
- void** ms_extra_hdrs_sp = NULL;
- void** ms_content_type_sp = NULL;
- void** ms_offline_message_sp = NULL;
- int ms_expire_time = 259200;
- int ms_check_time = 60;
- int ms_send_time = 0;
- int ms_clean_period = 10;
- int ms_use_contact = 1;
- int ms_add_date = 1;
- int ms_add_contact = 0;
- int ms_max_messages = 0;
- static str ms_snd_time_avp_param = {NULL, 0};
- int_str ms_snd_time_avp_name;
- unsigned short ms_snd_time_avp_type;
- static str ms_extra_hdrs_avp_param = {NULL, 0};
- int_str ms_extra_hdrs_avp_name;
- unsigned short ms_extra_hdrs_avp_type;
- str msg_type = str_init("MESSAGE");
- /** module functions */
- static int mod_init(void);
- static int child_init(int);
- 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 *);
- 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_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_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}
- };
- static param_export_t params[]={
- { "db_url", PARAM_STR, &ms_db_url },
- { "db_table", PARAM_STR, &ms_db_table },
- { "from_address", PARAM_STRING, &ms_from },
- { "contact_hdr", PARAM_STRING, &ms_contact },
- { "extra_hdrs", PARAM_STRING, &ms_extra_hdrs },
- { "content_type_hdr", PARAM_STRING, &ms_content_type },
- { "offline_message", PARAM_STRING, &ms_offline_message },
- { "reminder", PARAM_STR, &ms_reminder },
- { "outbound_proxy", PARAM_STR, &ms_outbound_proxy },
- { "expire_time", INT_PARAM, &ms_expire_time },
- { "check_time", INT_PARAM, &ms_check_time },
- { "send_time", INT_PARAM, &ms_send_time },
- { "clean_period", INT_PARAM, &ms_clean_period },
- { "use_contact", INT_PARAM, &ms_use_contact },
- { "sc_mid", PARAM_STR, &sc_mid },
- { "sc_from", PARAM_STR, &sc_from },
- { "sc_to", PARAM_STR, &sc_to },
- { "sc_uri_user", PARAM_STR, &sc_uri_user },
- { "sc_uri_host", PARAM_STR, &sc_uri_host },
- { "sc_body", PARAM_STR, &sc_body },
- { "sc_ctype", PARAM_STR, &sc_ctype },
- { "sc_exp_time", PARAM_STR, &sc_exp_time },
- { "sc_inc_time", PARAM_STR, &sc_inc_time },
- { "sc_snd_time", PARAM_STR, &sc_snd_time },
- { "sc_stored_hdrs", PARAM_STR, &sc_stored_hdrs },
- { "snd_time_avp", PARAM_STR, &ms_snd_time_avp_param },
- { "extra_hdrs_avp", PARAM_STR, &ms_extra_hdrs_avp_param },
- { "add_date", INT_PARAM, &ms_add_date },
- { "max_messages", INT_PARAM, &ms_max_messages },
- { "add_contact", INT_PARAM, &ms_add_contact },
- { 0,0,0 }
- };
- #ifdef STATISTICS
- #include "../../lib/kcore/statistics.h"
- stat_var* ms_stored_msgs;
- stat_var* ms_dumped_msgs;
- stat_var* ms_failed_msgs;
- stat_var* ms_dumped_rmds;
- stat_var* ms_failed_rmds;
- stat_export_t msilo_stats[] = {
- {"stored_messages" , 0, &ms_stored_msgs },
- {"dumped_messages" , 0, &ms_dumped_msgs },
- {"failed_messages" , 0, &ms_failed_msgs },
- {"dumped_reminders" , 0, &ms_dumped_rmds },
- {"failed_reminders" , 0, &ms_failed_rmds },
- {0,0,0}
- };
- #endif
- /** module exports */
- struct module_exports exports= {
- "msilo", /* module id */
- DEFAULT_DLFLAGS, /* dlopen flags */
- cmds, /* module's exported functions */
- params, /* module's exported parameters */
- #ifdef STATISTICS
- msilo_stats,
- #else
- 0, /* exported statistics */
- #endif
- 0, /* exported MI functions */
- 0, /* exported pseudo-variables */
- 0, /* extra processes */
- mod_init, /* module initialization function */
- 0, /* response handler */
- (destroy_function) destroy, /* module destroy function */
- 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
- */
- static int mod_init(void)
- {
- pv_spec_t avp_spec;
- #ifdef STATISTICS
- /* register statistics */
- if (register_module_stats( exports.name, msilo_stats)!=0 ) {
- LM_ERR("failed to register core statistics\n");
- return -1;
- }
- #endif
- /* binding to mysql module */
- if (db_bind_mod(&ms_db_url, &msilo_dbf))
- {
- LM_DBG("database module not found\n");
- return -1;
- }
- if (!DB_CAPABILITY(msilo_dbf, DB_CAP_ALL)) {
- LM_ERR("database module does not implement "
- "all functions needed by the module\n");
- return -1;
- }
- if (ms_snd_time_avp_param.s && ms_snd_time_avp_param.len > 0) {
- if (pv_parse_spec(&ms_snd_time_avp_param, &avp_spec)==0
- || avp_spec.type!=PVT_AVP) {
- LM_ERR("malformed or non AVP %.*s AVP definition\n",
- ms_snd_time_avp_param.len, ms_snd_time_avp_param.s);
- return -1;
- }
- if(pv_get_avp_name(0, &(avp_spec.pvp), &ms_snd_time_avp_name,
- &ms_snd_time_avp_type)!=0)
- {
- LM_ERR("[%.*s]- invalid AVP definition\n",
- ms_snd_time_avp_param.len, ms_snd_time_avp_param.s);
- return -1;
- }
- }
- if (ms_extra_hdrs_avp_param.s && ms_extra_hdrs_avp_param.len > 0) {
- if (pv_parse_spec(&ms_extra_hdrs_avp_param, &avp_spec)==0
- || avp_spec.type!=PVT_AVP) {
- LM_ERR("malformed or non AVP %.*s AVP definition\n",
- ms_extra_hdrs_avp_param.len, ms_extra_hdrs_avp_param.s);
- return -1;
- }
- if (pv_get_avp_name(0, &(avp_spec.pvp), &ms_extra_hdrs_avp_name,
- &ms_extra_hdrs_avp_type) != 0) {
- LM_ERR("[%.*s]- invalid AVP definition\n",
- ms_extra_hdrs_avp_param.len, ms_extra_hdrs_avp_param.s);
- return -1;
- }
- }
- db_con = msilo_dbf.init(&ms_db_url);
- if (!db_con)
- {
- LM_ERR("failed to connect to the database\n");
- return -1;
- }
- if(db_check_table_version(&msilo_dbf, db_con, &ms_db_table, S_TABLE_VERSION) < 0) {
- LM_ERR("error during table version check.\n");
- return -1;
- }
- if(db_con)
- msilo_dbf.close(db_con);
- db_con = NULL;
- /* load the TM API */
- if (load_tm_api(&tmb)!=0) {
- LM_ERR("can't load TM API\n");
- return -1;
- }
- if(ms_from!=NULL)
- {
- ms_from_sp = (void**)pkg_malloc(sizeof(void*));
- if(ms_from_sp==NULL)
- {
- LM_ERR("no more pkg\n");
- return -1;
- }
- *ms_from_sp = (void*)ms_from;
- if(fixup_spve_null(ms_from_sp, 1)!=0)
- {
- LM_ERR("bad contact parameter\n");
- return -1;
- }
- }
- if(ms_contact!=NULL)
- {
- ms_contact_sp = (void**)pkg_malloc(sizeof(void*));
- if(ms_contact_sp==NULL)
- {
- LM_ERR("no more pkg\n");
- return -1;
- }
- *ms_contact_sp = (void*)ms_contact;
- if(fixup_spve_null(ms_contact_sp, 1)!=0)
- {
- LM_ERR("bad contact parameter\n");
- return -1;
- }
- }
- if(ms_extra_hdrs!=NULL)
- {
- ms_extra_hdrs_sp = (void**)pkg_malloc(sizeof(void*));
- if(ms_extra_hdrs_sp==NULL)
- {
- LM_ERR("no more pkg\n");
- return -1;
- }
- *ms_extra_hdrs_sp = (void*)ms_extra_hdrs;
- if(fixup_spve_null(ms_extra_hdrs_sp, 1)!=0)
- {
- LM_ERR("bad extra_hdrs parameter\n");
- return -1;
- }
- }
- if(ms_content_type!=NULL)
- {
- ms_content_type_sp = (void**)pkg_malloc(sizeof(void*));
- if(ms_content_type_sp==NULL)
- {
- LM_ERR("no more pkg\n");
- return -1;
- }
- *ms_content_type_sp = (void*)ms_content_type;
- if(fixup_spve_null(ms_content_type_sp, 1)!=0)
- {
- LM_ERR("bad content_type parameter\n");
- return -1;
- }
- }
- if(ms_offline_message!=NULL)
- {
- ms_offline_message_sp = (void**)pkg_malloc(sizeof(void*));
- if(ms_offline_message_sp==NULL)
- {
- LM_ERR("no more pkg\n");
- return -1;
- }
- *ms_offline_message_sp = (void*)ms_offline_message;
- if(fixup_spve_null(ms_offline_message_sp, 1)!=0)
- {
- LM_ERR("bad offline_message parameter\n");
- return -1;
- }
- }
- if(ms_offline_message!=NULL && ms_content_type==NULL)
- {
- LM_ERR("content_type parameter must be set\n");
- return -1;
- }
- ml = msg_list_init();
- if(ml==NULL)
- {
- LM_ERR("can't initialize msg list\n");
- return -1;
- }
- if(ms_check_time<0)
- {
- LM_ERR("bad check time value\n");
- return -1;
- }
- register_timer(m_clean_silo, 0, ms_check_time);
- if(ms_send_time>0 && ms_reminder.s!=NULL)
- register_timer(m_send_ontimer, 0, ms_send_time);
- return 0;
- }
- /**
- * Initialize children
- */
- static int child_init(int rank)
- {
- if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
- return 0; /* do nothing for the main process */
- LM_DBG("rank #%d / pid <%d>\n", rank, getpid());
- if (msilo_dbf.init==0)
- {
- LM_CRIT("database not bound\n");
- return -1;
- }
- db_con = msilo_dbf.init(&ms_db_url);
- if (!db_con)
- {
- LM_ERR("child %d: failed to connect database\n", rank);
- return -1;
- }
- else
- {
- if (msilo_dbf.use_table(db_con, &ms_db_table) < 0) {
- LM_ERR("child %d: failed in use_table\n", rank);
- return -1;
- }
-
- LM_DBG("#%d database connection opened successfully\n", 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;
- int_str avp_value;
- struct usr_avp *avp;
- if (ms_extra_hdrs_avp_name.n != 0) {
- avp = NULL;
- avp = search_first_avp(ms_extra_hdrs_avp_type,
- ms_extra_hdrs_avp_name, &avp_value, 0);
- if ((avp != NULL) && is_avp_str_val(avp)) {
- if (buf_len <= avp_value.s.len) {
- LM_ERR("insufficient space to store headers in silo\n");
- return -1;
- }
- memcpy(buf, avp_value.s.s, avp_value.s.len);
- return avp_value.s.len;
- }
- }
- 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
- * = "1" -- look for outgoing URI starting with r-uri
- * = "2" -- look for outgoing URI only at to header
- */
- 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;
- #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];
- db1_res_t* res = NULL;
- uac_req_t uac_r;
-
- int nr_keys = 0, val, lexpire;
- content_type_t ctype;
- #define MS_BUF1_SIZE 1024
- static char ms_buf1[MS_BUF1_SIZE];
- int mime;
- str notify_from;
- str notify_body;
- str notify_ctype;
- str notify_contact;
- int_str avp_value;
- struct usr_avp *avp;
- LM_DBG("------------ start ------------\n");
- /* get message body - after that whole SIP MESSAGE is parsed */
- body.s = get_body( msg );
- if (body.s==0)
- {
- LM_ERR("cannot extract body from msg\n");
- goto error;
- }
-
- /* content-length (if present) must be already parsed */
- if (!msg->content_length)
- {
- LM_ERR("no Content-Length header found!\n");
- goto error;
- }
- body.len = get_content_length( msg );
- /* check if the body of message contains something */
- if(body.len <= 0)
- {
- LM_ERR("body of the message is empty!\n");
- goto error;
- }
-
- /* get TO URI */
- if(parse_to_header(msg)<0)
- {
- LM_ERR("failed getting 'to' header!\n");
- goto error;
- }
-
- pto = get_to(msg);
-
- /* get the owner */
- memset(&puri, 0, sizeof(struct sip_uri));
- if(owner_s != NULL)
- {
- 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);
- }
- } else { /* get it from R-URI */
- if(msg->new_uri.len <= 0)
- {
- if(msg->first_line.u.request.uri.len <= 0)
- {
- LM_ERR("bad dst URI!\n");
- goto error;
- }
- duri = msg->first_line.u.request.uri;
- } else {
- duri = msg->new_uri;
- }
- LM_DBG("NEW R-URI found - check if is AoR!\n");
- if(parse_uri(duri.s, duri.len, &puri)!=0)
- {
- LM_ERR("bad dst R-URI!!\n");
- goto error;
- }
- }
- if(puri.user.len<=0)
- {
- LM_ERR("no username for owner\n");
- goto error;
- }
-
- db_keys[nr_keys] = &sc_uri_user;
-
- db_vals[nr_keys].type = DB1_STR;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.str_val.s = puri.user.s;
- db_vals[nr_keys].val.str_val.len = puri.user.len;
- nr_keys++;
- db_keys[nr_keys] = &sc_uri_host;
-
- db_vals[nr_keys].type = DB1_STR;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.str_val.s = puri.host.s;
- db_vals[nr_keys].val.str_val.len = puri.host.len;
- nr_keys++;
- if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
- {
- LM_ERR("failed to use_table\n");
- goto error;
- }
- if (ms_max_messages > 0) {
- db_cols[0] = &sc_inc_time;
- if (msilo_dbf.query(db_con, db_keys, 0, db_vals, db_cols,
- 2, 1, 0, &res) < 0 ) {
- LM_ERR("failed to query the database\n");
- return -1;
- }
- if (RES_ROW_N(res) >= ms_max_messages) {
- LM_ERR("too many messages for AoR '%.*s@%.*s'\n",
- puri.user.len, puri.user.s, puri.host.len, puri.host.s);
- msilo_dbf.free_result(db_con, res);
- return -1;
- }
- msilo_dbf.free_result(db_con, res);
- }
- /* Set To key */
- db_keys[nr_keys] = &sc_to;
-
- db_vals[nr_keys].type = DB1_STR;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.str_val.s = pto->uri.s;
- db_vals[nr_keys].val.str_val.len = pto->uri.len;
- nr_keys++;
- /* check FROM URI */
- if ( parse_from_header( msg )<0 )
- {
- LM_ERR("cannot parse From header\n");
- goto error;
- }
- pfrom = get_from(msg);
- LM_DBG("'From' header: <%.*s>\n", pfrom->uri.len, pfrom->uri.s);
-
- db_keys[nr_keys] = &sc_from;
-
- db_vals[nr_keys].type = DB1_STR;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.str_val.s = pfrom->uri.s;
- db_vals[nr_keys].val.str_val.len = pfrom->uri.len;
- 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 )
- {
- LM_ERR("cannot parse Content-Type header\n");
- goto error;
- }
- db_keys[nr_keys] = &sc_ctype;
- db_vals[nr_keys].type = DB1_STR;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.str_val.s = "text/plain";
- db_vals[nr_keys].val.str_val.len = 10;
-
- /** check the content-type value */
- if( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
- && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM )
- {
- if(m_extract_content_type(msg->content_type->body.s,
- msg->content_type->body.len, &ctype, CT_TYPE) != -1)
- {
- LM_DBG("'content-type' found\n");
- db_vals[nr_keys].val.str_val.s = ctype.type.s;
- db_vals[nr_keys].val.str_val.len = ctype.type.len;
- }
- }
- nr_keys++;
- /* check 'expires' -- no more parsing - already done by get_body() */
- if(msg->expires && msg->expires->body.len > 0)
- {
- LM_DBG("'expires' found\n");
- val = atoi(msg->expires->body.s);
- if(val > 0)
- lexpire = (ms_expire_time<=val)?ms_expire_time:val;
- }
- /* current time */
- val = (int)time(NULL);
- /* add expiration time */
- db_keys[nr_keys] = &sc_exp_time;
- db_vals[nr_keys].type = DB1_INT;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.int_val = val+lexpire;
- nr_keys++;
- /* add incoming time */
- db_keys[nr_keys] = &sc_inc_time;
- db_vals[nr_keys].type = DB1_INT;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.int_val = val;
- nr_keys++;
- /* add sending time */
- db_keys[nr_keys] = &sc_snd_time;
- db_vals[nr_keys].type = DB1_INT;
- db_vals[nr_keys].nul = 0;
- db_vals[nr_keys].val.int_val = 0;
- if(ms_snd_time_avp_name.n!=0)
- {
- avp = NULL;
- avp=search_first_avp(ms_snd_time_avp_type, ms_snd_time_avp_name,
- &avp_value, 0);
- if(avp!=NULL && is_avp_str_val(avp))
- {
- if(ms_extract_time(&avp_value.s, &db_vals[nr_keys].val.int_val)!=0)
- db_vals[nr_keys].val.int_val = 0;
- }
- }
- 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_stored_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");
- goto error;
- }
- LM_DBG("message stored. T:<%.*s> F:<%.*s>\n",
- pto->uri.len, pto->uri.s, pfrom->uri.len, pfrom->uri.s);
-
- #ifdef STATISTICS
- update_stat(ms_stored_msgs, 1);
- #endif
- if(ms_from==NULL || ms_offline_message == NULL)
- goto done;
- LM_DBG("sending info message.\n");
- if(fixup_get_svalue(msg, (gparam_p)*ms_from_sp, ¬ify_from)!=0
- || notify_from.len<=0)
- {
- LM_WARN("cannot get notification From address\n");
- goto done;
- }
- if(fixup_get_svalue(msg, (gparam_p)*ms_offline_message_sp, ¬ify_body)!=0
- || notify_body.len<=0)
- {
- LM_WARN("cannot get notification body\n");
- goto done;
- }
- if(fixup_get_svalue(msg, (gparam_p)*ms_content_type_sp, ¬ify_ctype)!=0
- || notify_ctype.len<=0)
- {
- LM_WARN("cannot get notification content type\n");
- goto done;
- }
- if(ms_contact!=NULL && fixup_get_svalue(msg, (gparam_p)*ms_contact_sp,
- ¬ify_contact)==0 && notify_contact.len>0)
- {
- if(notify_contact.len+notify_ctype.len>=MS_BUF1_SIZE)
- {
- LM_WARN("insufficient buffer to build notification headers\n");
- goto done;
- }
- memcpy(ms_buf1, notify_contact.s, notify_contact.len);
- memcpy(ms_buf1+notify_contact.len, notify_ctype.s, notify_ctype.len);
- str_hdr.s = ms_buf1;
- str_hdr.len = notify_contact.len + notify_ctype.len;
- } else {
- str_hdr = notify_ctype;
- }
- /* look for Contact header -- must be parsed by now*/
- ctaddr.s = NULL;
- if(ms_use_contact && msg->contact!=NULL && msg->contact->body.s!=NULL
- && msg->contact->body.len > 0)
- {
- LM_DBG("contact header found\n");
- if((msg->contact->parsed!=NULL
- && ((contact_body_t*)(msg->contact->parsed))->contacts!=NULL)
- || (parse_contact(msg->contact)==0
- && msg->contact->parsed!=NULL
- && ((contact_body_t*)(msg->contact->parsed))->contacts!=NULL))
- {
- LM_DBG("using contact header for info msg\n");
- ctaddr.s =
- ((contact_body_t*)(msg->contact->parsed))->contacts->uri.s;
- ctaddr.len =
- ((contact_body_t*)(msg->contact->parsed))->contacts->uri.len;
-
- if(!ctaddr.s || ctaddr.len < 6 || strncmp(ctaddr.s, "sip:", 4)
- || ctaddr.s[4]==' ')
- ctaddr.s = NULL;
- else
- LM_DBG("feedback contact [%.*s]\n", ctaddr.len,ctaddr.s);
- }
- }
-
- memset(&uac_r,'\0', sizeof(uac_r));
- uac_r.method = &msg_type;
- uac_r.headers = &str_hdr;
- uac_r.body = ¬ify_body;
- tmb.t_request(&uac_r, /* UAC Req */
- (ctaddr.s)?&ctaddr:&pfrom->uri, /* Request-URI */
- &pfrom->uri, /* To */
- ¬ify_from, /* From */
- (ms_outbound_proxy.s)?&ms_outbound_proxy:0 /* outbound uri */
- );
- done:
- return 1;
- 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, 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[7];
- db1_res_t* db_res = NULL;
- 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;
- uac_req_t uac_r;
- str str_vals[5], hdr_str, body_str, extra_hdrs_str, tmp_extra_hdrs;
- time_t rtime;
-
- /* init */
- ob_key = &sc_mid;
- db_keys[0]=&sc_uri_user;
- db_keys[1]=&sc_uri_host;
- db_keys[2]=&sc_snd_time;
- db_ops[0]=OP_EQ;
- db_ops[1]=OP_EQ;
- db_ops[2]=OP_EQ;
- db_cols[0]=&sc_mid;
- db_cols[1]=&sc_from;
- db_cols[2]=&sc_to;
- db_cols[3]=&sc_body;
- db_cols[4]=&sc_ctype;
- db_cols[5]=&sc_inc_time;
- db_cols[6]=&sc_stored_hdrs;
-
- LM_DBG("------------ start ------------\n");
- hdr_str.s=hdr_buf;
- hdr_str.len=1024;
- body_str.s=body_buf;
- body_str.len=1024;
-
- /* check for TO header */
- if(parse_to_header(msg)<0)
- {
- LM_ERR("failed parsing To header\n");
- goto error;
- }
- pto = get_to(msg);
- /**
- * check if has expires=0 (REGISTER)
- */
- if(msg->first_line.u.request.method_value==METHOD_REGISTER)
- {
- if (check_message_support(msg)!=0) {
- LM_DBG("MESSAGE method not supported\n");
- return -1;
- }
- }
-
- /* get the owner */
- memset(&puri, 0, sizeof(struct sip_uri));
- if(owner_s)
- {
- 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);
- }
- } else { /* get it from To URI */
- if(parse_uri(pto->uri.s, pto->uri.len, &puri)!=0)
- {
- LM_ERR("bad owner To URI!\n");
- goto error;
- }
- }
- if(puri.user.len<=0 || puri.user.s==NULL
- || puri.host.len<=0 || puri.host.s==NULL)
- {
- LM_ERR("bad owner URI!\n");
- goto error;
- }
- db_vals[0].type = DB1_STR;
- db_vals[0].nul = 0;
- db_vals[0].val.str_val.s = puri.user.s;
- db_vals[0].val.str_val.len = puri.user.len;
- db_vals[1].type = DB1_STR;
- db_vals[1].nul = 0;
- db_vals[1].val.str_val.s = puri.host.s;
- db_vals[1].val.str_val.len = puri.host.len;
- db_vals[2].type = DB1_INT;
- db_vals[2].nul = 0;
- db_vals[2].val.int_val = 0;
- if (db_con == NULL) {
- LM_ERR("database connection has not been established\n");
- goto error;
- }
- if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
- {
- LM_ERR("failed to use_table\n");
- return -1;
- }
- if (msilo_dbf.query(db_con,db_keys,db_ops,db_vals,db_cols,db_no_keys,
- db_no_cols, ob_key, &db_res) < 0) {
- LM_ERR("failed to query database\n");
- goto error;
- }
- if (RES_ROW_N(db_res) <= 0) {
- LM_DBG("no stored message for <%.*s>!\n", pto->uri.len, pto->uri.s);
- goto done;
- }
-
- LM_DBG("dumping [%d] messages for <%.*s>!!!\n",
- RES_ROW_N(db_res), pto->uri.len, pto->uri.s);
- for(i = 0; i < RES_ROW_N(db_res); i++)
- {
- mid = RES_ROWS(db_res)[i].values[0].val.int_val;
- if(msg_list_check_msg(ml, mid))
- {
- LM_DBG("message[%d] mid=%d already sent.\n", i, mid);
- continue;
- }
-
- 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;
-
- if (ms_extra_hdrs != NULL) {
- if (fixup_get_svalue(msg, (gparam_p)*ms_extra_hdrs_sp,
- &extra_hdrs_str) != 0) {
- if (msilo_dbf.free_result(db_con, db_res) < 0)
- LM_ERR("failed to free the query result\n");
- LM_ERR("unable to get extra_hdrs value\n");
- goto error;
- }
- } else {
- extra_hdrs_str.len = 0;
- }
- tmp_extra_hdrs.len = extra_hdrs_str.len+str_vals[4].len;
- if(tmp_extra_hdrs.len>0)
- {
- if ((tmp_extra_hdrs.s = pkg_malloc(tmp_extra_hdrs.len)) == NULL)
- {
- LM_ERR("Out of pkg memory");
- if (msilo_dbf.free_result(db_con, db_res) < 0)
- LM_ERR("failed to free the query result\n");
- msg_list_set_flag(ml, mid, MS_MSG_ERRO);
- goto error;
- }
- if(extra_hdrs_str.len>0)
- memcpy(tmp_extra_hdrs.s, extra_hdrs_str.s, extra_hdrs_str.len);
- memcpy(tmp_extra_hdrs.s+extra_hdrs_str.len, str_vals[4].s, str_vals[4].len);
- } else {
- tmp_extra_hdrs.len = 0;
- tmp_extra_hdrs.s = "";
- }
- hdr_str.len = 1024;
- if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/,
- str_vals[0]/*from*/, rtime /*Date*/,
- tmp_extra_hdrs /*extra_hdrs*/) < 0)
- {
- LM_ERR("headers building failed [%d]\n", mid);
- if(tmp_extra_hdrs.len>0)
- pkg_free(tmp_extra_hdrs.s);
- if (msilo_dbf.free_result(db_con, db_res) < 0)
- LM_ERR("failed to free the query result\n");
- msg_list_set_flag(ml, mid, MS_MSG_ERRO);
- goto error;
- }
- if(tmp_extra_hdrs.len>0)
- pkg_free(tmp_extra_hdrs.s);
-
- LM_DBG("msg [%d-%d] for: %.*s\n", i+1, mid, pto->uri.len, pto->uri.s);
-
- /** sending using TM function: t_uac */
- body_str.len = 1024;
- /* send composed body only if content type is text/plain */
- if ((str_vals[3].len == 10) &&
- (strncmp(str_vals[3].s, "text/plain", 10) == 0)) {
- n = m_build_body(&body_str, rtime, str_vals[2/*body*/], 0);
- } else {
- n = -1;
- }
- if(n<0)
- LM_DBG("sending simple body\n");
- else
- LM_DBG("sending composed body\n");
-
- memset(&uac_r,'\0', sizeof(uac_r));
- uac_r.method = &msg_type;
- uac_r.headers = &hdr_str;
- uac_r.body = (n<0)?&str_vals[2]:&body_str;
- uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
- uac_r.cb = m_tm_callback;
- uac_r.cbp = (void*)(long)mid;
- tmb.t_request(&uac_r, /* UAC Req */
- &str_vals[1], /* Request-URI */
- &str_vals[1], /* To */
- &str_vals[0], /* From */
- (ms_outbound_proxy.s)?&ms_outbound_proxy:0 /* ob uri */
- );
- }
- done:
- /**
- * Free the result because we don't need it
- * anymore
- */
- if ((db_res !=NULL) && msilo_dbf.free_result(db_con, db_res) < 0)
- LM_ERR("failed to free result of query\n");
- return 1;
- 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
- */
- void m_clean_silo(unsigned int ticks, void *param)
- {
- msg_list_el mle = NULL, p;
- db_key_t db_keys[MAX_DEL_KEYS];
- db_val_t db_vals[MAX_DEL_KEYS];
- db_op_t db_ops[1] = { OP_LEQ };
- int n;
-
- LM_DBG("cleaning stored messages - %d\n", ticks);
-
- msg_list_check(ml);
- mle = p = msg_list_reset(ml);
- n = 0;
- if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
- {
- LM_ERR("failed to use_table\n");
- return;
- }
- while(p)
- {
- if(p->flag & MS_MSG_DONE)
- {
- #ifdef STATISTICS
- if(p->flag & MS_MSG_TSND)
- update_stat(ms_dumped_msgs, 1);
- else
- update_stat(ms_dumped_rmds, 1);
- #endif
- db_keys[n] = &sc_mid;
- db_vals[n].type = DB1_INT;
- db_vals[n].nul = 0;
- db_vals[n].val.int_val = p->msgid;
- LM_DBG("cleaning sent message [%d]\n", p->msgid);
- n++;
- if(n==MAX_DEL_KEYS)
- {
- if (msilo_dbf.delete(db_con, db_keys, NULL, db_vals, n) < 0)
- LM_ERR("failed to clean %d messages.\n",n);
- n = 0;
- }
- }
- if((p->flag & MS_MSG_ERRO) && (p->flag & MS_MSG_TSND))
- { /* set snd time to 0 */
- ms_reset_stime(p->msgid);
- #ifdef STATISTICS
- update_stat(ms_failed_rmds, 1);
- #endif
- }
- #ifdef STATISTICS
- if((p->flag & MS_MSG_ERRO) && !(p->flag & MS_MSG_TSND))
- update_stat(ms_failed_msgs, 1);
- #endif
- p = p->next;
- }
- if(n>0)
- {
- if (msilo_dbf.delete(db_con, db_keys, NULL, db_vals, n) < 0)
- LM_ERR("failed to clean %d messages\n", n);
- n = 0;
- }
- msg_list_el_free_all(mle);
-
- /* cleaning expired messages */
- if(ticks%(ms_check_time*ms_clean_period)<ms_check_time)
- {
- LM_DBG("cleaning expired messages\n");
- db_keys[0] = &sc_exp_time;
- db_vals[0].type = DB1_INT;
- db_vals[0].nul = 0;
- db_vals[0].val.int_val = (int)time(NULL);
- if (msilo_dbf.delete(db_con, db_keys, db_ops, db_vals, 1) < 0)
- LM_DBG("ERROR cleaning expired messages\n");
- }
- }
- /**
- * destroy function
- */
- static void destroy(void)
- {
- msg_list_free(ml);
- if(db_con && msilo_dbf.close)
- msilo_dbf.close(db_con);
- }
- /**
- * TM callback function - delete message from database if was sent OK
- */
- void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps)
- {
- if(ps->param==NULL || *ps->param==0)
- {
- LM_DBG("message id not received\n");
- goto done;
- }
-
- LM_DBG("completed with status %d [mid: %ld/%d]\n",
- ps->code, (long)ps->param, *((int*)ps->param));
- if(!db_con)
- {
- LM_ERR("db_con is NULL\n");
- goto done;
- }
- if(ps->code >= 300)
- {
- LM_DBG("message <%d> was not sent successfully\n", *((int*)ps->param));
- msg_list_set_flag(ml, *((int*)ps->param), MS_MSG_ERRO);
- goto done;
- }
- LM_DBG("message <%d> was sent successfully\n", *((int*)ps->param));
- msg_list_set_flag(ml, *((int*)ps->param), MS_MSG_DONE);
- done:
- return;
- }
- void m_send_ontimer(unsigned int ticks, void *param)
- {
- db_key_t db_keys[2];
- db_op_t db_ops[2];
- db_val_t db_vals[2];
- db_key_t db_cols[6];
- db1_res_t* db_res = NULL;
- int i, db_no_cols = 6, db_no_keys = 2, mid, n;
- static char hdr_buf[1024];
- static char uri_buf[1024];
- static char body_buf[1024];
- str puri;
- time_t ttime;
- uac_req_t uac_r;
- str str_vals[4], hdr_str, body_str;
- str extra_hdrs_str = {0};
- time_t stime;
- if(ms_reminder.s==NULL)
- {
- LM_WARN("reminder address null\n");
- return;
- }
-
- /* init */
- db_keys[0]=&sc_snd_time;
- db_keys[1]=&sc_snd_time;
- db_ops[0]=OP_NEQ;
- db_ops[1]=OP_LEQ;
- db_cols[0]=&sc_mid;
- db_cols[1]=&sc_uri_user;
- db_cols[2]=&sc_uri_host;
- db_cols[3]=&sc_body;
- db_cols[4]=&sc_ctype;
- db_cols[5]=&sc_snd_time;
-
- LM_DBG("------------ start ------------\n");
- hdr_str.s=hdr_buf;
- hdr_str.len=1024;
- body_str.s=body_buf;
- body_str.len=1024;
-
- db_vals[0].type = DB1_INT;
- db_vals[0].nul = 0;
- db_vals[0].val.int_val = 0;
-
- db_vals[1].type = DB1_INT;
- db_vals[1].nul = 0;
- ttime = time(NULL);
- db_vals[1].val.int_val = (int)ttime;
-
- if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
- {
- LM_ERR("failed to use_table\n");
- return;
- }
- if (msilo_dbf.query(db_con,db_keys,db_ops,db_vals,db_cols,db_no_keys,
- db_no_cols, NULL,&db_res) < 0) {
- LM_ERR("failed to query database\n");
- goto done;
- }
- if (RES_ROW_N(db_res) <= 0)
- {
- LM_DBG("no message for <%.*s>!\n", 24, ctime((const time_t*)&ttime));
- goto done;
- }
-
- LM_DBG("dumping [%d] messages for <%.*s>!!!\n", RES_ROW_N(db_res), 24,
- ctime((const time_t*)&ttime));
- for(i = 0; i < RES_ROW_N(db_res); i++)
- {
- mid = RES_ROWS(db_res)[i].values[0].val.int_val;
- if(msg_list_check_msg(ml, mid))
- {
- LM_DBG("message[%d] mid=%d already sent.\n", i, mid);
- continue;
- }
-
- memset(str_vals, 0, 4*sizeof(str));
- SET_STR_VAL(str_vals[0], db_res, i, 1); /* user */
- SET_STR_VAL(str_vals[1], db_res, i, 2); /* host */
- SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */
- SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */
- extra_hdrs_str.len = 0;
- hdr_str.len = 1024;
- if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/,
- ms_reminder/*from*/,0/*Date*/,
- extra_hdrs_str/*extra*/)
- < 0)
- {
- LM_ERR("headers building failed [%d]\n", mid);
- if (msilo_dbf.free_result(db_con, db_res) < 0)
- LM_DBG("failed to free result of query\n");
- msg_list_set_flag(ml, mid, MS_MSG_ERRO);
- return;
- }
- puri.s = uri_buf;
- puri.len = 4 + str_vals[0].len + 1 + str_vals[1].len;
- memcpy(puri.s, "sip:", 4);
- memcpy(puri.s+4, str_vals[0].s, str_vals[0].len);
- puri.s[4+str_vals[0].len] = '@';
- memcpy(puri.s+4+str_vals[0].len+1, str_vals[1].s, str_vals[1].len);
-
- LM_DBG("msg [%d-%d] for: %.*s\n", i+1, mid, puri.len, puri.s);
-
- /** sending using TM function: t_uac */
- body_str.len = 1024;
- stime =
- (time_t)RES_ROWS(db_res)[i].values[5/*snd time*/].val.int_val;
- n = m_build_body(&body_str, 0, str_vals[2/*body*/], stime);
- if(n<0)
- LM_DBG("sending simple body\n");
- else
- LM_DBG("sending composed body\n");
-
- msg_list_set_flag(ml, mid, MS_MSG_TSND);
- memset(&uac_r, '\0', sizeof(uac_r));
- uac_r.method = &msg_type;
- uac_r.headers = &hdr_str;
- uac_r.body = (n<0)?&str_vals[2]:&body_str;
- uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
- uac_r.cb = m_tm_callback;
- uac_r.cbp = (void*)(long)mid;
- tmb.t_request(&uac_r, /* UAC Req */
- &puri, /* Request-URI */
- &puri, /* To */
- &ms_reminder, /* From */
- (ms_outbound_proxy.s)?&ms_outbound_proxy:0 /* ob uri */
- );
- }
- done:
- /**
- * Free the result because we don't need it anymore
- */
- if ((db_res != NULL) && msilo_dbf.free_result(db_con, db_res) < 0)
- LM_DBG("failed to free result of query\n");
- return;
- }
- int ms_reset_stime(int mid)
- {
- db_key_t db_keys[1];
- db_op_t db_ops[1];
- db_val_t db_vals[1];
- db_key_t db_cols[1];
- db_val_t db_cvals[1];
-
- db_keys[0]=&sc_mid;
- db_ops[0]=OP_EQ;
- db_vals[0].type = DB1_INT;
- db_vals[0].nul = 0;
- db_vals[0].val.int_val = mid;
-
- db_cols[0]=&sc_snd_time;
- db_cvals[0].type = DB1_INT;
- db_cvals[0].nul = 0;
- db_cvals[0].val.int_val = 0;
-
- LM_DBG("updating send time for [%d]!\n", mid);
-
- if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
- {
- LM_ERR("failed to use_table\n");
- return -1;
- }
- if(msilo_dbf.update(db_con,db_keys,db_ops,db_vals,db_cols,db_cvals,1,1)!=0)
- {
- LM_ERR("failed to make update for [%d]!\n", mid);
- return -1;
- }
- return 0;
- }
- /*
- * Check if REGISTER request has contacts that support MESSAGE method or
- * if MESSAGE method is listed in Allow header and contact does not have
- * methods parameter.
- */
- int check_message_support(struct sip_msg* msg)
- {
- contact_t* c;
- unsigned int allow_message = 0;
- unsigned int allow_hdr = 0;
- str *methods_body;
- unsigned int methods;
- int expires;
- int posexp = 0;
- /* Parse all headers in order to see all Allow headers */
- if (parse_headers(msg, HDR_EOH_F, 0) == -1)
- {
- LM_ERR("failed to parse headers\n");
- return -1;
- }
- if (parse_allow(msg) == 0)
- {
- allow_hdr = 1;
- allow_message = get_allow_methods(msg) & METHOD_MESSAGE;
- }
- LM_DBG("Allow message: %u\n", allow_message);
- if (!msg->contact)
- {
- LM_DBG("no Contact found\n");
- return -1;
- }
- if (parse_contact(msg->contact) < 0)
- {
- LM_ERR("failed to parse Contact HF\n");
- return -1;
- }
- if (((contact_body_t*)msg->contact->parsed)->star)
- {
- LM_DBG("* Contact found\n");
- return -1;
- }
- if (contact_iterator(&c, msg, 0) < 0)
- return -1;
- /*
- * Check contacts for MESSAGE method in methods parameter list
- * If contact does not have methods parameter, use Allow header methods,
- * if any. Stop if MESSAGE method is found.
- */
- while(c)
- {
- /* calculate expires */
- expires=1; /* 0 is explicitely set in hdr or param */
- if(c->expires==NULL || c->expires->body.len<=0)
- {
- if(msg->expires!=NULL && msg->expires->body.len>0)
- expires = atoi(msg->expires->body.s);
- } else {
- str2int(&c->expires->body, (unsigned int*)(&expires));
- }
- /* skip contacts with zero expires */
- if (expires > 0)
- {
- posexp = 1;
- if (c->methods)
- {
- methods_body = &(c->methods->body);
- if (parse_methods(methods_body, &methods) < 0)
- {
- LM_ERR("failed to parse contact methods\n");
- return -1;
- }
- if (methods & METHOD_MESSAGE)
- {
- LM_DBG("MESSAGE contact found\n");
- return 0;
- }
- } else {
- if (allow_message)
- {
- LM_DBG("MESSAGE found in Allow Header\n");
- return 0;
- }
- }
- }
- if (contact_iterator(&c, msg, c) < 0)
- {
- LM_DBG("MESSAGE contact not found\n");
- return -1;
- }
- }
- /* no positivie expires header */
- if(posexp==0)
- return -1;
- /* no Allow header and no methods in Contact => dump MESSAGEs */
- if(allow_hdr==0)
- return 0;
- return -1;
- }
|