00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <stdio.h>
00046 #include <string.h>
00047 #include <stdlib.h>
00048 #include <sys/types.h>
00049 #include <sys/ipc.h>
00050 #include <unistd.h>
00051 #include <fcntl.h>
00052 #include <time.h>
00053
00054 #include "../../sr_module.h"
00055 #include "../../dprint.h"
00056 #include "../../ut.h"
00057 #include "../../timer.h"
00058 #include "../../mem/shm_mem.h"
00059 #include "../../lib/srdb1/db.h"
00060 #include "../../parser/parse_from.h"
00061 #include "../../parser/parse_content.h"
00062 #include "../../parser/contact/parse_contact.h"
00063 #include "../../parser/parse_allow.h"
00064 #include "../../parser/parse_methods.h"
00065 #include "../../resolve.h"
00066 #include "../../usr_avp.h"
00067 #include "../../mod_fix.h"
00068
00069 #include "../../modules/tm/tm_load.h"
00070
00071 #include "ms_msg_list.h"
00072 #include "msfuncs.h"
00073 #include "api.h"
00074
00075 #define MAX_DEL_KEYS 1
00076 #define NR_KEYS 11
00077
00078 static str sc_mid = str_init("id");
00079 static str sc_from = str_init("src_addr");
00080 static str sc_to = str_init("dst_addr");
00081 static str sc_uri_user = str_init("username");
00082 static str sc_uri_host = str_init("domain");
00083 static str sc_body = str_init("body");
00084 static str sc_ctype = str_init("ctype");
00085 static str sc_exp_time = str_init("exp_time");
00086 static str sc_inc_time = str_init("inc_time");
00087 static str sc_snd_time = str_init("snd_time");
00088 static str sc_stored_hdrs = str_init("extra_hdrs");
00089
00090 #define SET_STR_VAL(_str, _res, _r, _c) \
00091 if (RES_ROWS(_res)[_r].values[_c].nul == 0) \
00092 { \
00093 switch(RES_ROWS(_res)[_r].values[_c].type) \
00094 { \
00095 case DB1_STRING: \
00096 (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.string_val; \
00097 (_str).len=strlen((_str).s); \
00098 break; \
00099 case DB1_STR: \
00100 (_str).len=RES_ROWS(_res)[_r].values[_c].val.str_val.len; \
00101 (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.str_val.s; \
00102 break; \
00103 case DB1_BLOB: \
00104 (_str).len=RES_ROWS(_res)[_r].values[_c].val.blob_val.len; \
00105 (_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.blob_val.s; \
00106 break; \
00107 default: \
00108 (_str).len=0; \
00109 (_str).s=NULL; \
00110 } \
00111 }
00112
00113 MODULE_VERSION
00114
00115 #define S_TABLE_VERSION 7
00116
00118 static db1_con_t *db_con = NULL;
00119 static db_func_t msilo_dbf;
00120
00122 msg_list ml = NULL;
00123
00125 struct tm_binds tmb;
00126
00129 static str ms_db_url = str_init(DEFAULT_DB_URL);
00130 static str ms_db_table = str_init("silo");
00131 str ms_reminder = {NULL, 0};
00132 str ms_outbound_proxy = {NULL, 0};
00133
00134 char* ms_from = NULL;
00135 char* ms_contact = NULL;
00136 char* ms_extra_hdrs = NULL;
00137 char* ms_content_type = NULL;
00138 char* ms_offline_message = NULL;
00139 void** ms_from_sp = NULL;
00140 void** ms_contact_sp = NULL;
00141 void** ms_extra_hdrs_sp = NULL;
00142 void** ms_content_type_sp = NULL;
00143 void** ms_offline_message_sp = NULL;
00144
00145 int ms_expire_time = 259200;
00146 int ms_check_time = 60;
00147 int ms_send_time = 0;
00148 int ms_clean_period = 10;
00149 int ms_use_contact = 1;
00150 int ms_add_date = 1;
00151 int ms_add_contact = 0;
00152 int ms_max_messages = 0;
00153
00154 static str ms_snd_time_avp_param = {NULL, 0};
00155 int_str ms_snd_time_avp_name;
00156 unsigned short ms_snd_time_avp_type;
00157
00158 static str ms_extra_hdrs_avp_param = {NULL, 0};
00159 int_str ms_extra_hdrs_avp_name;
00160 unsigned short ms_extra_hdrs_avp_type;
00161
00162 str msg_type = str_init("MESSAGE");
00163
00165 static int mod_init(void);
00166 static int child_init(int);
00167
00168 static int m_store(struct sip_msg*, str*);
00169 static int m_dump(struct sip_msg*, str*);
00170
00171 static int m_store_2(struct sip_msg*, char*, char*);
00172 static int m_dump_2(struct sip_msg*, char*, char*);
00173
00174 static void destroy(void);
00175
00176 static int bind_msilo(msilo_api_t* api);
00177
00178 void m_clean_silo(unsigned int ticks, void *);
00179 void m_send_ontimer(unsigned int ticks, void *);
00180
00181 int ms_reset_stime(int mid);
00182
00183 int check_message_support(struct sip_msg* msg);
00184
00185
00187 static void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps);
00188
00189 static cmd_export_t cmds[]={
00190 {"m_store", (cmd_function)m_store_2, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE},
00191 {"m_store", (cmd_function)m_store_2, 1, fixup_spve_null, 0,
00192 REQUEST_ROUTE | FAILURE_ROUTE},
00193 {"m_dump", (cmd_function)m_dump_2, 0, 0, 0, REQUEST_ROUTE},
00194 {"m_dump", (cmd_function)m_dump_2, 1, fixup_spve_null, 0,
00195 REQUEST_ROUTE},
00196 {"bind_msilo",(cmd_function)bind_msilo, 1, 0, 0, ANY_ROUTE},
00197 {0,0,0,0,0,0}
00198 };
00199
00200
00201 static param_export_t params[]={
00202 { "db_url", STR_PARAM, &ms_db_url.s },
00203 { "db_table", STR_PARAM, &ms_db_table.s },
00204 { "from_address", STR_PARAM, &ms_from },
00205 { "contact_hdr", STR_PARAM, &ms_contact },
00206 { "extra_hdrs", STR_PARAM, &ms_extra_hdrs },
00207 { "content_type_hdr", STR_PARAM, &ms_content_type },
00208 { "offline_message", STR_PARAM, &ms_offline_message },
00209 { "reminder", STR_PARAM, &ms_reminder.s },
00210 { "outbound_proxy", STR_PARAM, &ms_outbound_proxy.s },
00211 { "expire_time", INT_PARAM, &ms_expire_time },
00212 { "check_time", INT_PARAM, &ms_check_time },
00213 { "send_time", INT_PARAM, &ms_send_time },
00214 { "clean_period", INT_PARAM, &ms_clean_period },
00215 { "use_contact", INT_PARAM, &ms_use_contact },
00216 { "sc_mid", STR_PARAM, &sc_mid.s },
00217 { "sc_from", STR_PARAM, &sc_from.s },
00218 { "sc_to", STR_PARAM, &sc_to.s },
00219 { "sc_uri_user", STR_PARAM, &sc_uri_user.s },
00220 { "sc_uri_host", STR_PARAM, &sc_uri_host.s },
00221 { "sc_body", STR_PARAM, &sc_body.s },
00222 { "sc_ctype", STR_PARAM, &sc_ctype.s },
00223 { "sc_exp_time", STR_PARAM, &sc_exp_time.s },
00224 { "sc_inc_time", STR_PARAM, &sc_inc_time.s },
00225 { "sc_snd_time", STR_PARAM, &sc_snd_time.s },
00226 { "sc_stored_hdrs", STR_PARAM, &sc_stored_hdrs.s },
00227 { "snd_time_avp", STR_PARAM, &ms_snd_time_avp_param.s },
00228 { "extra_hdrs_avp", STR_PARAM, &ms_extra_hdrs_avp_param.s },
00229 { "add_date", INT_PARAM, &ms_add_date },
00230 { "max_messages", INT_PARAM, &ms_max_messages },
00231 { "add_contact", INT_PARAM, &ms_add_contact },
00232 { 0,0,0 }
00233 };
00234
00235 #ifdef STATISTICS
00236 #include "../../lib/kcore/statistics.h"
00237
00238 stat_var* ms_stored_msgs;
00239 stat_var* ms_dumped_msgs;
00240 stat_var* ms_failed_msgs;
00241 stat_var* ms_dumped_rmds;
00242 stat_var* ms_failed_rmds;
00243
00244 stat_export_t msilo_stats[] = {
00245 {"stored_messages" , 0, &ms_stored_msgs },
00246 {"dumped_messages" , 0, &ms_dumped_msgs },
00247 {"failed_messages" , 0, &ms_failed_msgs },
00248 {"dumped_reminders" , 0, &ms_dumped_rmds },
00249 {"failed_reminders" , 0, &ms_failed_rmds },
00250 {0,0,0}
00251 };
00252
00253 #endif
00254
00255 struct module_exports exports= {
00256 "msilo",
00257 DEFAULT_DLFLAGS,
00258 cmds,
00259 params,
00260 #ifdef STATISTICS
00261 msilo_stats,
00262 #else
00263 0,
00264 #endif
00265 0,
00266 0,
00267 0,
00268 mod_init,
00269 0,
00270 (destroy_function) destroy,
00271 child_init
00272 };
00273
00274 static int bind_msilo(msilo_api_t* api)
00275 {
00276 if (!api) {
00277 return -1;
00278 }
00279 api->m_store = m_store;
00280 api->m_dump = m_dump;
00281 return 0;
00282 }
00283
00287 static int mod_init(void)
00288 {
00289 pv_spec_t avp_spec;
00290
00291 #ifdef STATISTICS
00292
00293 if (register_module_stats( exports.name, msilo_stats)!=0 ) {
00294 LM_ERR("failed to register core statistics\n");
00295 return -1;
00296 }
00297 #endif
00298 ms_db_url.len = strlen (ms_db_url.s);
00299 ms_db_table.len = strlen (ms_db_table.s);
00300 sc_mid.len = strlen(sc_mid.s);
00301 sc_from.len = strlen(sc_from.s);
00302 sc_to.len = strlen(sc_to.s);
00303 sc_uri_user.len = strlen(sc_uri_user.s);
00304 sc_uri_host.len = strlen(sc_uri_host.s);
00305 sc_body.len = strlen(sc_body.s);
00306 sc_ctype.len = strlen(sc_ctype.s);
00307 sc_exp_time.len = strlen(sc_exp_time.s);
00308 sc_inc_time.len = strlen(sc_inc_time.s);
00309 sc_snd_time.len = strlen(sc_snd_time.s);
00310 if (ms_snd_time_avp_param.s)
00311 ms_snd_time_avp_param.len = strlen(ms_snd_time_avp_param.s);
00312 if (ms_extra_hdrs_avp_param.s)
00313 ms_extra_hdrs_avp_param.len = strlen(ms_extra_hdrs_avp_param.s);
00314
00315
00316 if (db_bind_mod(&ms_db_url, &msilo_dbf))
00317 {
00318 LM_DBG("database module not found\n");
00319 return -1;
00320 }
00321
00322 if (!DB_CAPABILITY(msilo_dbf, DB_CAP_ALL)) {
00323 LM_ERR("database module does not implement "
00324 "all functions needed by the module\n");
00325 return -1;
00326 }
00327
00328 if (ms_snd_time_avp_param.s && ms_snd_time_avp_param.len > 0) {
00329 if (pv_parse_spec(&ms_snd_time_avp_param, &avp_spec)==0
00330 || avp_spec.type!=PVT_AVP) {
00331 LM_ERR("malformed or non AVP %.*s AVP definition\n",
00332 ms_snd_time_avp_param.len, ms_snd_time_avp_param.s);
00333 return -1;
00334 }
00335
00336 if(pv_get_avp_name(0, &(avp_spec.pvp), &ms_snd_time_avp_name,
00337 &ms_snd_time_avp_type)!=0)
00338 {
00339 LM_ERR("[%.*s]- invalid AVP definition\n",
00340 ms_snd_time_avp_param.len, ms_snd_time_avp_param.s);
00341 return -1;
00342 }
00343 }
00344
00345 if (ms_extra_hdrs_avp_param.s && ms_extra_hdrs_avp_param.len > 0) {
00346 if (pv_parse_spec(&ms_extra_hdrs_avp_param, &avp_spec)==0
00347 || avp_spec.type!=PVT_AVP) {
00348 LM_ERR("malformed or non AVP %.*s AVP definition\n",
00349 ms_extra_hdrs_avp_param.len, ms_extra_hdrs_avp_param.s);
00350 return -1;
00351 }
00352
00353 if (pv_get_avp_name(0, &(avp_spec.pvp), &ms_extra_hdrs_avp_name,
00354 &ms_extra_hdrs_avp_type) != 0) {
00355 LM_ERR("[%.*s]- invalid AVP definition\n",
00356 ms_extra_hdrs_avp_param.len, ms_extra_hdrs_avp_param.s);
00357 return -1;
00358 }
00359 }
00360
00361 db_con = msilo_dbf.init(&ms_db_url);
00362 if (!db_con)
00363 {
00364 LM_ERR("failed to connect to the database\n");
00365 return -1;
00366 }
00367
00368 if(db_check_table_version(&msilo_dbf, db_con, &ms_db_table, S_TABLE_VERSION) < 0) {
00369 LM_ERR("error during table version check.\n");
00370 return -1;
00371 }
00372 if(db_con)
00373 msilo_dbf.close(db_con);
00374 db_con = NULL;
00375
00376
00377 if (load_tm_api(&tmb)!=0) {
00378 LM_ERR("can't load TM API\n");
00379 return -1;
00380 }
00381
00382 if(ms_from!=NULL)
00383 {
00384 ms_from_sp = (void**)pkg_malloc(sizeof(void*));
00385 if(ms_from_sp==NULL)
00386 {
00387 LM_ERR("no more pkg\n");
00388 return -1;
00389 }
00390 *ms_from_sp = (void*)ms_from;
00391 if(fixup_spve_null(ms_from_sp, 1)!=0)
00392 {
00393 LM_ERR("bad contact parameter\n");
00394 return -1;
00395 }
00396 }
00397 if(ms_contact!=NULL)
00398 {
00399 ms_contact_sp = (void**)pkg_malloc(sizeof(void*));
00400 if(ms_contact_sp==NULL)
00401 {
00402 LM_ERR("no more pkg\n");
00403 return -1;
00404 }
00405 *ms_contact_sp = (void*)ms_contact;
00406 if(fixup_spve_null(ms_contact_sp, 1)!=0)
00407 {
00408 LM_ERR("bad contact parameter\n");
00409 return -1;
00410 }
00411 }
00412 if(ms_extra_hdrs!=NULL)
00413 {
00414 ms_extra_hdrs_sp = (void**)pkg_malloc(sizeof(void*));
00415 if(ms_extra_hdrs_sp==NULL)
00416 {
00417 LM_ERR("no more pkg\n");
00418 return -1;
00419 }
00420 *ms_extra_hdrs_sp = (void*)ms_extra_hdrs;
00421 if(fixup_spve_null(ms_extra_hdrs_sp, 1)!=0)
00422 {
00423 LM_ERR("bad extra_hdrs parameter\n");
00424 return -1;
00425 }
00426 }
00427 if(ms_content_type!=NULL)
00428 {
00429 ms_content_type_sp = (void**)pkg_malloc(sizeof(void*));
00430 if(ms_content_type_sp==NULL)
00431 {
00432 LM_ERR("no more pkg\n");
00433 return -1;
00434 }
00435 *ms_content_type_sp = (void*)ms_content_type;
00436 if(fixup_spve_null(ms_content_type_sp, 1)!=0)
00437 {
00438 LM_ERR("bad content_type parameter\n");
00439 return -1;
00440 }
00441 }
00442 if(ms_offline_message!=NULL)
00443 {
00444 ms_offline_message_sp = (void**)pkg_malloc(sizeof(void*));
00445 if(ms_offline_message_sp==NULL)
00446 {
00447 LM_ERR("no more pkg\n");
00448 return -1;
00449 }
00450 *ms_offline_message_sp = (void*)ms_offline_message;
00451 if(fixup_spve_null(ms_offline_message_sp, 1)!=0)
00452 {
00453 LM_ERR("bad offline_message parameter\n");
00454 return -1;
00455 }
00456 }
00457 if(ms_offline_message!=NULL && ms_content_type==NULL)
00458 {
00459 LM_ERR("content_type parameter must be set\n");
00460 return -1;
00461 }
00462
00463 ml = msg_list_init();
00464 if(ml==NULL)
00465 {
00466 LM_ERR("can't initialize msg list\n");
00467 return -1;
00468 }
00469 if(ms_check_time<0)
00470 {
00471 LM_ERR("bad check time value\n");
00472 return -1;
00473 }
00474 register_timer(m_clean_silo, 0, ms_check_time);
00475 if(ms_send_time>0 && ms_reminder.s!=NULL)
00476 register_timer(m_send_ontimer, 0, ms_send_time);
00477
00478 if(ms_reminder.s!=NULL)
00479 ms_reminder.len = strlen(ms_reminder.s);
00480 if(ms_outbound_proxy.s!=NULL)
00481 ms_outbound_proxy.len = strlen(ms_outbound_proxy.s);
00482
00483 return 0;
00484 }
00485
00489 static int child_init(int rank)
00490 {
00491 if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
00492 return 0;
00493
00494 LM_DBG("rank #%d / pid <%d>\n", rank, getpid());
00495 if (msilo_dbf.init==0)
00496 {
00497 LM_CRIT("database not bound\n");
00498 return -1;
00499 }
00500 db_con = msilo_dbf.init(&ms_db_url);
00501 if (!db_con)
00502 {
00503 LM_ERR("child %d: failed to connect database\n", rank);
00504 return -1;
00505 }
00506 else
00507 {
00508 if (msilo_dbf.use_table(db_con, &ms_db_table) < 0) {
00509 LM_ERR("child %d: failed in use_table\n", rank);
00510 return -1;
00511 }
00512
00513 LM_DBG("#%d database connection opened successfully\n", rank);
00514 }
00515 return 0;
00516 }
00517
00525 static int get_non_mandatory_headers(struct sip_msg *msg, char *buf, int buf_len)
00526 {
00527 struct hdr_field *hdrs;
00528 int len = 0;
00529 int_str avp_value;
00530 struct usr_avp *avp;
00531
00532 if (ms_extra_hdrs_avp_name.n != 0) {
00533 avp = NULL;
00534 avp = search_first_avp(ms_extra_hdrs_avp_type,
00535 ms_extra_hdrs_avp_name, &avp_value, 0);
00536 if ((avp != NULL) && is_avp_str_val(avp)) {
00537 if (buf_len <= avp_value.s.len) {
00538 LM_ERR("insufficient space to store headers in silo\n");
00539 return -1;
00540 }
00541 memcpy(buf, avp_value.s.s, avp_value.s.len);
00542 return avp_value.s.len;
00543 }
00544 }
00545
00546 for (hdrs = msg->headers; hdrs != NULL; hdrs = hdrs->next)
00547 {
00548 switch (hdrs->type) {
00549 case HDR_OTHER_T:
00550 case HDR_PPI_T:
00551 case HDR_PAI_T:
00552 case HDR_PRIVACY_T:
00553 if (buf_len <= hdrs->len)
00554 {
00555 LM_ERR("Insufficient space to store headers in silo\n");
00556 return -1;
00557 }
00558 memcpy(buf, hdrs->name.s, hdrs->len);
00559 len += hdrs->len;
00560 buf += hdrs->len;
00561 buf_len -= hdrs->len;
00562 break;
00563 default:
00564 break;
00565 }
00566 }
00567 return len;
00568 }
00569
00577 static int m_store(struct sip_msg* msg, str *owner_s)
00578 {
00579 str body, str_hdr, ctaddr;
00580 struct to_body *pto, *pfrom;
00581 struct sip_uri puri;
00582 str duri;
00583 #define EXTRA_HDRS_BUF_LEN 1024
00584 static char extra_hdrs_buf[EXTRA_HDRS_BUF_LEN];
00585 str extra_hdrs;
00586 db_key_t db_keys[NR_KEYS-1];
00587 db_val_t db_vals[NR_KEYS-1];
00588 db_key_t db_cols[1];
00589 db1_res_t* res = NULL;
00590 uac_req_t uac_r;
00591
00592 int nr_keys = 0, val, lexpire;
00593 content_type_t ctype;
00594 #define MS_BUF1_SIZE 1024
00595 static char ms_buf1[MS_BUF1_SIZE];
00596 int mime;
00597 str notify_from;
00598 str notify_body;
00599 str notify_ctype;
00600 str notify_contact;
00601
00602 int_str avp_value;
00603 struct usr_avp *avp;
00604
00605 LM_DBG("------------ start ------------\n");
00606
00607
00608 body.s = get_body( msg );
00609 if (body.s==0)
00610 {
00611 LM_ERR("cannot extract body from msg\n");
00612 goto error;
00613 }
00614
00615
00616 if (!msg->content_length)
00617 {
00618 LM_ERR("no Content-Length header found!\n");
00619 goto error;
00620 }
00621 body.len = get_content_length( msg );
00622
00623
00624 if(body.len <= 0)
00625 {
00626 LM_ERR("body of the message is empty!\n");
00627 goto error;
00628 }
00629
00630
00631 if(parse_to_header(msg)<0)
00632 {
00633 LM_ERR("failed getting 'to' header!\n");
00634 goto error;
00635 }
00636
00637 pto = get_to(msg);
00638
00639
00640 memset(&puri, 0, sizeof(struct sip_uri));
00641 if(owner_s != NULL)
00642 {
00643 if(parse_uri(owner_s->s, owner_s->len, &puri)!=0)
00644 {
00645 LM_ERR("bad owner SIP address!\n");
00646 goto error;
00647 } else {
00648 LM_DBG("using user id [%.*s]\n", owner_s->len, owner_s->s);
00649 }
00650 } else {
00651 if(msg->new_uri.len <= 0)
00652 {
00653 if(msg->first_line.u.request.uri.len <= 0)
00654 {
00655 LM_ERR("bad dst URI!\n");
00656 goto error;
00657 }
00658 duri = msg->first_line.u.request.uri;
00659 } else {
00660 duri = msg->new_uri;
00661 }
00662 LM_DBG("NEW R-URI found - check if is AoR!\n");
00663 if(parse_uri(duri.s, duri.len, &puri)!=0)
00664 {
00665 LM_ERR("bad dst R-URI!!\n");
00666 goto error;
00667 }
00668 }
00669 if(puri.user.len<=0)
00670 {
00671 LM_ERR("no username for owner\n");
00672 goto error;
00673 }
00674
00675 db_keys[nr_keys] = &sc_uri_user;
00676
00677 db_vals[nr_keys].type = DB1_STR;
00678 db_vals[nr_keys].nul = 0;
00679 db_vals[nr_keys].val.str_val.s = puri.user.s;
00680 db_vals[nr_keys].val.str_val.len = puri.user.len;
00681
00682 nr_keys++;
00683
00684 db_keys[nr_keys] = &sc_uri_host;
00685
00686 db_vals[nr_keys].type = DB1_STR;
00687 db_vals[nr_keys].nul = 0;
00688 db_vals[nr_keys].val.str_val.s = puri.host.s;
00689 db_vals[nr_keys].val.str_val.len = puri.host.len;
00690
00691 nr_keys++;
00692
00693 if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
00694 {
00695 LM_ERR("failed to use_table\n");
00696 goto error;
00697 }
00698
00699 if (ms_max_messages > 0) {
00700 db_cols[0] = &sc_inc_time;
00701 if (msilo_dbf.query(db_con, db_keys, 0, db_vals, db_cols,
00702 2, 1, 0, &res) < 0 ) {
00703 LM_ERR("failed to query the database\n");
00704 return -1;
00705 }
00706 if (RES_ROW_N(res) >= ms_max_messages) {
00707 LM_ERR("too many messages for AoR '%.*s@%.*s'\n",
00708 puri.user.len, puri.user.s, puri.host.len, puri.host.s);
00709 msilo_dbf.free_result(db_con, res);
00710 return -1;
00711 }
00712 msilo_dbf.free_result(db_con, res);
00713 }
00714
00715
00716 db_keys[nr_keys] = &sc_to;
00717
00718 db_vals[nr_keys].type = DB1_STR;
00719 db_vals[nr_keys].nul = 0;
00720 db_vals[nr_keys].val.str_val.s = pto->uri.s;
00721 db_vals[nr_keys].val.str_val.len = pto->uri.len;
00722
00723 nr_keys++;
00724
00725
00726 if ( parse_from_header( msg )<0 )
00727 {
00728 LM_ERR("cannot parse From header\n");
00729 goto error;
00730 }
00731 pfrom = get_from(msg);
00732 LM_DBG("'From' header: <%.*s>\n", pfrom->uri.len, pfrom->uri.s);
00733
00734 db_keys[nr_keys] = &sc_from;
00735
00736 db_vals[nr_keys].type = DB1_STR;
00737 db_vals[nr_keys].nul = 0;
00738 db_vals[nr_keys].val.str_val.s = pfrom->uri.s;
00739 db_vals[nr_keys].val.str_val.len = pfrom->uri.len;
00740
00741 nr_keys++;
00742
00743
00744
00745 db_keys[nr_keys] = &sc_body;
00746
00747 db_vals[nr_keys].type = DB1_BLOB;
00748 db_vals[nr_keys].nul = 0;
00749 db_vals[nr_keys].val.blob_val.s = body.s;
00750 db_vals[nr_keys].val.blob_val.len = body.len;
00751
00752 nr_keys++;
00753
00754 lexpire = ms_expire_time;
00755
00756 if ((mime=parse_content_type_hdr(msg))<1 )
00757 {
00758 LM_ERR("cannot parse Content-Type header\n");
00759 goto error;
00760 }
00761
00762 db_keys[nr_keys] = &sc_ctype;
00763 db_vals[nr_keys].type = DB1_STR;
00764 db_vals[nr_keys].nul = 0;
00765 db_vals[nr_keys].val.str_val.s = "text/plain";
00766 db_vals[nr_keys].val.str_val.len = 10;
00767
00769 if( mime!=(TYPE_TEXT<<16)+SUBTYPE_PLAIN
00770 && mime!=(TYPE_MESSAGE<<16)+SUBTYPE_CPIM )
00771 {
00772 if(m_extract_content_type(msg->content_type->body.s,
00773 msg->content_type->body.len, &ctype, CT_TYPE) != -1)
00774 {
00775 LM_DBG("'content-type' found\n");
00776 db_vals[nr_keys].val.str_val.s = ctype.type.s;
00777 db_vals[nr_keys].val.str_val.len = ctype.type.len;
00778 }
00779 }
00780 nr_keys++;
00781
00782
00783 if(msg->expires && msg->expires->body.len > 0)
00784 {
00785 LM_DBG("'expires' found\n");
00786 val = atoi(msg->expires->body.s);
00787 if(val > 0)
00788 lexpire = (ms_expire_time<=val)?ms_expire_time:val;
00789 }
00790
00791
00792 val = (int)time(NULL);
00793
00794
00795 db_keys[nr_keys] = &sc_exp_time;
00796 db_vals[nr_keys].type = DB1_INT;
00797 db_vals[nr_keys].nul = 0;
00798 db_vals[nr_keys].val.int_val = val+lexpire;
00799 nr_keys++;
00800
00801
00802 db_keys[nr_keys] = &sc_inc_time;
00803 db_vals[nr_keys].type = DB1_INT;
00804 db_vals[nr_keys].nul = 0;
00805 db_vals[nr_keys].val.int_val = val;
00806 nr_keys++;
00807
00808
00809 db_keys[nr_keys] = &sc_snd_time;
00810 db_vals[nr_keys].type = DB1_INT;
00811 db_vals[nr_keys].nul = 0;
00812 db_vals[nr_keys].val.int_val = 0;
00813 if(ms_snd_time_avp_name.n!=0)
00814 {
00815 avp = NULL;
00816 avp=search_first_avp(ms_snd_time_avp_type, ms_snd_time_avp_name,
00817 &avp_value, 0);
00818 if(avp!=NULL && is_avp_str_val(avp))
00819 {
00820 if(ms_extract_time(&avp_value.s, &db_vals[nr_keys].val.int_val)!=0)
00821 db_vals[nr_keys].val.int_val = 0;
00822 }
00823 }
00824 nr_keys++;
00825
00826
00827 extra_hdrs.s = extra_hdrs_buf;
00828 extra_hdrs.len = get_non_mandatory_headers(msg, extra_hdrs_buf, EXTRA_HDRS_BUF_LEN);
00829 if (extra_hdrs.len < 0)
00830 {
00831 goto error;
00832 }
00833
00834 db_keys[nr_keys] = &sc_stored_hdrs;
00835
00836 db_vals[nr_keys].type = DB1_BLOB;
00837 db_vals[nr_keys].nul = 0;
00838 db_vals[nr_keys].val.blob_val.s = extra_hdrs.s;
00839 db_vals[nr_keys].val.blob_val.len = extra_hdrs.len;
00840
00841 nr_keys++;
00842
00843 if(msilo_dbf.insert(db_con, db_keys, db_vals, nr_keys) < 0)
00844 {
00845 LM_ERR("failed to store message\n");
00846 goto error;
00847 }
00848 LM_DBG("message stored. T:<%.*s> F:<%.*s>\n",
00849 pto->uri.len, pto->uri.s, pfrom->uri.len, pfrom->uri.s);
00850
00851 #ifdef STATISTICS
00852 update_stat(ms_stored_msgs, 1);
00853 #endif
00854
00855 if(ms_from==NULL || ms_offline_message == NULL)
00856 goto done;
00857
00858 LM_DBG("sending info message.\n");
00859 if(fixup_get_svalue(msg, (gparam_p)*ms_from_sp, ¬ify_from)!=0
00860 || notify_from.len<=0)
00861 {
00862 LM_WARN("cannot get notification From address\n");
00863 goto done;
00864 }
00865 if(fixup_get_svalue(msg, (gparam_p)*ms_offline_message_sp, ¬ify_body)!=0
00866 || notify_body.len<=0)
00867 {
00868 LM_WARN("cannot get notification body\n");
00869 goto done;
00870 }
00871 if(fixup_get_svalue(msg, (gparam_p)*ms_content_type_sp, ¬ify_ctype)!=0
00872 || notify_ctype.len<=0)
00873 {
00874 LM_WARN("cannot get notification content type\n");
00875 goto done;
00876 }
00877
00878 if(ms_contact!=NULL && fixup_get_svalue(msg, (gparam_p)*ms_contact_sp,
00879 ¬ify_contact)==0 && notify_contact.len>0)
00880 {
00881 if(notify_contact.len+notify_ctype.len>=MS_BUF1_SIZE)
00882 {
00883 LM_WARN("insufficient buffer to build notification headers\n");
00884 goto done;
00885 }
00886 memcpy(ms_buf1, notify_contact.s, notify_contact.len);
00887 memcpy(ms_buf1+notify_contact.len, notify_ctype.s, notify_ctype.len);
00888 str_hdr.s = ms_buf1;
00889 str_hdr.len = notify_contact.len + notify_ctype.len;
00890 } else {
00891 str_hdr = notify_ctype;
00892 }
00893
00894
00895 ctaddr.s = NULL;
00896 if(ms_use_contact && msg->contact!=NULL && msg->contact->body.s!=NULL
00897 && msg->contact->body.len > 0)
00898 {
00899 LM_DBG("contact header found\n");
00900 if((msg->contact->parsed!=NULL
00901 && ((contact_body_t*)(msg->contact->parsed))->contacts!=NULL)
00902 || (parse_contact(msg->contact)==0
00903 && msg->contact->parsed!=NULL
00904 && ((contact_body_t*)(msg->contact->parsed))->contacts!=NULL))
00905 {
00906 LM_DBG("using contact header for info msg\n");
00907 ctaddr.s =
00908 ((contact_body_t*)(msg->contact->parsed))->contacts->uri.s;
00909 ctaddr.len =
00910 ((contact_body_t*)(msg->contact->parsed))->contacts->uri.len;
00911
00912 if(!ctaddr.s || ctaddr.len < 6 || strncmp(ctaddr.s, "sip:", 4)
00913 || ctaddr.s[4]==' ')
00914 ctaddr.s = NULL;
00915 else
00916 LM_DBG("feedback contact [%.*s]\n", ctaddr.len,ctaddr.s);
00917 }
00918 }
00919
00920 memset(&uac_r,'\0', sizeof(uac_r));
00921 uac_r.method = &msg_type;
00922 uac_r.headers = &str_hdr;
00923 uac_r.body = ¬ify_body;
00924 tmb.t_request(&uac_r,
00925 (ctaddr.s)?&ctaddr:&pfrom->uri,
00926 &pfrom->uri,
00927 ¬ify_from,
00928 (ms_outbound_proxy.s)?&ms_outbound_proxy:0
00929 );
00930
00931 done:
00932 return 1;
00933 error:
00934 return -1;
00935 }
00936
00940 static int m_store_2(struct sip_msg* msg, char* owner, char* s2)
00941 {
00942 str owner_s;
00943 if (owner != NULL)
00944 {
00945 if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
00946 {
00947 LM_ERR("invalid owner uri parameter");
00948 return -1;
00949 }
00950 return m_store(msg, &owner_s);
00951 }
00952 return m_store(msg, NULL);
00953 }
00954
00958 static int m_dump(struct sip_msg* msg, str* owner_s)
00959 {
00960 struct to_body *pto = NULL;
00961 db_key_t db_keys[3];
00962 db_key_t ob_key;
00963 db_op_t db_ops[3];
00964 db_val_t db_vals[3];
00965 db_key_t db_cols[7];
00966 db1_res_t* db_res = NULL;
00967 int i, db_no_cols = 7, db_no_keys = 3, mid, n;
00968 static char hdr_buf[1024];
00969 static char body_buf[1024];
00970 struct sip_uri puri;
00971 uac_req_t uac_r;
00972 str str_vals[5], hdr_str, body_str, extra_hdrs_str, tmp_extra_hdrs;
00973 time_t rtime;
00974
00975
00976 ob_key = &sc_mid;
00977
00978 db_keys[0]=&sc_uri_user;
00979 db_keys[1]=&sc_uri_host;
00980 db_keys[2]=&sc_snd_time;
00981 db_ops[0]=OP_EQ;
00982 db_ops[1]=OP_EQ;
00983 db_ops[2]=OP_EQ;
00984
00985 db_cols[0]=&sc_mid;
00986 db_cols[1]=&sc_from;
00987 db_cols[2]=&sc_to;
00988 db_cols[3]=&sc_body;
00989 db_cols[4]=&sc_ctype;
00990 db_cols[5]=&sc_inc_time;
00991 db_cols[6]=&sc_stored_hdrs;
00992
00993
00994 LM_DBG("------------ start ------------\n");
00995 hdr_str.s=hdr_buf;
00996 hdr_str.len=1024;
00997 body_str.s=body_buf;
00998 body_str.len=1024;
00999
01000
01001 if(parse_to_header(msg)<0)
01002 {
01003 LM_ERR("failed parsing To header\n");
01004 goto error;
01005 }
01006
01007 pto = get_to(msg);
01008
01012 if(msg->first_line.u.request.method_value==METHOD_REGISTER)
01013 {
01014 if (check_message_support(msg)!=0) {
01015 LM_DBG("MESSAGE method not supported\n");
01016 return -1;
01017 }
01018 }
01019
01020
01021 memset(&puri, 0, sizeof(struct sip_uri));
01022 if(owner_s)
01023 {
01024 if(parse_uri(owner_s->s, owner_s->len, &puri)!=0)
01025 {
01026 LM_ERR("bad owner SIP address!\n");
01027 goto error;
01028 } else {
01029 LM_DBG("using user id [%.*s]\n", owner_s->len, owner_s->s);
01030 }
01031 } else {
01032 if(parse_uri(pto->uri.s, pto->uri.len, &puri)!=0)
01033 {
01034 LM_ERR("bad owner To URI!\n");
01035 goto error;
01036 }
01037 }
01038 if(puri.user.len<=0 || puri.user.s==NULL
01039 || puri.host.len<=0 || puri.host.s==NULL)
01040 {
01041 LM_ERR("bad owner URI!\n");
01042 goto error;
01043 }
01044
01045 db_vals[0].type = DB1_STR;
01046 db_vals[0].nul = 0;
01047 db_vals[0].val.str_val.s = puri.user.s;
01048 db_vals[0].val.str_val.len = puri.user.len;
01049
01050 db_vals[1].type = DB1_STR;
01051 db_vals[1].nul = 0;
01052 db_vals[1].val.str_val.s = puri.host.s;
01053 db_vals[1].val.str_val.len = puri.host.len;
01054
01055 db_vals[2].type = DB1_INT;
01056 db_vals[2].nul = 0;
01057 db_vals[2].val.int_val = 0;
01058
01059 if (db_con == NULL) {
01060 LM_ERR("database connection has not been established\n");
01061 goto error;
01062 }
01063
01064 if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
01065 {
01066 LM_ERR("failed to use_table\n");
01067 return -1;
01068 }
01069
01070 if (msilo_dbf.query(db_con,db_keys,db_ops,db_vals,db_cols,db_no_keys,
01071 db_no_cols, ob_key, &db_res) < 0) {
01072 LM_ERR("failed to query database\n");
01073 goto error;
01074 }
01075
01076 if (RES_ROW_N(db_res) <= 0) {
01077 LM_DBG("no stored message for <%.*s>!\n", pto->uri.len, pto->uri.s);
01078 goto done;
01079 }
01080
01081 LM_DBG("dumping [%d] messages for <%.*s>!!!\n",
01082 RES_ROW_N(db_res), pto->uri.len, pto->uri.s);
01083
01084 for(i = 0; i < RES_ROW_N(db_res); i++)
01085 {
01086 mid = RES_ROWS(db_res)[i].values[0].val.int_val;
01087 if(msg_list_check_msg(ml, mid))
01088 {
01089 LM_DBG("message[%d] mid=%d already sent.\n", i, mid);
01090 continue;
01091 }
01092
01093 memset(str_vals, 0, 5*sizeof(str));
01094 SET_STR_VAL(str_vals[0], db_res, i, 1);
01095 SET_STR_VAL(str_vals[1], db_res, i, 2);
01096 SET_STR_VAL(str_vals[2], db_res, i, 3);
01097 SET_STR_VAL(str_vals[3], db_res, i, 4);
01098 SET_STR_VAL(str_vals[4], db_res, i, 6);
01099 rtime =
01100 (time_t)RES_ROWS(db_res)[i].values[5].val.int_val;
01101
01102 if (ms_extra_hdrs != NULL) {
01103 if (fixup_get_svalue(msg, (gparam_p)*ms_extra_hdrs_sp,
01104 &extra_hdrs_str) != 0) {
01105 if (msilo_dbf.free_result(db_con, db_res) < 0)
01106 LM_ERR("failed to free the query result\n");
01107 LM_ERR("unable to get extra_hdrs value\n");
01108 goto error;
01109 }
01110 } else {
01111 extra_hdrs_str.len = 0;
01112 }
01113
01114 tmp_extra_hdrs.len = extra_hdrs_str.len+str_vals[4].len;
01115 if(tmp_extra_hdrs.len>0)
01116 {
01117 if ((tmp_extra_hdrs.s = pkg_malloc(tmp_extra_hdrs.len)) == NULL)
01118 {
01119 LM_ERR("Out of pkg memory");
01120 if (msilo_dbf.free_result(db_con, db_res) < 0)
01121 LM_ERR("failed to free the query result\n");
01122 msg_list_set_flag(ml, mid, MS_MSG_ERRO);
01123 goto error;
01124 }
01125 memcpy(tmp_extra_hdrs.s, extra_hdrs_str.s, extra_hdrs_str.len);
01126 memcpy(tmp_extra_hdrs.s+extra_hdrs_str.len, str_vals[4].s, str_vals[4].len);
01127 } else {
01128 tmp_extra_hdrs.len = 0;
01129 tmp_extra_hdrs.s = "";
01130 }
01131 hdr_str.len = 1024;
01132 if(m_build_headers(&hdr_str, str_vals[3] ,
01133 str_vals[0], rtime ,
01134 tmp_extra_hdrs ) < 0)
01135 {
01136 LM_ERR("headers building failed [%d]\n", mid);
01137 pkg_free(tmp_extra_hdrs.s);
01138 if (msilo_dbf.free_result(db_con, db_res) < 0)
01139 LM_ERR("failed to free the query result\n");
01140 msg_list_set_flag(ml, mid, MS_MSG_ERRO);
01141 goto error;
01142 }
01143 pkg_free(tmp_extra_hdrs.s);
01144
01145 LM_DBG("msg [%d-%d] for: %.*s\n", i+1, mid, pto->uri.len, pto->uri.s);
01146
01148 body_str.len = 1024;
01149
01150 if ((str_vals[3].len == 10) &&
01151 (strncmp(str_vals[3].s, "text/plain", 10) == 0)) {
01152 n = m_build_body(&body_str, rtime, str_vals[2], 0);
01153 } else {
01154 n = -1;
01155 }
01156 if(n<0)
01157 LM_DBG("sending simple body\n");
01158 else
01159 LM_DBG("sending composed body\n");
01160
01161 memset(&uac_r,'\0', sizeof(uac_r));
01162 uac_r.method = &msg_type;
01163 uac_r.headers = &hdr_str;
01164 uac_r.body = (n<0)?&str_vals[2]:&body_str;
01165 uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
01166 uac_r.cb = m_tm_callback;
01167 uac_r.cbp = (void*)(long)mid;
01168
01169 tmb.t_request(&uac_r,
01170 &str_vals[1],
01171 &str_vals[1],
01172 &str_vals[0],
01173 (ms_outbound_proxy.s)?&ms_outbound_proxy:0
01174 );
01175 }
01176
01177 done:
01182 if ((db_res !=NULL) && msilo_dbf.free_result(db_con, db_res) < 0)
01183 LM_ERR("failed to free result of query\n");
01184
01185 return 1;
01186 error:
01187 return -1;
01188 }
01189
01193 static int m_dump_2(struct sip_msg* msg, char* owner, char* s2)
01194 {
01195 str owner_s;
01196 if (owner != NULL)
01197 {
01198 if(fixup_get_svalue(msg, (gparam_p)owner, &owner_s)!=0)
01199 {
01200 LM_ERR("invalid owner uri parameter");
01201 return -1;
01202 }
01203 return m_dump(msg, &owner_s);
01204 }
01205 return m_dump(msg, NULL);
01206 }
01207
01212 void m_clean_silo(unsigned int ticks, void *param)
01213 {
01214 msg_list_el mle = NULL, p;
01215 db_key_t db_keys[MAX_DEL_KEYS];
01216 db_val_t db_vals[MAX_DEL_KEYS];
01217 db_op_t db_ops[1] = { OP_LEQ };
01218 int n;
01219
01220 LM_DBG("cleaning stored messages - %d\n", ticks);
01221
01222 msg_list_check(ml);
01223 mle = p = msg_list_reset(ml);
01224 n = 0;
01225 if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
01226 {
01227 LM_ERR("failed to use_table\n");
01228 return;
01229 }
01230 while(p)
01231 {
01232 if(p->flag & MS_MSG_DONE)
01233 {
01234 #ifdef STATISTICS
01235 if(p->flag & MS_MSG_TSND)
01236 update_stat(ms_dumped_msgs, 1);
01237 else
01238 update_stat(ms_dumped_rmds, 1);
01239 #endif
01240
01241 db_keys[n] = &sc_mid;
01242 db_vals[n].type = DB1_INT;
01243 db_vals[n].nul = 0;
01244 db_vals[n].val.int_val = p->msgid;
01245 LM_DBG("cleaning sent message [%d]\n", p->msgid);
01246 n++;
01247 if(n==MAX_DEL_KEYS)
01248 {
01249 if (msilo_dbf.delete(db_con, db_keys, NULL, db_vals, n) < 0)
01250 LM_ERR("failed to clean %d messages.\n",n);
01251 n = 0;
01252 }
01253 }
01254 if((p->flag & MS_MSG_ERRO) && (p->flag & MS_MSG_TSND))
01255 {
01256 ms_reset_stime(p->msgid);
01257 #ifdef STATISTICS
01258 update_stat(ms_failed_rmds, 1);
01259 #endif
01260
01261 }
01262 #ifdef STATISTICS
01263 if((p->flag & MS_MSG_ERRO) && !(p->flag & MS_MSG_TSND))
01264 update_stat(ms_failed_msgs, 1);
01265 #endif
01266 p = p->next;
01267 }
01268 if(n>0)
01269 {
01270 if (msilo_dbf.delete(db_con, db_keys, NULL, db_vals, n) < 0)
01271 LM_ERR("failed to clean %d messages\n", n);
01272 n = 0;
01273 }
01274
01275 msg_list_el_free_all(mle);
01276
01277
01278 if(ticks%(ms_check_time*ms_clean_period)<ms_check_time)
01279 {
01280 LM_DBG("cleaning expired messages\n");
01281 db_keys[0] = &sc_exp_time;
01282 db_vals[0].type = DB1_INT;
01283 db_vals[0].nul = 0;
01284 db_vals[0].val.int_val = (int)time(NULL);
01285 if (msilo_dbf.delete(db_con, db_keys, db_ops, db_vals, 1) < 0)
01286 LM_DBG("ERROR cleaning expired messages\n");
01287 }
01288 }
01289
01290
01294 static void destroy(void)
01295 {
01296 msg_list_free(ml);
01297
01298 if(db_con && msilo_dbf.close)
01299 msilo_dbf.close(db_con);
01300 }
01301
01305 void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps)
01306 {
01307 if(ps->param==NULL || *ps->param==0)
01308 {
01309 LM_DBG("message id not received\n");
01310 goto done;
01311 }
01312
01313 LM_DBG("completed with status %d [mid: %ld/%d]\n",
01314 ps->code, (long)ps->param, *((int*)ps->param));
01315 if(!db_con)
01316 {
01317 LM_ERR("db_con is NULL\n");
01318 goto done;
01319 }
01320 if(ps->code >= 300)
01321 {
01322 LM_DBG("message <%d> was not sent successfully\n", *((int*)ps->param));
01323 msg_list_set_flag(ml, *((int*)ps->param), MS_MSG_ERRO);
01324 goto done;
01325 }
01326
01327 LM_DBG("message <%d> was sent successfully\n", *((int*)ps->param));
01328 msg_list_set_flag(ml, *((int*)ps->param), MS_MSG_DONE);
01329
01330 done:
01331 return;
01332 }
01333
01334 void m_send_ontimer(unsigned int ticks, void *param)
01335 {
01336 db_key_t db_keys[2];
01337 db_op_t db_ops[2];
01338 db_val_t db_vals[2];
01339 db_key_t db_cols[6];
01340 db1_res_t* db_res = NULL;
01341 int i, db_no_cols = 6, db_no_keys = 2, mid, n;
01342 static char hdr_buf[1024];
01343 static char uri_buf[1024];
01344 static char body_buf[1024];
01345 str puri;
01346 time_t ttime;
01347 uac_req_t uac_r;
01348 str str_vals[4], hdr_str, body_str, extra_hdrs_str;
01349 time_t stime;
01350
01351 if(ms_reminder.s==NULL)
01352 {
01353 LM_WARN("reminder address null\n");
01354 return;
01355 }
01356
01357
01358 db_keys[0]=&sc_snd_time;
01359 db_keys[1]=&sc_snd_time;
01360 db_ops[0]=OP_NEQ;
01361 db_ops[1]=OP_LEQ;
01362
01363 db_cols[0]=&sc_mid;
01364 db_cols[1]=&sc_uri_user;
01365 db_cols[2]=&sc_uri_host;
01366 db_cols[3]=&sc_body;
01367 db_cols[4]=&sc_ctype;
01368 db_cols[5]=&sc_snd_time;
01369
01370
01371 LM_DBG("------------ start ------------\n");
01372 hdr_str.s=hdr_buf;
01373 hdr_str.len=1024;
01374 body_str.s=body_buf;
01375 body_str.len=1024;
01376
01377 db_vals[0].type = DB1_INT;
01378 db_vals[0].nul = 0;
01379 db_vals[0].val.int_val = 0;
01380
01381 db_vals[1].type = DB1_INT;
01382 db_vals[1].nul = 0;
01383 ttime = time(NULL);
01384 db_vals[1].val.int_val = (int)ttime;
01385
01386 if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
01387 {
01388 LM_ERR("failed to use_table\n");
01389 return;
01390 }
01391
01392 if (msilo_dbf.query(db_con,db_keys,db_ops,db_vals,db_cols,db_no_keys,
01393 db_no_cols, NULL,&db_res) < 0) {
01394 LM_ERR("failed to query database\n");
01395 goto done;
01396 }
01397
01398 if (RES_ROW_N(db_res) <= 0)
01399 {
01400 LM_DBG("no message for <%.*s>!\n", 24, ctime((const time_t*)&ttime));
01401 goto done;
01402 }
01403
01404 LM_DBG("dumping [%d] messages for <%.*s>!!!\n", RES_ROW_N(db_res), 24,
01405 ctime((const time_t*)&ttime));
01406
01407 for(i = 0; i < RES_ROW_N(db_res); i++)
01408 {
01409 mid = RES_ROWS(db_res)[i].values[0].val.int_val;
01410 if(msg_list_check_msg(ml, mid))
01411 {
01412 LM_DBG("message[%d] mid=%d already sent.\n", i, mid);
01413 continue;
01414 }
01415
01416 memset(str_vals, 0, 4*sizeof(str));
01417 SET_STR_VAL(str_vals[0], db_res, i, 1);
01418 SET_STR_VAL(str_vals[1], db_res, i, 2);
01419 SET_STR_VAL(str_vals[2], db_res, i, 3);
01420 SET_STR_VAL(str_vals[3], db_res, i, 4);
01421
01422 extra_hdrs_str.len = 0;
01423 hdr_str.len = 1024;
01424 if(m_build_headers(&hdr_str, str_vals[3] ,
01425 ms_reminder,0,
01426 extra_hdrs_str)
01427 < 0)
01428 {
01429 LM_ERR("headers building failed [%d]\n", mid);
01430 if (msilo_dbf.free_result(db_con, db_res) < 0)
01431 LM_DBG("failed to free result of query\n");
01432 msg_list_set_flag(ml, mid, MS_MSG_ERRO);
01433 return;
01434 }
01435
01436 puri.s = uri_buf;
01437 puri.len = 4 + str_vals[0].len + 1 + str_vals[1].len;
01438 memcpy(puri.s, "sip:", 4);
01439 memcpy(puri.s+4, str_vals[0].s, str_vals[0].len);
01440 puri.s[4+str_vals[0].len] = '@';
01441 memcpy(puri.s+4+str_vals[0].len+1, str_vals[1].s, str_vals[1].len);
01442
01443 LM_DBG("msg [%d-%d] for: %.*s\n", i+1, mid, puri.len, puri.s);
01444
01446 body_str.len = 1024;
01447 stime =
01448 (time_t)RES_ROWS(db_res)[i].values[5].val.int_val;
01449 n = m_build_body(&body_str, 0, str_vals[2], stime);
01450 if(n<0)
01451 LM_DBG("sending simple body\n");
01452 else
01453 LM_DBG("sending composed body\n");
01454
01455 msg_list_set_flag(ml, mid, MS_MSG_TSND);
01456
01457
01458 memset(&uac_r, '\0', sizeof(uac_r));
01459 uac_r.method = &msg_type;
01460 uac_r.headers = &hdr_str;
01461 uac_r.body = (n<0)?&str_vals[2]:&body_str;
01462 uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
01463 uac_r.cb = m_tm_callback;
01464 uac_r.cbp = (void*)(long)mid;
01465 tmb.t_request(&uac_r,
01466 &puri,
01467 &puri,
01468 &ms_reminder,
01469 (ms_outbound_proxy.s)?&ms_outbound_proxy:0
01470 );
01471 }
01472
01473 done:
01477 if ((db_res != NULL) && msilo_dbf.free_result(db_con, db_res) < 0)
01478 LM_DBG("failed to free result of query\n");
01479
01480 return;
01481 }
01482
01483 int ms_reset_stime(int mid)
01484 {
01485 db_key_t db_keys[1];
01486 db_op_t db_ops[1];
01487 db_val_t db_vals[1];
01488 db_key_t db_cols[1];
01489 db_val_t db_cvals[1];
01490
01491 db_keys[0]=&sc_mid;
01492 db_ops[0]=OP_EQ;
01493
01494 db_vals[0].type = DB1_INT;
01495 db_vals[0].nul = 0;
01496 db_vals[0].val.int_val = mid;
01497
01498
01499 db_cols[0]=&sc_snd_time;
01500 db_cvals[0].type = DB1_INT;
01501 db_cvals[0].nul = 0;
01502 db_cvals[0].val.int_val = 0;
01503
01504 LM_DBG("updating send time for [%d]!\n", mid);
01505
01506 if (msilo_dbf.use_table(db_con, &ms_db_table) < 0)
01507 {
01508 LM_ERR("failed to use_table\n");
01509 return -1;
01510 }
01511
01512 if(msilo_dbf.update(db_con,db_keys,db_ops,db_vals,db_cols,db_cvals,1,1)!=0)
01513 {
01514 LM_ERR("failed to make update for [%d]!\n", mid);
01515 return -1;
01516 }
01517 return 0;
01518 }
01519
01520
01521
01522
01523
01524
01525 int check_message_support(struct sip_msg* msg)
01526 {
01527 contact_t* c;
01528 unsigned int allow_message = 0;
01529 unsigned int allow_hdr = 0;
01530 str *methods_body;
01531 unsigned int methods;
01532 int expires;
01533
01534
01535 if (parse_headers(msg, HDR_EOH_F, 0) == -1)
01536 {
01537 LM_ERR("failed to parse headers\n");
01538 return -1;
01539 }
01540
01541 if (parse_allow(msg) == 0)
01542 {
01543 allow_hdr = 1;
01544 allow_message = get_allow_methods(msg) & METHOD_MESSAGE;
01545 }
01546 LM_DBG("Allow message: %u\n", allow_message);
01547
01548 if (!msg->contact)
01549 {
01550 LM_DBG("no Contact found\n");
01551 return -1;
01552 }
01553 if (parse_contact(msg->contact) < 0)
01554 {
01555 LM_ERR("failed to parse Contact HF\n");
01556 return -1;
01557 }
01558 if (((contact_body_t*)msg->contact->parsed)->star)
01559 {
01560 LM_DBG("* Contact found\n");
01561 return -1;
01562 }
01563
01564 if (contact_iterator(&c, msg, 0) < 0)
01565 return -1;
01566
01567
01568
01569
01570
01571
01572 while(c)
01573 {
01574
01575 expires=1;
01576 if(c->expires==NULL || c->expires->body.len<=0)
01577 {
01578 if(msg->expires!=NULL && msg->expires->body.len>0)
01579 expires = atoi(msg->expires->body.s);
01580 } else {
01581 str2int(&c->expires->body, (unsigned int*)(&expires));
01582 }
01583
01584 if (expires > 0)
01585 {
01586 if (c->methods)
01587 {
01588 methods_body = &(c->methods->body);
01589 if (parse_methods(methods_body, &methods) < 0)
01590 {
01591 LM_ERR("failed to parse contact methods\n");
01592 return -1;
01593 }
01594 if (methods & METHOD_MESSAGE)
01595 {
01596 LM_DBG("MESSAGE contact found\n");
01597 return 0;
01598 }
01599 } else {
01600 if (allow_message)
01601 {
01602 LM_DBG("MESSAGE found in Allow Header\n");
01603 return 0;
01604 }
01605 }
01606 }
01607 if (contact_iterator(&c, msg, c) < 0)
01608 {
01609 LM_DBG("MESSAGE contact not found\n");
01610 return -1;
01611 }
01612 }
01613
01614 if(allow_hdr==0)
01615 return 0;
01616 return -1;
01617 }
01618