msilo.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608
  1. /*
  2. * $Id$
  3. *
  4. * MSILO module
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of Kamailio, a free SIP server.
  9. *
  10. * Kamailio is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * Kamailio is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * History
  25. * -------
  26. *
  27. * 2003-01-23: switched from t_uac to t_uac_dlg (dcm)
  28. * 2003-02-28: protocolization of t_uac_dlg completed (jiri)
  29. * 2003-03-11: updated to the new module interface (andrei)
  30. * removed non-constant initializers to some strs (andrei)
  31. * 2003-03-16: flags parameter added (janakj)
  32. * 2003-04-05: default_uri #define used (jiri)
  33. * 2003-04-06: db_init removed from mod_init, will be called from child_init
  34. * now (janakj)
  35. * 2003-04-07: m_dump takes a parameter which sets the way the outgoing URI
  36. * is computed (dcm)
  37. * 2003-08-05 adapted to the new parse_content_type_hdr function (bogdan)
  38. * 2004-06-07 updated to the new DB api (andrei)
  39. * 2006-09-10 m_dump now checks if registering UA supports MESSAGE method (jh)
  40. * 2006-10-05 added max_messages module variable (jh)
  41. * 2011-10-19 added storage of extra SIP headers (hpw)
  42. * 2011-12-07 added storage of extra SIP headers from AVP (jh)
  43. */
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <stdlib.h>
  47. #include <sys/types.h>
  48. #include <sys/ipc.h>
  49. #include <unistd.h>
  50. #include <fcntl.h>
  51. #include <time.h>
  52. #include "../../sr_module.h"
  53. #include "../../dprint.h"
  54. #include "../../ut.h"
  55. #include "../../timer.h"
  56. #include "../../mem/shm_mem.h"
  57. #include "../../lib/srdb1/db.h"
  58. #include "../../parser/parse_from.h"
  59. #include "../../parser/parse_content.h"
  60. #include "../../parser/contact/parse_contact.h"
  61. #include "../../parser/parse_allow.h"
  62. #include "../../parser/parse_methods.h"
  63. #include "../../resolve.h"
  64. #include "../../usr_avp.h"
  65. #include "../../mod_fix.h"
  66. #include "../../modules/tm/tm_load.h"
  67. #include "ms_msg_list.h"
  68. #include "msfuncs.h"
  69. #include "api.h"
  70. #define MAX_DEL_KEYS 1
  71. #define NR_KEYS 11
  72. static str sc_mid = str_init("id"); /* 0 */
  73. static str sc_from = str_init("src_addr"); /* 1 */
  74. static str sc_to = str_init("dst_addr"); /* 2 */
  75. static str sc_uri_user = str_init("username"); /* 3 */
  76. static str sc_uri_host = str_init("domain"); /* 4 */
  77. static str sc_body = str_init("body"); /* 5 */
  78. static str sc_ctype = str_init("ctype"); /* 6 */
  79. static str sc_exp_time = str_init("exp_time"); /* 7 */
  80. static str sc_inc_time = str_init("inc_time"); /* 8 */
  81. static str sc_snd_time = str_init("snd_time"); /* 9 */
  82. static str sc_stored_hdrs = str_init("extra_hdrs"); /* 10 */
  83. #define SET_STR_VAL(_str, _res, _r, _c) \
  84. if (RES_ROWS(_res)[_r].values[_c].nul == 0) \
  85. { \
  86. switch(RES_ROWS(_res)[_r].values[_c].type) \
  87. { \
  88. case DB1_STRING: \
  89. (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.string_val; \
  90. (_str).len=strlen((_str).s); \
  91. break; \
  92. case DB1_STR: \
  93. (_str).len=RES_ROWS(_res)[_r].values[_c].val.str_val.len; \
  94. (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.str_val.s; \
  95. break; \
  96. case DB1_BLOB: \
  97. (_str).len=RES_ROWS(_res)[_r].values[_c].val.blob_val.len; \
  98. (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.blob_val.s; \
  99. break; \
  100. default: \
  101. (_str).len=0; \
  102. (_str).s=NULL; \
  103. } \
  104. }
  105. MODULE_VERSION
  106. #define S_TABLE_VERSION 7
  107. /** database connection */
  108. static db1_con_t *db_con = NULL;
  109. static db_func_t msilo_dbf;
  110. /** precessed msg list - used for dumping the messages */
  111. msg_list ml = NULL;
  112. /** TM bind */
  113. struct tm_binds tmb;
  114. /** parameters */
  115. static str ms_db_url = str_init(DEFAULT_DB_URL);
  116. static str ms_db_table = str_init("silo");
  117. str ms_reminder = {NULL, 0};
  118. str ms_outbound_proxy = {NULL, 0};
  119. char* ms_from = NULL; /*"sip:[email protected]";*/
  120. char* ms_contact = NULL; /*"Contact: <sip:[email protected]>\r\n";*/
  121. char* ms_extra_hdrs = NULL; /*"X-foo: bar\r\nX-bar: foo\r\n";*/
  122. char* ms_content_type = NULL; /*"Content-Type: text/plain\r\n";*/
  123. char* ms_offline_message = NULL; /*"<em>I'm offline.</em>"*/
  124. void** ms_from_sp = NULL;
  125. void** ms_contact_sp = NULL;
  126. void** ms_extra_hdrs_sp = NULL;
  127. void** ms_content_type_sp = NULL;
  128. void** ms_offline_message_sp = NULL;
  129. int ms_expire_time = 259200;
  130. int ms_check_time = 60;
  131. int ms_send_time = 0;
  132. int ms_clean_period = 10;
  133. int ms_use_contact = 1;
  134. int ms_add_date = 1;
  135. int ms_add_contact = 0;
  136. int ms_max_messages = 0;
  137. static str ms_snd_time_avp_param = {NULL, 0};
  138. int_str ms_snd_time_avp_name;
  139. unsigned short ms_snd_time_avp_type;
  140. static str ms_extra_hdrs_avp_param = {NULL, 0};
  141. int_str ms_extra_hdrs_avp_name;
  142. unsigned short ms_extra_hdrs_avp_type;
  143. str msg_type = str_init("MESSAGE");
  144. /** module functions */
  145. static int mod_init(void);
  146. static int child_init(int);
  147. static int m_store(struct sip_msg*, str*);
  148. static int m_dump(struct sip_msg*, str*);
  149. static int m_store_2(struct sip_msg*, char*, char*);
  150. static int m_dump_2(struct sip_msg*, char*, char*);
  151. static void destroy(void);
  152. static int bind_msilo(msilo_api_t* api);
  153. void m_clean_silo(unsigned int ticks, void *);
  154. void m_send_ontimer(unsigned int ticks, void *);
  155. int ms_reset_stime(int mid);
  156. int check_message_support(struct sip_msg* msg);
  157. /** TM callback function */
  158. static void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps);
  159. static cmd_export_t cmds[]={
  160. {"m_store", (cmd_function)m_store_2, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE},
  161. {"m_store", (cmd_function)m_store_2, 1, fixup_spve_null, 0,
  162. REQUEST_ROUTE | FAILURE_ROUTE},
  163. {"m_dump", (cmd_function)m_dump_2, 0, 0, 0, REQUEST_ROUTE},
  164. {"m_dump", (cmd_function)m_dump_2, 1, fixup_spve_null, 0,
  165. REQUEST_ROUTE},
  166. {"bind_msilo",(cmd_function)bind_msilo, 1, 0, 0, ANY_ROUTE},
  167. {0,0,0,0,0,0}
  168. };
  169. static param_export_t params[]={
  170. { "db_url", PARAM_STR, &ms_db_url },
  171. { "db_table", PARAM_STR, &ms_db_table },
  172. { "from_address", PARAM_STRING, &ms_from },
  173. { "contact_hdr", PARAM_STRING, &ms_contact },
  174. { "extra_hdrs", PARAM_STRING, &ms_extra_hdrs },
  175. { "content_type_hdr", PARAM_STRING, &ms_content_type },
  176. { "offline_message", PARAM_STRING, &ms_offline_message },
  177. { "reminder", PARAM_STR, &ms_reminder },
  178. { "outbound_proxy", PARAM_STR, &ms_outbound_proxy },
  179. { "expire_time", INT_PARAM, &ms_expire_time },
  180. { "check_time", INT_PARAM, &ms_check_time },
  181. { "send_time", INT_PARAM, &ms_send_time },
  182. { "clean_period", INT_PARAM, &ms_clean_period },
  183. { "use_contact", INT_PARAM, &ms_use_contact },
  184. { "sc_mid", PARAM_STR, &sc_mid },
  185. { "sc_from", PARAM_STR, &sc_from },
  186. { "sc_to", PARAM_STR, &sc_to },
  187. { "sc_uri_user", PARAM_STR, &sc_uri_user },
  188. { "sc_uri_host", PARAM_STR, &sc_uri_host },
  189. { "sc_body", PARAM_STR, &sc_body },
  190. { "sc_ctype", PARAM_STR, &sc_ctype },
  191. { "sc_exp_time", PARAM_STR, &sc_exp_time },
  192. { "sc_inc_time", PARAM_STR, &sc_inc_time },
  193. { "sc_snd_time", PARAM_STR, &sc_snd_time },
  194. { "sc_stored_hdrs", PARAM_STR, &sc_stored_hdrs },
  195. { "snd_time_avp", PARAM_STR, &ms_snd_time_avp_param },
  196. { "extra_hdrs_avp", PARAM_STR, &ms_extra_hdrs_avp_param },
  197. { "add_date", INT_PARAM, &ms_add_date },
  198. { "max_messages", INT_PARAM, &ms_max_messages },
  199. { "add_contact", INT_PARAM, &ms_add_contact },
  200. { 0,0,0 }
  201. };
  202. #ifdef STATISTICS
  203. #include "../../lib/kcore/statistics.h"
  204. stat_var* ms_stored_msgs;
  205. stat_var* ms_dumped_msgs;
  206. stat_var* ms_failed_msgs;
  207. stat_var* ms_dumped_rmds;
  208. stat_var* ms_failed_rmds;
  209. stat_export_t msilo_stats[] = {
  210. {"stored_messages" , 0, &ms_stored_msgs },
  211. {"dumped_messages" , 0, &ms_dumped_msgs },
  212. {"failed_messages" , 0, &ms_failed_msgs },
  213. {"dumped_reminders" , 0, &ms_dumped_rmds },
  214. {"failed_reminders" , 0, &ms_failed_rmds },
  215. {0,0,0}
  216. };
  217. #endif
  218. /** module exports */
  219. struct module_exports exports= {
  220. "msilo", /* module id */
  221. DEFAULT_DLFLAGS, /* dlopen flags */
  222. cmds, /* module's exported functions */
  223. params, /* module's exported parameters */
  224. #ifdef STATISTICS
  225. msilo_stats,
  226. #else
  227. 0, /* exported statistics */
  228. #endif
  229. 0, /* exported MI functions */
  230. 0, /* exported pseudo-variables */
  231. 0, /* extra processes */
  232. mod_init, /* module initialization function */
  233. 0, /* response handler */
  234. (destroy_function) destroy, /* module destroy function */
  235. child_init /* per-child init function */
  236. };
  237. static int bind_msilo(msilo_api_t* api)
  238. {
  239. if (!api) {
  240. return -1;
  241. }
  242. api->m_store = m_store;
  243. api->m_dump = m_dump;
  244. return 0;
  245. }
  246. /**
  247. * init module function
  248. */
  249. static int mod_init(void)
  250. {
  251. pv_spec_t avp_spec;
  252. #ifdef STATISTICS
  253. /* register statistics */
  254. if (register_module_stats( exports.name, msilo_stats)!=0 ) {
  255. LM_ERR("failed to register core statistics\n");
  256. return -1;
  257. }
  258. #endif
  259. /* binding to mysql module */
  260. if (db_bind_mod(&ms_db_url, &msilo_dbf))
  261. {
  262. LM_DBG("database module not found\n");
  263. return -1;
  264. }
  265. if (!DB_CAPABILITY(msilo_dbf, DB_CAP_ALL)) {
  266. LM_ERR("database module does not implement "
  267. "all functions needed by the module\n");
  268. return -1;
  269. }
  270. if (ms_snd_time_avp_param.s && ms_snd_time_avp_param.len > 0) {
  271. if (pv_parse_spec(&ms_snd_time_avp_param, &avp_spec)==0
  272. || avp_spec.type!=PVT_AVP) {
  273. LM_ERR("malformed or non AVP %.*s AVP definition\n",
  274. ms_snd_time_avp_param.len, ms_snd_time_avp_param.s);
  275. return -1;
  276. }
  277. if(pv_get_avp_name(0, &(avp_spec.pvp), &ms_snd_time_avp_name,
  278. &ms_snd_time_avp_type)!=0)
  279. {
  280. LM_ERR("[%.*s]- invalid AVP definition\n",
  281. ms_snd_time_avp_param.len, ms_snd_time_avp_param.s);
  282. return -1;
  283. }
  284. }
  285. if (ms_extra_hdrs_avp_param.s && ms_extra_hdrs_avp_param.len > 0) {
  286. if (pv_parse_spec(&ms_extra_hdrs_avp_param, &avp_spec)==0
  287. || avp_spec.type!=PVT_AVP) {
  288. LM_ERR("malformed or non AVP %.*s AVP definition\n",
  289. ms_extra_hdrs_avp_param.len, ms_extra_hdrs_avp_param.s);
  290. return -1;
  291. }
  292. if (pv_get_avp_name(0, &(avp_spec.pvp), &ms_extra_hdrs_avp_name,
  293. &ms_extra_hdrs_avp_type) != 0) {
  294. LM_ERR("[%.*s]- invalid AVP definition\n",
  295. ms_extra_hdrs_avp_param.len, ms_extra_hdrs_avp_param.s);
  296. return -1;
  297. }
  298. }
  299. db_con = msilo_dbf.init(&ms_db_url);
  300. if (!db_con)
  301. {
  302. LM_ERR("failed to connect to the database\n");
  303. return -1;
  304. }
  305. if(db_check_table_version(&msilo_dbf, db_con, &ms_db_table, S_TABLE_VERSION) < 0) {
  306. LM_ERR("error during table version check.\n");
  307. return -1;
  308. }
  309. if(db_con)
  310. msilo_dbf.close(db_con);
  311. db_con = NULL;
  312. /* load the TM API */
  313. if (load_tm_api(&tmb)!=0) {
  314. LM_ERR("can't load TM API\n");
  315. return -1;
  316. }
  317. if(ms_from!=NULL)
  318. {
  319. ms_from_sp = (void**)pkg_malloc(sizeof(void*));
  320. if(ms_from_sp==NULL)
  321. {
  322. LM_ERR("no more pkg\n");
  323. return -1;
  324. }
  325. *ms_from_sp = (void*)ms_from;
  326. if(fixup_spve_null(ms_from_sp, 1)!=0)
  327. {
  328. LM_ERR("bad contact parameter\n");
  329. return -1;
  330. }
  331. }
  332. if(ms_contact!=NULL)
  333. {
  334. ms_contact_sp = (void**)pkg_malloc(sizeof(void*));
  335. if(ms_contact_sp==NULL)
  336. {
  337. LM_ERR("no more pkg\n");
  338. return -1;
  339. }
  340. *ms_contact_sp = (void*)ms_contact;
  341. if(fixup_spve_null(ms_contact_sp, 1)!=0)
  342. {
  343. LM_ERR("bad contact parameter\n");
  344. return -1;
  345. }
  346. }
  347. if(ms_extra_hdrs!=NULL)
  348. {
  349. ms_extra_hdrs_sp = (void**)pkg_malloc(sizeof(void*));
  350. if(ms_extra_hdrs_sp==NULL)
  351. {
  352. LM_ERR("no more pkg\n");
  353. return -1;
  354. }
  355. *ms_extra_hdrs_sp = (void*)ms_extra_hdrs;
  356. if(fixup_spve_null(ms_extra_hdrs_sp, 1)!=0)
  357. {
  358. LM_ERR("bad extra_hdrs parameter\n");
  359. return -1;
  360. }
  361. }
  362. if(ms_content_type!=NULL)
  363. {
  364. ms_content_type_sp = (void**)pkg_malloc(sizeof(void*));
  365. if(ms_content_type_sp==NULL)
  366. {
  367. LM_ERR("no more pkg\n");
  368. return -1;
  369. }
  370. *ms_content_type_sp = (void*)ms_content_type;
  371. if(fixup_spve_null(ms_content_type_sp, 1)!=0)
  372. {
  373. LM_ERR("bad content_type parameter\n");
  374. return -1;
  375. }
  376. }
  377. if(ms_offline_message!=NULL)
  378. {
  379. ms_offline_message_sp = (void**)pkg_malloc(sizeof(void*));
  380. if(ms_offline_message_sp==NULL)
  381. {
  382. LM_ERR("no more pkg\n");
  383. return -1;
  384. }
  385. *ms_offline_message_sp = (void*)ms_offline_message;
  386. if(fixup_spve_null(ms_offline_message_sp, 1)!=0)
  387. {
  388. LM_ERR("bad offline_message parameter\n");
  389. return -1;
  390. }
  391. }
  392. if(ms_offline_message!=NULL && ms_content_type==NULL)
  393. {
  394. LM_ERR("content_type parameter must be set\n");
  395. return -1;
  396. }
  397. ml = msg_list_init();
  398. if(ml==NULL)
  399. {
  400. LM_ERR("can't initialize msg list\n");
  401. return -1;
  402. }
  403. if(ms_check_time<0)
  404. {
  405. LM_ERR("bad check time value\n");
  406. return -1;
  407. }
  408. register_timer(m_clean_silo, 0, ms_check_time);
  409. if(ms_send_time>0 && ms_reminder.s!=NULL)
  410. register_timer(m_send_ontimer, 0, ms_send_time);
  411. return 0;
  412. }
  413. /**
  414. * Initialize children
  415. */
  416. static int child_init(int rank)
  417. {
  418. if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
  419. return 0; /* do nothing for the main process */
  420. LM_DBG("rank #%d / pid <%d>\n", rank, getpid());
  421. if (msilo_dbf.init==0)
  422. {
  423. LM_CRIT("database not bound\n");
  424. return -1;
  425. }
  426. db_con = msilo_dbf.init(&ms_db_url);
  427. if (!db_con)
  428. {
  429. LM_ERR("child %d: failed to connect database\n", rank);
  430. return -1;
  431. }
  432. else
  433. {
  434. if (msilo_dbf.use_table(db_con, &ms_db_table) < 0) {
  435. LM_ERR("child %d: failed in use_table\n", rank);
  436. return -1;
  437. }
  438. LM_DBG("#%d database connection opened successfully\n", rank);
  439. }
  440. return 0;
  441. }
  442. /**
  443. * get_non_mandatory_headers
  444. * Extracts additional headers into the given buffer for storing alongside the message
  445. * returns the length of the created data
  446. *
  447. * It is assumed that all headers have been parsed at this point
  448. */
  449. static int get_non_mandatory_headers(struct sip_msg *msg, char *buf, int buf_len)
  450. {
  451. struct hdr_field *hdrs;
  452. int len = 0;
  453. int_str avp_value;
  454. struct usr_avp *avp;
  455. if (ms_extra_hdrs_avp_name.n != 0) {
  456. avp = NULL;
  457. avp = search_first_avp(ms_extra_hdrs_avp_type,
  458. ms_extra_hdrs_avp_name, &avp_value, 0);
  459. if ((avp != NULL) && is_avp_str_val(avp)) {
  460. if (buf_len <= avp_value.s.len) {
  461. LM_ERR("insufficient space to store headers in silo\n");
  462. return -1;
  463. }
  464. memcpy(buf, avp_value.s.s, avp_value.s.len);
  465. return avp_value.s.len;
  466. }
  467. }
  468. for (hdrs = msg->headers; hdrs != NULL; hdrs = hdrs->next)
  469. {
  470. switch (hdrs->type) {
  471. case HDR_OTHER_T:
  472. case HDR_PPI_T:
  473. case HDR_PAI_T:
  474. case HDR_PRIVACY_T:
  475. if (buf_len <= hdrs->len)
  476. {
  477. LM_ERR("Insufficient space to store headers in silo\n");
  478. return -1;
  479. }
  480. memcpy(buf, hdrs->name.s, hdrs->len);
  481. len += hdrs->len;
  482. buf += hdrs->len;
  483. buf_len -= hdrs->len;
  484. break;
  485. default:
  486. break;
  487. }
  488. }
  489. return len;
  490. }
  491. /**
  492. * store message
  493. * mode = "0" -- look for outgoing URI starting with new_uri
  494. * = "1" -- look for outgoing URI starting with r-uri
  495. * = "2" -- look for outgoing URI only at to header
  496. */
  497. static int m_store(struct sip_msg* msg, str *owner_s)
  498. {
  499. str body, str_hdr, ctaddr;
  500. struct to_body *pto, *pfrom;
  501. struct sip_uri puri;
  502. str duri;
  503. #define EXTRA_HDRS_BUF_LEN 1024
  504. static char extra_hdrs_buf[EXTRA_HDRS_BUF_LEN];
  505. str extra_hdrs;
  506. db_key_t db_keys[NR_KEYS-1];
  507. db_val_t db_vals[NR_KEYS-1];
  508. db_key_t db_cols[1];
  509. db1_res_t* res = NULL;
  510. uac_req_t uac_r;
  511. int nr_keys = 0, val, lexpire;
  512. content_type_t ctype;
  513. #define MS_BUF1_SIZE 1024
  514. static char ms_buf1[MS_BUF1_SIZE];
  515. int mime;
  516. str notify_from;
  517. str notify_body;
  518. str notify_ctype;
  519. str notify_contact;
  520. int_str avp_value;
  521. struct usr_avp *avp;
  522. LM_DBG("------------ start ------------\n");
  523. /* get message body - after that whole SIP MESSAGE is parsed */
  524. body.s = get_body( msg );
  525. if (body.s==0)
  526. {
  527. LM_ERR("cannot extract body from msg\n");
  528. goto error;
  529. }
  530. /* content-length (if present) must be already parsed */
  531. if (!msg->content_length)
  532. {
  533. LM_ERR("no Content-Length header found!\n");
  534. goto error;
  535. }
  536. body.len = get_content_length( msg );
  537. /* check if the body of message contains something */
  538. if(body.len <= 0)
  539. {
  540. LM_ERR("body of the message is empty!\n");
  541. goto error;
  542. }
  543. /* get TO URI */
  544. if(parse_to_header(msg)<0)
  545. {
  546. LM_ERR("failed getting 'to' header!\n");
  547. goto error;
  548. }
  549. pto = get_to(msg);
  550. /* get the owner */
  551. memset(&puri, 0, sizeof(struct sip_uri));
  552. if(owner_s != NULL)
  553. {
  554. if(parse_uri(owner_s->s, owner_s->len, &puri)!=0)
  555. {
  556. LM_ERR("bad owner SIP address!\n");
  557. goto error;
  558. } else {
  559. LM_DBG("using user id [%.*s]\n", owner_s->len, owner_s->s);
  560. }
  561. } else { /* get it from R-URI */
  562. if(msg->new_uri.len <= 0)
  563. {
  564. if(msg->first_line.u.request.uri.len <= 0)
  565. {
  566. LM_ERR("bad dst URI!\n");
  567. goto error;
  568. }
  569. duri = msg->first_line.u.request.uri;
  570. } else {
  571. duri = msg->new_uri;
  572. }
  573. LM_DBG("NEW R-URI found - check if is AoR!\n");
  574. if(parse_uri(duri.s, duri.len, &puri)!=0)
  575. {
  576. LM_ERR("bad dst R-URI!!\n");
  577. goto error;
  578. }
  579. }
  580. if(puri.user.len<=0)
  581. {
  582. LM_ERR("no username for owner\n");
  583. goto error;
  584. }
  585. db_keys[nr_keys] = &sc_uri_user;
  586. db_vals[nr_keys].type = DB1_STR;
  587. db_vals[nr_keys].nul = 0;
  588. db_vals[nr_keys].val.str_val.s = puri.user.s;
  589. db_vals[nr_keys].val.str_val.len = puri.user.len;
  590. nr_keys++;
  591. db_keys[nr_keys] = &sc_uri_host;
  592. db_vals[nr_keys].type = DB1_STR;
  593. db_vals[nr_keys].nul = 0;
  594. db_vals[nr_keys].val.str_val.s = puri.host.s;
  595. db_vals[nr_keys].val.str_val.len = puri.host.len;
  596. nr_keys++;
  597. if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
  598. {
  599. LM_ERR("failed to use_table\n");
  600. goto error;
  601. }
  602. if (ms_max_messages > 0) {
  603. db_cols[0] = &sc_inc_time;
  604. if (msilo_dbf.query(db_con, db_keys, 0, db_vals, db_cols,
  605. 2, 1, 0, &res) < 0 ) {
  606. LM_ERR("failed to query the database\n");
  607. return -1;
  608. }
  609. if (RES_ROW_N(res) >= ms_max_messages) {
  610. LM_ERR("too many messages for AoR '%.*s@%.*s'\n",
  611. puri.user.len, puri.user.s, puri.host.len, puri.host.s);
  612. msilo_dbf.free_result(db_con, res);
  613. return -1;
  614. }
  615. msilo_dbf.free_result(db_con, res);
  616. }
  617. /* Set To key */
  618. db_keys[nr_keys] = &sc_to;
  619. db_vals[nr_keys].type = DB1_STR;
  620. db_vals[nr_keys].nul = 0;
  621. db_vals[nr_keys].val.str_val.s = pto->uri.s;
  622. db_vals[nr_keys].val.str_val.len = pto->uri.len;
  623. nr_keys++;
  624. /* check FROM URI */
  625. if ( parse_from_header( msg )<0 )
  626. {
  627. LM_ERR("cannot parse From header\n");
  628. goto error;
  629. }
  630. pfrom = get_from(msg);
  631. LM_DBG("'From' header: <%.*s>\n", pfrom->uri.len, pfrom->uri.s);
  632. db_keys[nr_keys] = &sc_from;
  633. db_vals[nr_keys].type = DB1_STR;
  634. db_vals[nr_keys].nul = 0;
  635. db_vals[nr_keys].val.str_val.s = pfrom->uri.s;
  636. db_vals[nr_keys].val.str_val.len = pfrom->uri.len;
  637. nr_keys++;
  638. /* add the message's body in SQL query */
  639. db_keys[nr_keys] = &sc_body;
  640. db_vals[nr_keys].type = DB1_BLOB;
  641. db_vals[nr_keys].nul = 0;
  642. db_vals[nr_keys].val.blob_val.s = body.s;
  643. db_vals[nr_keys].val.blob_val.len = body.len;
  644. nr_keys++;
  645. lexpire = ms_expire_time;
  646. /* add 'content-type' -- parse the content-type header */
  647. if ((mime=parse_content_type_hdr(msg))<1 )
  648. {
  649. LM_ERR("cannot parse Content-Type header\n");
  650. goto error;
  651. }
  652. db_keys[nr_keys] = &sc_ctype;
  653. db_vals[nr_keys].type = DB1_STR;
  654. db_vals[nr_keys].nul = 0;
  655. db_vals[nr_keys].val.str_val.s = "text/plain";
  656. db_vals[nr_keys].val.str_val.len = 10;
  657. /** check the content-type value */
  658. if( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
  659. && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM )
  660. {
  661. if(m_extract_content_type(msg->content_type->body.s,
  662. msg->content_type->body.len, &ctype, CT_TYPE) != -1)
  663. {
  664. LM_DBG("'content-type' found\n");
  665. db_vals[nr_keys].val.str_val.s = ctype.type.s;
  666. db_vals[nr_keys].val.str_val.len = ctype.type.len;
  667. }
  668. }
  669. nr_keys++;
  670. /* check 'expires' -- no more parsing - already done by get_body() */
  671. if(msg->expires && msg->expires->body.len > 0)
  672. {
  673. LM_DBG("'expires' found\n");
  674. val = atoi(msg->expires->body.s);
  675. if(val > 0)
  676. lexpire = (ms_expire_time<=val)?ms_expire_time:val;
  677. }
  678. /* current time */
  679. val = (int)time(NULL);
  680. /* add expiration time */
  681. db_keys[nr_keys] = &sc_exp_time;
  682. db_vals[nr_keys].type = DB1_INT;
  683. db_vals[nr_keys].nul = 0;
  684. db_vals[nr_keys].val.int_val = val+lexpire;
  685. nr_keys++;
  686. /* add incoming time */
  687. db_keys[nr_keys] = &sc_inc_time;
  688. db_vals[nr_keys].type = DB1_INT;
  689. db_vals[nr_keys].nul = 0;
  690. db_vals[nr_keys].val.int_val = val;
  691. nr_keys++;
  692. /* add sending time */
  693. db_keys[nr_keys] = &sc_snd_time;
  694. db_vals[nr_keys].type = DB1_INT;
  695. db_vals[nr_keys].nul = 0;
  696. db_vals[nr_keys].val.int_val = 0;
  697. if(ms_snd_time_avp_name.n!=0)
  698. {
  699. avp = NULL;
  700. avp=search_first_avp(ms_snd_time_avp_type, ms_snd_time_avp_name,
  701. &avp_value, 0);
  702. if(avp!=NULL && is_avp_str_val(avp))
  703. {
  704. if(ms_extract_time(&avp_value.s, &db_vals[nr_keys].val.int_val)!=0)
  705. db_vals[nr_keys].val.int_val = 0;
  706. }
  707. }
  708. nr_keys++;
  709. /* add the extra headers in SQL query */
  710. extra_hdrs.s = extra_hdrs_buf;
  711. extra_hdrs.len = get_non_mandatory_headers(msg, extra_hdrs_buf, EXTRA_HDRS_BUF_LEN);
  712. if (extra_hdrs.len < 0)
  713. {
  714. goto error;
  715. }
  716. db_keys[nr_keys] = &sc_stored_hdrs;
  717. db_vals[nr_keys].type = DB1_BLOB;
  718. db_vals[nr_keys].nul = 0;
  719. db_vals[nr_keys].val.blob_val.s = extra_hdrs.s;
  720. db_vals[nr_keys].val.blob_val.len = extra_hdrs.len;
  721. nr_keys++;
  722. if(msilo_dbf.insert(db_con, db_keys, db_vals, nr_keys) < 0)
  723. {
  724. LM_ERR("failed to store message\n");
  725. goto error;
  726. }
  727. LM_DBG("message stored. T:<%.*s> F:<%.*s>\n",
  728. pto->uri.len, pto->uri.s, pfrom->uri.len, pfrom->uri.s);
  729. #ifdef STATISTICS
  730. update_stat(ms_stored_msgs, 1);
  731. #endif
  732. if(ms_from==NULL || ms_offline_message == NULL)
  733. goto done;
  734. LM_DBG("sending info message.\n");
  735. if(fixup_get_svalue(msg, (gparam_p)*ms_from_sp, &notify_from)!=0
  736. || notify_from.len<=0)
  737. {
  738. LM_WARN("cannot get notification From address\n");
  739. goto done;
  740. }
  741. if(fixup_get_svalue(msg, (gparam_p)*ms_offline_message_sp, &notify_body)!=0
  742. || notify_body.len<=0)
  743. {
  744. LM_WARN("cannot get notification body\n");
  745. goto done;
  746. }
  747. if(fixup_get_svalue(msg, (gparam_p)*ms_content_type_sp, &notify_ctype)!=0
  748. || notify_ctype.len<=0)
  749. {
  750. LM_WARN("cannot get notification content type\n");
  751. goto done;
  752. }
  753. if(ms_contact!=NULL && fixup_get_svalue(msg, (gparam_p)*ms_contact_sp,
  754. &notify_contact)==0 && notify_contact.len>0)
  755. {
  756. if(notify_contact.len+notify_ctype.len>=MS_BUF1_SIZE)
  757. {
  758. LM_WARN("insufficient buffer to build notification headers\n");
  759. goto done;
  760. }
  761. memcpy(ms_buf1, notify_contact.s, notify_contact.len);
  762. memcpy(ms_buf1+notify_contact.len, notify_ctype.s, notify_ctype.len);
  763. str_hdr.s = ms_buf1;
  764. str_hdr.len = notify_contact.len + notify_ctype.len;
  765. } else {
  766. str_hdr = notify_ctype;
  767. }
  768. /* look for Contact header -- must be parsed by now*/
  769. ctaddr.s = NULL;
  770. if(ms_use_contact && msg->contact!=NULL && msg->contact->body.s!=NULL
  771. && msg->contact->body.len > 0)
  772. {
  773. LM_DBG("contact header found\n");
  774. if((msg->contact->parsed!=NULL
  775. && ((contact_body_t*)(msg->contact->parsed))->contacts!=NULL)
  776. || (parse_contact(msg->contact)==0
  777. && msg->contact->parsed!=NULL
  778. && ((contact_body_t*)(msg->contact->parsed))->contacts!=NULL))
  779. {
  780. LM_DBG("using contact header for info msg\n");
  781. ctaddr.s =
  782. ((contact_body_t*)(msg->contact->parsed))->contacts->uri.s;
  783. ctaddr.len =
  784. ((contact_body_t*)(msg->contact->parsed))->contacts->uri.len;
  785. if(!ctaddr.s || ctaddr.len < 6 || strncmp(ctaddr.s, "sip:", 4)
  786. || ctaddr.s[4]==' ')
  787. ctaddr.s = NULL;
  788. else
  789. LM_DBG("feedback contact [%.*s]\n", ctaddr.len,ctaddr.s);
  790. }
  791. }
  792. memset(&uac_r,'\0', sizeof(uac_r));
  793. uac_r.method = &msg_type;
  794. uac_r.headers = &str_hdr;
  795. uac_r.body = &notify_body;
  796. tmb.t_request(&uac_r, /* UAC Req */
  797. (ctaddr.s)?&ctaddr:&pfrom->uri, /* Request-URI */
  798. &pfrom->uri, /* To */
  799. &notify_from, /* From */
  800. (ms_outbound_proxy.s)?&ms_outbound_proxy:0 /* outbound uri */
  801. );
  802. done:
  803. return 1;
  804. error:
  805. return -1;
  806. }
  807. /**
  808. * store message
  809. */
  810. static int m_store_2(struct sip_msg* msg, char* owner, char* s2)
  811. {
  812. str owner_s;
  813. if (owner != NULL)
  814. {
  815. if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
  816. {
  817. LM_ERR("invalid owner uri parameter");
  818. return -1;
  819. }
  820. return m_store(msg, &owner_s);
  821. }
  822. return m_store(msg, NULL);
  823. }
  824. /**
  825. * dump message
  826. */
  827. static int m_dump(struct sip_msg* msg, str* owner_s)
  828. {
  829. struct to_body *pto = NULL;
  830. db_key_t db_keys[3];
  831. db_key_t ob_key;
  832. db_op_t db_ops[3];
  833. db_val_t db_vals[3];
  834. db_key_t db_cols[7];
  835. db1_res_t* db_res = NULL;
  836. int i, db_no_cols = 7, db_no_keys = 3, mid, n;
  837. static char hdr_buf[1024];
  838. static char body_buf[1024];
  839. struct sip_uri puri;
  840. uac_req_t uac_r;
  841. str str_vals[5], hdr_str, body_str, extra_hdrs_str, tmp_extra_hdrs;
  842. time_t rtime;
  843. /* init */
  844. ob_key = &sc_mid;
  845. db_keys[0]=&sc_uri_user;
  846. db_keys[1]=&sc_uri_host;
  847. db_keys[2]=&sc_snd_time;
  848. db_ops[0]=OP_EQ;
  849. db_ops[1]=OP_EQ;
  850. db_ops[2]=OP_EQ;
  851. db_cols[0]=&sc_mid;
  852. db_cols[1]=&sc_from;
  853. db_cols[2]=&sc_to;
  854. db_cols[3]=&sc_body;
  855. db_cols[4]=&sc_ctype;
  856. db_cols[5]=&sc_inc_time;
  857. db_cols[6]=&sc_stored_hdrs;
  858. LM_DBG("------------ start ------------\n");
  859. hdr_str.s=hdr_buf;
  860. hdr_str.len=1024;
  861. body_str.s=body_buf;
  862. body_str.len=1024;
  863. /* check for TO header */
  864. if(parse_to_header(msg)<0)
  865. {
  866. LM_ERR("failed parsing To header\n");
  867. goto error;
  868. }
  869. pto = get_to(msg);
  870. /**
  871. * check if has expires=0 (REGISTER)
  872. */
  873. if(msg->first_line.u.request.method_value==METHOD_REGISTER)
  874. {
  875. if (check_message_support(msg)!=0) {
  876. LM_DBG("MESSAGE method not supported\n");
  877. return -1;
  878. }
  879. }
  880. /* get the owner */
  881. memset(&puri, 0, sizeof(struct sip_uri));
  882. if(owner_s)
  883. {
  884. if(parse_uri(owner_s->s, owner_s->len, &puri)!=0)
  885. {
  886. LM_ERR("bad owner SIP address!\n");
  887. goto error;
  888. } else {
  889. LM_DBG("using user id [%.*s]\n", owner_s->len, owner_s->s);
  890. }
  891. } else { /* get it from To URI */
  892. if(parse_uri(pto->uri.s, pto->uri.len, &puri)!=0)
  893. {
  894. LM_ERR("bad owner To URI!\n");
  895. goto error;
  896. }
  897. }
  898. if(puri.user.len<=0 || puri.user.s==NULL
  899. || puri.host.len<=0 || puri.host.s==NULL)
  900. {
  901. LM_ERR("bad owner URI!\n");
  902. goto error;
  903. }
  904. db_vals[0].type = DB1_STR;
  905. db_vals[0].nul = 0;
  906. db_vals[0].val.str_val.s = puri.user.s;
  907. db_vals[0].val.str_val.len = puri.user.len;
  908. db_vals[1].type = DB1_STR;
  909. db_vals[1].nul = 0;
  910. db_vals[1].val.str_val.s = puri.host.s;
  911. db_vals[1].val.str_val.len = puri.host.len;
  912. db_vals[2].type = DB1_INT;
  913. db_vals[2].nul = 0;
  914. db_vals[2].val.int_val = 0;
  915. if (db_con == NULL) {
  916. LM_ERR("database connection has not been established\n");
  917. goto error;
  918. }
  919. if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
  920. {
  921. LM_ERR("failed to use_table\n");
  922. return -1;
  923. }
  924. if (msilo_dbf.query(db_con,db_keys,db_ops,db_vals,db_cols,db_no_keys,
  925. db_no_cols, ob_key, &db_res) < 0) {
  926. LM_ERR("failed to query database\n");
  927. goto error;
  928. }
  929. if (RES_ROW_N(db_res) <= 0) {
  930. LM_DBG("no stored message for <%.*s>!\n", pto->uri.len, pto->uri.s);
  931. goto done;
  932. }
  933. LM_DBG("dumping [%d] messages for <%.*s>!!!\n",
  934. RES_ROW_N(db_res), pto->uri.len, pto->uri.s);
  935. for(i = 0; i < RES_ROW_N(db_res); i++)
  936. {
  937. mid = RES_ROWS(db_res)[i].values[0].val.int_val;
  938. if(msg_list_check_msg(ml, mid))
  939. {
  940. LM_DBG("message[%d] mid=%d already sent.\n", i, mid);
  941. continue;
  942. }
  943. memset(str_vals, 0, 5*sizeof(str));
  944. SET_STR_VAL(str_vals[0], db_res, i, 1); /* from */
  945. SET_STR_VAL(str_vals[1], db_res, i, 2); /* to */
  946. SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */
  947. SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */
  948. SET_STR_VAL(str_vals[4], db_res, i, 6); /* stored hdrs */
  949. rtime =
  950. (time_t)RES_ROWS(db_res)[i].values[5/*inc time*/].val.int_val;
  951. if (ms_extra_hdrs != NULL) {
  952. if (fixup_get_svalue(msg, (gparam_p)*ms_extra_hdrs_sp,
  953. &extra_hdrs_str) != 0) {
  954. if (msilo_dbf.free_result(db_con, db_res) < 0)
  955. LM_ERR("failed to free the query result\n");
  956. LM_ERR("unable to get extra_hdrs value\n");
  957. goto error;
  958. }
  959. } else {
  960. extra_hdrs_str.len = 0;
  961. }
  962. tmp_extra_hdrs.len = extra_hdrs_str.len+str_vals[4].len;
  963. if(tmp_extra_hdrs.len>0)
  964. {
  965. if ((tmp_extra_hdrs.s = pkg_malloc(tmp_extra_hdrs.len)) == NULL)
  966. {
  967. LM_ERR("Out of pkg memory");
  968. if (msilo_dbf.free_result(db_con, db_res) < 0)
  969. LM_ERR("failed to free the query result\n");
  970. msg_list_set_flag(ml, mid, MS_MSG_ERRO);
  971. goto error;
  972. }
  973. if(extra_hdrs_str.len>0)
  974. memcpy(tmp_extra_hdrs.s, extra_hdrs_str.s, extra_hdrs_str.len);
  975. memcpy(tmp_extra_hdrs.s+extra_hdrs_str.len, str_vals[4].s, str_vals[4].len);
  976. } else {
  977. tmp_extra_hdrs.len = 0;
  978. tmp_extra_hdrs.s = "";
  979. }
  980. hdr_str.len = 1024;
  981. if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/,
  982. str_vals[0]/*from*/, rtime /*Date*/,
  983. tmp_extra_hdrs /*extra_hdrs*/) < 0)
  984. {
  985. LM_ERR("headers building failed [%d]\n", mid);
  986. if(tmp_extra_hdrs.len>0)
  987. pkg_free(tmp_extra_hdrs.s);
  988. if (msilo_dbf.free_result(db_con, db_res) < 0)
  989. LM_ERR("failed to free the query result\n");
  990. msg_list_set_flag(ml, mid, MS_MSG_ERRO);
  991. goto error;
  992. }
  993. if(tmp_extra_hdrs.len>0)
  994. pkg_free(tmp_extra_hdrs.s);
  995. LM_DBG("msg [%d-%d] for: %.*s\n", i+1, mid, pto->uri.len, pto->uri.s);
  996. /** sending using TM function: t_uac */
  997. body_str.len = 1024;
  998. /* send composed body only if content type is text/plain */
  999. if ((str_vals[3].len == 10) &&
  1000. (strncmp(str_vals[3].s, "text/plain", 10) == 0)) {
  1001. n = m_build_body(&body_str, rtime, str_vals[2/*body*/], 0);
  1002. } else {
  1003. n = -1;
  1004. }
  1005. if(n<0)
  1006. LM_DBG("sending simple body\n");
  1007. else
  1008. LM_DBG("sending composed body\n");
  1009. memset(&uac_r,'\0', sizeof(uac_r));
  1010. uac_r.method = &msg_type;
  1011. uac_r.headers = &hdr_str;
  1012. uac_r.body = (n<0)?&str_vals[2]:&body_str;
  1013. uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
  1014. uac_r.cb = m_tm_callback;
  1015. uac_r.cbp = (void*)(long)mid;
  1016. tmb.t_request(&uac_r, /* UAC Req */
  1017. &str_vals[1], /* Request-URI */
  1018. &str_vals[1], /* To */
  1019. &str_vals[0], /* From */
  1020. (ms_outbound_proxy.s)?&ms_outbound_proxy:0 /* ob uri */
  1021. );
  1022. }
  1023. done:
  1024. /**
  1025. * Free the result because we don't need it
  1026. * anymore
  1027. */
  1028. if ((db_res !=NULL) && msilo_dbf.free_result(db_con, db_res) < 0)
  1029. LM_ERR("failed to free result of query\n");
  1030. return 1;
  1031. error:
  1032. return -1;
  1033. }
  1034. /**
  1035. * dump message
  1036. */
  1037. static int m_dump_2(struct sip_msg* msg, char* owner, char* s2)
  1038. {
  1039. str owner_s;
  1040. if (owner != NULL)
  1041. {
  1042. if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
  1043. {
  1044. LM_ERR("invalid owner uri parameter");
  1045. return -1;
  1046. }
  1047. return m_dump(msg, &owner_s);
  1048. }
  1049. return m_dump(msg, NULL);
  1050. }
  1051. /**
  1052. * - cleaning up the messages that got reply
  1053. * - delete expired messages from database
  1054. */
  1055. void m_clean_silo(unsigned int ticks, void *param)
  1056. {
  1057. msg_list_el mle = NULL, p;
  1058. db_key_t db_keys[MAX_DEL_KEYS];
  1059. db_val_t db_vals[MAX_DEL_KEYS];
  1060. db_op_t db_ops[1] = { OP_LEQ };
  1061. int n;
  1062. LM_DBG("cleaning stored messages - %d\n", ticks);
  1063. msg_list_check(ml);
  1064. mle = p = msg_list_reset(ml);
  1065. n = 0;
  1066. if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
  1067. {
  1068. LM_ERR("failed to use_table\n");
  1069. return;
  1070. }
  1071. while(p)
  1072. {
  1073. if(p->flag & MS_MSG_DONE)
  1074. {
  1075. #ifdef STATISTICS
  1076. if(p->flag & MS_MSG_TSND)
  1077. update_stat(ms_dumped_msgs, 1);
  1078. else
  1079. update_stat(ms_dumped_rmds, 1);
  1080. #endif
  1081. db_keys[n] = &sc_mid;
  1082. db_vals[n].type = DB1_INT;
  1083. db_vals[n].nul = 0;
  1084. db_vals[n].val.int_val = p->msgid;
  1085. LM_DBG("cleaning sent message [%d]\n", p->msgid);
  1086. n++;
  1087. if(n==MAX_DEL_KEYS)
  1088. {
  1089. if (msilo_dbf.delete(db_con, db_keys, NULL, db_vals, n) < 0)
  1090. LM_ERR("failed to clean %d messages.\n",n);
  1091. n = 0;
  1092. }
  1093. }
  1094. if((p->flag & MS_MSG_ERRO) && (p->flag & MS_MSG_TSND))
  1095. { /* set snd time to 0 */
  1096. ms_reset_stime(p->msgid);
  1097. #ifdef STATISTICS
  1098. update_stat(ms_failed_rmds, 1);
  1099. #endif
  1100. }
  1101. #ifdef STATISTICS
  1102. if((p->flag & MS_MSG_ERRO) && !(p->flag & MS_MSG_TSND))
  1103. update_stat(ms_failed_msgs, 1);
  1104. #endif
  1105. p = p->next;
  1106. }
  1107. if(n>0)
  1108. {
  1109. if (msilo_dbf.delete(db_con, db_keys, NULL, db_vals, n) < 0)
  1110. LM_ERR("failed to clean %d messages\n", n);
  1111. n = 0;
  1112. }
  1113. msg_list_el_free_all(mle);
  1114. /* cleaning expired messages */
  1115. if(ticks%(ms_check_time*ms_clean_period)<ms_check_time)
  1116. {
  1117. LM_DBG("cleaning expired messages\n");
  1118. db_keys[0] = &sc_exp_time;
  1119. db_vals[0].type = DB1_INT;
  1120. db_vals[0].nul = 0;
  1121. db_vals[0].val.int_val = (int)time(NULL);
  1122. if (msilo_dbf.delete(db_con, db_keys, db_ops, db_vals, 1) < 0)
  1123. LM_DBG("ERROR cleaning expired messages\n");
  1124. }
  1125. }
  1126. /**
  1127. * destroy function
  1128. */
  1129. static void destroy(void)
  1130. {
  1131. msg_list_free(ml);
  1132. if(db_con && msilo_dbf.close)
  1133. msilo_dbf.close(db_con);
  1134. }
  1135. /**
  1136. * TM callback function - delete message from database if was sent OK
  1137. */
  1138. void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps)
  1139. {
  1140. if(ps->param==NULL || *ps->param==0)
  1141. {
  1142. LM_DBG("message id not received\n");
  1143. goto done;
  1144. }
  1145. LM_DBG("completed with status %d [mid: %ld/%d]\n",
  1146. ps->code, (long)ps->param, *((int*)ps->param));
  1147. if(!db_con)
  1148. {
  1149. LM_ERR("db_con is NULL\n");
  1150. goto done;
  1151. }
  1152. if(ps->code >= 300)
  1153. {
  1154. LM_DBG("message <%d> was not sent successfully\n", *((int*)ps->param));
  1155. msg_list_set_flag(ml, *((int*)ps->param), MS_MSG_ERRO);
  1156. goto done;
  1157. }
  1158. LM_DBG("message <%d> was sent successfully\n", *((int*)ps->param));
  1159. msg_list_set_flag(ml, *((int*)ps->param), MS_MSG_DONE);
  1160. done:
  1161. return;
  1162. }
  1163. void m_send_ontimer(unsigned int ticks, void *param)
  1164. {
  1165. db_key_t db_keys[2];
  1166. db_op_t db_ops[2];
  1167. db_val_t db_vals[2];
  1168. db_key_t db_cols[6];
  1169. db1_res_t* db_res = NULL;
  1170. int i, db_no_cols = 6, db_no_keys = 2, mid, n;
  1171. static char hdr_buf[1024];
  1172. static char uri_buf[1024];
  1173. static char body_buf[1024];
  1174. str puri;
  1175. time_t ttime;
  1176. uac_req_t uac_r;
  1177. str str_vals[4], hdr_str, body_str;
  1178. str extra_hdrs_str = {0};
  1179. time_t stime;
  1180. if(ms_reminder.s==NULL)
  1181. {
  1182. LM_WARN("reminder address null\n");
  1183. return;
  1184. }
  1185. /* init */
  1186. db_keys[0]=&sc_snd_time;
  1187. db_keys[1]=&sc_snd_time;
  1188. db_ops[0]=OP_NEQ;
  1189. db_ops[1]=OP_LEQ;
  1190. db_cols[0]=&sc_mid;
  1191. db_cols[1]=&sc_uri_user;
  1192. db_cols[2]=&sc_uri_host;
  1193. db_cols[3]=&sc_body;
  1194. db_cols[4]=&sc_ctype;
  1195. db_cols[5]=&sc_snd_time;
  1196. LM_DBG("------------ start ------------\n");
  1197. hdr_str.s=hdr_buf;
  1198. hdr_str.len=1024;
  1199. body_str.s=body_buf;
  1200. body_str.len=1024;
  1201. db_vals[0].type = DB1_INT;
  1202. db_vals[0].nul = 0;
  1203. db_vals[0].val.int_val = 0;
  1204. db_vals[1].type = DB1_INT;
  1205. db_vals[1].nul = 0;
  1206. ttime = time(NULL);
  1207. db_vals[1].val.int_val = (int)ttime;
  1208. if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
  1209. {
  1210. LM_ERR("failed to use_table\n");
  1211. return;
  1212. }
  1213. if (msilo_dbf.query(db_con,db_keys,db_ops,db_vals,db_cols,db_no_keys,
  1214. db_no_cols, NULL,&db_res) < 0) {
  1215. LM_ERR("failed to query database\n");
  1216. goto done;
  1217. }
  1218. if (RES_ROW_N(db_res) <= 0)
  1219. {
  1220. LM_DBG("no message for <%.*s>!\n", 24, ctime((const time_t*)&ttime));
  1221. goto done;
  1222. }
  1223. LM_DBG("dumping [%d] messages for <%.*s>!!!\n", RES_ROW_N(db_res), 24,
  1224. ctime((const time_t*)&ttime));
  1225. for(i = 0; i < RES_ROW_N(db_res); i++)
  1226. {
  1227. mid = RES_ROWS(db_res)[i].values[0].val.int_val;
  1228. if(msg_list_check_msg(ml, mid))
  1229. {
  1230. LM_DBG("message[%d] mid=%d already sent.\n", i, mid);
  1231. continue;
  1232. }
  1233. memset(str_vals, 0, 4*sizeof(str));
  1234. SET_STR_VAL(str_vals[0], db_res, i, 1); /* user */
  1235. SET_STR_VAL(str_vals[1], db_res, i, 2); /* host */
  1236. SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */
  1237. SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */
  1238. extra_hdrs_str.len = 0;
  1239. hdr_str.len = 1024;
  1240. if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/,
  1241. ms_reminder/*from*/,0/*Date*/,
  1242. extra_hdrs_str/*extra*/)
  1243. < 0)
  1244. {
  1245. LM_ERR("headers building failed [%d]\n", mid);
  1246. if (msilo_dbf.free_result(db_con, db_res) < 0)
  1247. LM_DBG("failed to free result of query\n");
  1248. msg_list_set_flag(ml, mid, MS_MSG_ERRO);
  1249. return;
  1250. }
  1251. puri.s = uri_buf;
  1252. puri.len = 4 + str_vals[0].len + 1 + str_vals[1].len;
  1253. memcpy(puri.s, "sip:", 4);
  1254. memcpy(puri.s+4, str_vals[0].s, str_vals[0].len);
  1255. puri.s[4+str_vals[0].len] = '@';
  1256. memcpy(puri.s+4+str_vals[0].len+1, str_vals[1].s, str_vals[1].len);
  1257. LM_DBG("msg [%d-%d] for: %.*s\n", i+1, mid, puri.len, puri.s);
  1258. /** sending using TM function: t_uac */
  1259. body_str.len = 1024;
  1260. stime =
  1261. (time_t)RES_ROWS(db_res)[i].values[5/*snd time*/].val.int_val;
  1262. n = m_build_body(&body_str, 0, str_vals[2/*body*/], stime);
  1263. if(n<0)
  1264. LM_DBG("sending simple body\n");
  1265. else
  1266. LM_DBG("sending composed body\n");
  1267. msg_list_set_flag(ml, mid, MS_MSG_TSND);
  1268. memset(&uac_r, '\0', sizeof(uac_r));
  1269. uac_r.method = &msg_type;
  1270. uac_r.headers = &hdr_str;
  1271. uac_r.body = (n<0)?&str_vals[2]:&body_str;
  1272. uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
  1273. uac_r.cb = m_tm_callback;
  1274. uac_r.cbp = (void*)(long)mid;
  1275. tmb.t_request(&uac_r, /* UAC Req */
  1276. &puri, /* Request-URI */
  1277. &puri, /* To */
  1278. &ms_reminder, /* From */
  1279. (ms_outbound_proxy.s)?&ms_outbound_proxy:0 /* ob uri */
  1280. );
  1281. }
  1282. done:
  1283. /**
  1284. * Free the result because we don't need it anymore
  1285. */
  1286. if ((db_res != NULL) && msilo_dbf.free_result(db_con, db_res) < 0)
  1287. LM_DBG("failed to free result of query\n");
  1288. return;
  1289. }
  1290. int ms_reset_stime(int mid)
  1291. {
  1292. db_key_t db_keys[1];
  1293. db_op_t db_ops[1];
  1294. db_val_t db_vals[1];
  1295. db_key_t db_cols[1];
  1296. db_val_t db_cvals[1];
  1297. db_keys[0]=&sc_mid;
  1298. db_ops[0]=OP_EQ;
  1299. db_vals[0].type = DB1_INT;
  1300. db_vals[0].nul = 0;
  1301. db_vals[0].val.int_val = mid;
  1302. db_cols[0]=&sc_snd_time;
  1303. db_cvals[0].type = DB1_INT;
  1304. db_cvals[0].nul = 0;
  1305. db_cvals[0].val.int_val = 0;
  1306. LM_DBG("updating send time for [%d]!\n", mid);
  1307. if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
  1308. {
  1309. LM_ERR("failed to use_table\n");
  1310. return -1;
  1311. }
  1312. if(msilo_dbf.update(db_con,db_keys,db_ops,db_vals,db_cols,db_cvals,1,1)!=0)
  1313. {
  1314. LM_ERR("failed to make update for [%d]!\n", mid);
  1315. return -1;
  1316. }
  1317. return 0;
  1318. }
  1319. /*
  1320. * Check if REGISTER request has contacts that support MESSAGE method or
  1321. * if MESSAGE method is listed in Allow header and contact does not have
  1322. * methods parameter.
  1323. */
  1324. int check_message_support(struct sip_msg* msg)
  1325. {
  1326. contact_t* c;
  1327. unsigned int allow_message = 0;
  1328. unsigned int allow_hdr = 0;
  1329. str *methods_body;
  1330. unsigned int methods;
  1331. int expires;
  1332. int posexp = 0;
  1333. /* Parse all headers in order to see all Allow headers */
  1334. if (parse_headers(msg, HDR_EOH_F, 0) == -1)
  1335. {
  1336. LM_ERR("failed to parse headers\n");
  1337. return -1;
  1338. }
  1339. if (parse_allow(msg) == 0)
  1340. {
  1341. allow_hdr = 1;
  1342. allow_message = get_allow_methods(msg) & METHOD_MESSAGE;
  1343. }
  1344. LM_DBG("Allow message: %u\n", allow_message);
  1345. if (!msg->contact)
  1346. {
  1347. LM_DBG("no Contact found\n");
  1348. return -1;
  1349. }
  1350. if (parse_contact(msg->contact) < 0)
  1351. {
  1352. LM_ERR("failed to parse Contact HF\n");
  1353. return -1;
  1354. }
  1355. if (((contact_body_t*)msg->contact->parsed)->star)
  1356. {
  1357. LM_DBG("* Contact found\n");
  1358. return -1;
  1359. }
  1360. if (contact_iterator(&c, msg, 0) < 0)
  1361. return -1;
  1362. /*
  1363. * Check contacts for MESSAGE method in methods parameter list
  1364. * If contact does not have methods parameter, use Allow header methods,
  1365. * if any. Stop if MESSAGE method is found.
  1366. */
  1367. while(c)
  1368. {
  1369. /* calculate expires */
  1370. expires=1; /* 0 is explicitely set in hdr or param */
  1371. if(c->expires==NULL || c->expires->body.len<=0)
  1372. {
  1373. if(msg->expires!=NULL && msg->expires->body.len>0)
  1374. expires = atoi(msg->expires->body.s);
  1375. } else {
  1376. str2int(&c->expires->body, (unsigned int*)(&expires));
  1377. }
  1378. /* skip contacts with zero expires */
  1379. if (expires > 0)
  1380. {
  1381. posexp = 1;
  1382. if (c->methods)
  1383. {
  1384. methods_body = &(c->methods->body);
  1385. if (parse_methods(methods_body, &methods) < 0)
  1386. {
  1387. LM_ERR("failed to parse contact methods\n");
  1388. return -1;
  1389. }
  1390. if (methods & METHOD_MESSAGE)
  1391. {
  1392. LM_DBG("MESSAGE contact found\n");
  1393. return 0;
  1394. }
  1395. } else {
  1396. if (allow_message)
  1397. {
  1398. LM_DBG("MESSAGE found in Allow Header\n");
  1399. return 0;
  1400. }
  1401. }
  1402. }
  1403. if (contact_iterator(&c, msg, c) < 0)
  1404. {
  1405. LM_DBG("MESSAGE contact not found\n");
  1406. return -1;
  1407. }
  1408. }
  1409. /* no positivie expires header */
  1410. if(posexp==0)
  1411. return -1;
  1412. /* no Allow header and no methods in Contact => dump MESSAGEs */
  1413. if(allow_hdr==0)
  1414. return 0;
  1415. return -1;
  1416. }