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 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <time.h>
00036 #include "../../sr_module.h"
00037 #include "../../dprint.h"
00038 #include "../../ut.h"
00039 #include "../../ip_addr.h"
00040 #include "../../mem/mem.h"
00041 #include "../../mem/shm_mem.h"
00042 #include "../../mi/mi.h"
00043 #include "../../db/db.h"
00044 #include "../../parser/parse_content.h"
00045 #include "../../parser/parse_from.h"
00046 #include "../../pvar.h"
00047 #include "../tm/tm_load.h"
00048 #include "../sl/sl_cb.h"
00049 #include "../../str.h"
00050
00051 MODULE_VERSION
00052
00053 struct tm_binds tmb;
00054
00055
00056 static int mod_init(void);
00057 static int child_init(int rank);
00058 static void destroy(void);
00059 static int sip_trace(struct sip_msg*, char*, char*);
00060
00061 static int trace_send_duplicate(char *buf, int len);
00062
00063 static void trace_onreq_in(struct cell* t, int type, struct tmcb_params *ps);
00064 static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps);
00065 static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps);
00066 static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps);
00067 static void trace_sl_onreply_out(unsigned int types, struct sip_msg* req, struct sl_cb_param *sl_param);
00068 static void trace_sl_ack_in(unsigned int types, struct sip_msg* req, struct sl_cb_param *sl_param);
00069
00070 static struct mi_root* sip_trace_mi(struct mi_root* cmd, void* param );
00071
00072 static str db_url = str_init(DEFAULT_RODB_URL);
00073 static str siptrace_table = str_init("sip_trace");
00074 static str date_column = str_init("time_stamp");
00075 static str callid_column = str_init("callid");
00076 static str traced_user_column = str_init("traced_user");
00077 static str msg_column = str_init("msg");
00078 static str method_column = str_init("method");
00079 static str status_column = str_init("status");
00080 static str fromip_column = str_init("fromip");
00081 static str toip_column = str_init("toip");
00082 static str fromtag_column = str_init("fromtag");
00083 static str direction_column = str_init("direction");
00084
00085 #define NR_KEYS 10
00086
00087 int trace_flag = -1;
00088 int trace_on = 0;
00089
00090 str dup_uri_str = {0, 0};
00091 struct sip_uri *dup_uri = 0;
00092
00093 int *trace_on_flag = NULL;
00094
00095 static unsigned short traced_user_avp_type = 0;
00096 static int_str traced_user_avp;
00097 static str traced_user_avp_str = {NULL, 0};
00098
00099 static unsigned short trace_table_avp_type = 0;
00100 static int_str trace_table_avp;
00101 static str trace_table_avp_str = {NULL, 0};
00102
00103 static str trace_local_ip = {NULL, 0};
00104
00105 db_con_t *db_con = NULL;
00106 db_func_t db_funcs;
00107
00108 register_slcb_t register_slcb_f=NULL;
00109
00110
00111
00112
00113 static cmd_export_t cmds[] = {
00114 {"sip_trace", (cmd_function)sip_trace, 0, 0, 0,
00115 REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00116 {0, 0, 0, 0, 0, 0}
00117 };
00118
00119
00120
00121
00122
00123 static param_export_t params[] = {
00124 {"db_url", STR_PARAM, &db_url.s },
00125 {"table", STR_PARAM, &siptrace_table.s },
00126 {"date_column", STR_PARAM, &date_column.s },
00127 {"callid_column", STR_PARAM, &callid_column.s },
00128 {"traced_user_column", STR_PARAM, &traced_user_column.s },
00129 {"msg_column", STR_PARAM, &msg_column.s },
00130 {"method_column", STR_PARAM, &method_column.s },
00131 {"status_column", STR_PARAM, &status_column.s },
00132 {"fromip_column", STR_PARAM, &fromip_column.s },
00133 {"toip_column", STR_PARAM, &toip_column.s },
00134 {"fromtag_column", STR_PARAM, &fromtag_column.s },
00135 {"direction_column", STR_PARAM, &direction_column.s },
00136 {"trace_flag", INT_PARAM, &trace_flag },
00137 {"trace_on", INT_PARAM, &trace_on },
00138 {"traced_user_avp", STR_PARAM, &traced_user_avp_str.s},
00139 {"trace_table_avp", STR_PARAM, &trace_table_avp_str.s},
00140 {"duplicate_uri", STR_PARAM, &dup_uri_str.s },
00141 {"trace_local_ip", STR_PARAM, &trace_local_ip.s },
00142 {0, 0, 0}
00143 };
00144
00145
00146
00147
00148 static mi_export_t mi_cmds[] = {
00149 { "sip_trace", sip_trace_mi, 0, 0, 0 },
00150 { 0, 0, 0, 0, 0}
00151 };
00152
00153
00154 #ifdef STATISTICS
00155 #include "../../statistics.h"
00156
00157 stat_var* siptrace_req;
00158 stat_var* siptrace_rpl;
00159
00160 stat_export_t siptrace_stats[] = {
00161 {"traced_requests" , 0, &siptrace_req },
00162 {"traced_replies" , 0, &siptrace_rpl },
00163 {0,0,0}
00164 };
00165 #endif
00166
00167
00168 struct module_exports exports = {
00169 "siptrace",
00170 DEFAULT_DLFLAGS,
00171 cmds,
00172 params,
00173 #ifdef STATISTICS
00174 siptrace_stats,
00175 #else
00176 0,
00177 #endif
00178 mi_cmds,
00179 0,
00180 0,
00181 mod_init,
00182 0,
00183 destroy,
00184 child_init
00185 };
00186
00187
00188
00189 static int mod_init(void)
00190 {
00191 pv_spec_t avp_spec;
00192
00193 db_url.len = strlen(db_url.s);
00194 siptrace_table.len = strlen(siptrace_table.s);
00195 date_column.len = strlen(date_column.s);
00196 callid_column.len = strlen(callid_column.s);
00197 traced_user_column.len = strlen(traced_user_column.s);
00198 msg_column.len = strlen(msg_column.s);
00199 method_column.len = strlen(method_column.s);
00200 status_column.len = strlen(status_column.s);
00201 fromip_column.len = strlen(fromip_column.s);
00202 toip_column.len = strlen(toip_column.s);
00203 fromtag_column.len = strlen(fromtag_column.s);
00204 direction_column.len = strlen(direction_column.s);
00205 if (traced_user_avp_str.s)
00206 traced_user_avp_str.len = strlen(traced_user_avp_str.s);
00207 if (trace_table_avp_str.s)
00208 trace_table_avp_str.len = strlen(trace_table_avp_str.s);
00209 if (dup_uri_str.s)
00210 dup_uri_str.len = strlen(dup_uri_str.s);
00211 if (trace_local_ip.s)
00212 trace_local_ip.len = strlen(trace_local_ip.s);
00213
00214 if (flag_idx2mask(&trace_flag)<0)
00215 return -1;
00216
00217
00218 if (db_bind_mod(&db_url, &db_funcs)) {
00219 LM_ERR("unable to bind database module\n");
00220 return -1;
00221 }
00222 if (!DB_CAPABILITY(db_funcs, DB_CAP_INSERT)) {
00223 LM_ERR("database modules does not provide all functions needed by module\n");
00224 return -1;
00225 }
00226
00227 trace_on_flag = (int*)shm_malloc(sizeof(int));
00228 if(trace_on_flag==NULL) {
00229 LM_ERR("no more shm memory left\n");
00230 return -1;
00231 }
00232
00233 *trace_on_flag = trace_on;
00234
00235
00236 if (load_tm_api(&tmb)!=0) {
00237 LM_ERR("can't load tm api. Is module tm loaded?\n");
00238 return -1;
00239 }
00240
00241 if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0, 0) <=0) {
00242 LM_ERR("can't register trace_onreq_in\n");
00243 return -1;
00244 }
00245
00246
00247 register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0);
00248 if(register_slcb_f==NULL) {
00249 LM_ERR("can't load sl api. Is module sl loaded?\n");
00250 return -1;
00251 }
00252 if(register_slcb_f(SLCB_REPLY_OUT,trace_sl_onreply_out, NULL)!=0) {
00253 LM_ERR("can't register trace_sl_onreply_out\n");
00254 return -1;
00255 }
00256 if(register_slcb_f(SLCB_ACK_IN,trace_sl_ack_in, NULL)!=0) {
00257 LM_ERR("can't register trace_sl_ack_in\n");
00258 return -1;
00259 }
00260
00261 if(dup_uri_str.s!=0) {
00262 dup_uri_str.len = strlen(dup_uri_str.s);
00263 dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri));
00264 if(dup_uri==0) {
00265 LM_ERR("no more pkg memory left\n");
00266 return -1;
00267 }
00268 memset(dup_uri, 0, sizeof(struct sip_uri));
00269 if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0) {
00270 LM_ERR("bad dup uri\n");
00271 return -1;
00272 }
00273 }
00274
00275 if(traced_user_avp_str.s && traced_user_avp_str.len > 0) {
00276 if (pv_parse_spec(&traced_user_avp_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
00277 LM_ERR("malformed or non AVP %.*s AVP definition\n", traced_user_avp_str.len, traced_user_avp_str.s);
00278 return -1;
00279 }
00280
00281 if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp, &traced_user_avp_type)!=0) {
00282 LM_ERR("[%.*s] - invalid AVP definition\n", traced_user_avp_str.len, traced_user_avp_str.s);
00283 return -1;
00284 }
00285 } else {
00286 traced_user_avp.n = 0;
00287 traced_user_avp_type = 0;
00288 }
00289 if(trace_table_avp_str.s && trace_table_avp_str.len > 0) {
00290 if (pv_parse_spec(&trace_table_avp_str, &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
00291 LM_ERR("malformed or non AVP %.*s AVP definition\n", trace_table_avp_str.len, trace_table_avp_str.s);
00292 return -1;
00293 }
00294
00295 if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp, &trace_table_avp_type)!=0) {
00296 LM_ERR("[%.*s] - invalid AVP definition\n", trace_table_avp_str.len, trace_table_avp_str.s);
00297 return -1;
00298 }
00299 } else {
00300 trace_table_avp.n = 0;
00301 trace_table_avp_type = 0;
00302 }
00303
00304 return 0;
00305 }
00306
00307
00308 static int child_init(int rank)
00309 {
00310 db_con = db_funcs.init(&db_url);
00311 if (!db_con) {
00312 LM_ERR("unable to connect to database. Please check configuration.\n");
00313 return -1;
00314 }
00315
00316 return 0;
00317 }
00318
00319
00320 static void destroy(void)
00321 {
00322 if (db_con!=NULL)
00323 db_funcs.close(db_con);
00324 if (trace_on_flag)
00325 shm_free(trace_on_flag);
00326 }
00327
00328 static inline int siptrace_copy_proto(int proto, char *buf)
00329 {
00330 if(buf==0)
00331 return -1;
00332 if(proto==PROTO_TCP) {
00333 strcpy(buf, "tcp:");
00334 } else if(proto==PROTO_TLS) {
00335 strcpy(buf, "tls:");
00336 } else if(proto==PROTO_SCTP) {
00337 strcpy(buf, "sctp:");
00338 } else {
00339 strcpy(buf, "udp:");
00340 }
00341 return 0;
00342 }
00343
00344 static inline str* siptrace_get_table(void)
00345 {
00346 static int_str avp_value;
00347 struct usr_avp *avp;
00348
00349 if(trace_table_avp.n==0)
00350 return &siptrace_table;
00351
00352 avp = NULL;
00353 if(trace_table_avp.n!=0)
00354 avp=search_first_avp(trace_table_avp_type, trace_table_avp, &avp_value, 0);
00355
00356 if(avp==NULL || !is_avp_str_val(avp) || avp_value.s.len<=0)
00357 return &siptrace_table;
00358
00359 return &avp_value.s;
00360 }
00361
00362 static int sip_trace(struct sip_msg *msg, char *s1, char *s2)
00363 {
00364 db_key_t db_keys[NR_KEYS];
00365 db_val_t db_vals[NR_KEYS];
00366 static char toip_buff[IP_ADDR_MAX_STR_SIZE+6];
00367 static char fromip_buff[IP_ADDR_MAX_STR_SIZE+6];
00368 int_str avp_value;
00369 struct usr_avp *avp;
00370
00371 if(msg==NULL) {
00372 LM_DBG("no uas request, local transaction\n");
00373 return -1;
00374 }
00375
00376 avp = NULL;
00377 if(traced_user_avp.n!=0)
00378 avp=search_first_avp(traced_user_avp_type, traced_user_avp, &avp_value, 0);
00379
00380 if((avp==NULL) && (trace_on_flag==NULL || *trace_on_flag==0)) {
00381 LM_DBG("trace off...\n");
00382 return -1;
00383 }
00384
00385 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) {
00386 LM_ERR("cannot parse FROM header\n");
00387 goto error;
00388 }
00389
00390 if(parse_headers(msg, HDR_CALLID_F, 0)!=0 || msg->callid==NULL || msg->callid->body.s==NULL) {
00391 LM_ERR("cannot parse call-id\n");
00392 goto error;
00393 }
00394
00395 db_keys[0] = &msg_column;
00396 db_vals[0].type = DB_BLOB;
00397 db_vals[0].nul = 0;
00398 db_vals[0].val.blob_val.s = msg->buf;
00399 db_vals[0].val.blob_val.len = msg->len;
00400
00401 db_keys[1] = &callid_column;
00402 db_vals[1].type = DB_STR;
00403 db_vals[1].nul = 0;
00404 db_vals[1].val.str_val.s = msg->callid->body.s;
00405 db_vals[1].val.str_val.len = msg->callid->body.len;
00406
00407 db_keys[2] = &method_column;
00408 db_vals[2].type = DB_STR;
00409 db_vals[2].nul = 0;
00410 if(msg->first_line.type==SIP_REQUEST) {
00411 db_vals[2].val.str_val.s = msg->first_line.u.request.method.s;
00412 db_vals[2].val.str_val.len = msg->first_line.u.request.method.len;
00413 } else {
00414 db_vals[2].val.str_val.s = "";
00415 db_vals[2].val.str_val.len = 0;
00416 }
00417
00418 db_keys[3] = &status_column;
00419 db_vals[3].type = DB_STR;
00420 db_vals[3].nul = 0;
00421 if(msg->first_line.type==SIP_REPLY) {
00422 db_vals[3].val.str_val.s = msg->first_line.u.reply.status.s;
00423 db_vals[3].val.str_val.len = msg->first_line.u.reply.status.len;
00424 } else {
00425 db_vals[3].val.str_val.s = "";
00426 db_vals[3].val.str_val.len = 0;
00427 }
00428
00429 db_keys[4] = &fromip_column;
00430 db_vals[4].type = DB_STRING;
00431 db_vals[4].nul = 0;
00432 siptrace_copy_proto(msg->rcv.proto, fromip_buff);
00433 strcat(fromip_buff, ip_addr2a(&msg->rcv.src_ip));
00434 strcat(fromip_buff,":");
00435 strcat(fromip_buff, int2str(msg->rcv.src_port, NULL));
00436 db_vals[4].val.string_val = fromip_buff;
00437
00438 db_keys[5] = &toip_column;
00439 db_vals[5].type = DB_STRING;
00440 db_vals[5].nul = 0;
00441
00442 siptrace_copy_proto(msg->rcv.proto, toip_buff);
00443 strcat(toip_buff, ip_addr2a(&msg->rcv.dst_ip));
00444 strcat(toip_buff,":");
00445 strcat(toip_buff, int2str(msg->rcv.dst_port, NULL));
00446 db_vals[5].val.string_val = toip_buff;
00447
00448 db_keys[6] = &date_column;
00449 db_vals[6].type = DB_DATETIME;
00450 db_vals[6].nul = 0;
00451 db_vals[6].val.time_val = time(NULL);
00452
00453 db_keys[7] = &direction_column;
00454 db_vals[7].type = DB_STRING;
00455 db_vals[7].nul = 0;
00456 db_vals[7].val.string_val = "in";
00457
00458 db_keys[8] = &fromtag_column;
00459 db_vals[8].type = DB_STR;
00460 db_vals[8].nul = 0;
00461 db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
00462 db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
00463
00464 db_funcs.use_table(db_con, siptrace_get_table());
00465
00466 db_keys[9] = &traced_user_column;
00467 db_vals[9].type = DB_STR;
00468 db_vals[9].nul = 0;
00469
00470 if(trace_on_flag!=NULL && *trace_on_flag!=0) {
00471 db_vals[9].val.str_val.s = "";
00472 db_vals[9].val.str_val.len = 0;
00473
00474 LM_DBG("storing info...\n");
00475 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00476 LM_ERR("error storing trace\n");
00477 goto error;
00478 }
00479 #ifdef STATISTICS
00480 if(msg->first_line.type==SIP_REPLY) {
00481 update_stat(siptrace_rpl, 1);
00482 } else {
00483 update_stat(siptrace_req, 1);
00484 }
00485 #endif
00486 }
00487
00488 if(avp==NULL)
00489 goto done;
00490
00491 trace_send_duplicate(db_vals[0].val.blob_val.s, db_vals[0].val.blob_val.len);
00492
00493 db_vals[9].val.str_val.s = avp_value.s.s;
00494 db_vals[9].val.str_val.len = avp_value.s.len;
00495
00496 LM_DBG("storing info...\n");
00497 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00498 LM_ERR("error storing trace\n");
00499 goto error;
00500 }
00501
00502 avp = search_next_avp( avp, &avp_value);
00503 while(avp!=NULL) {
00504 db_vals[9].val.str_val.s = avp_value.s.s;
00505 db_vals[9].val.str_val.len = avp_value.s.len;
00506
00507 LM_DBG("storing info...\n");
00508 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00509 LM_ERR("error storing trace\n");
00510 goto error;
00511 }
00512 avp = search_next_avp( avp, &avp_value);
00513 }
00514
00515 done:
00516 return 1;
00517 error:
00518 return -1;
00519 }
00520
00521 #define trace_is_off(_msg) \
00522 (trace_on_flag==NULL || *trace_on_flag==0 || \
00523 ((_msg)->flags&trace_flag)==0)
00524
00525 static void trace_onreq_in(struct cell* t, int type, struct tmcb_params *ps)
00526 {
00527 struct sip_msg* msg;
00528 int_str avp_value;
00529 struct usr_avp* avp;
00530
00531 if(t==NULL || ps==NULL) {
00532 LM_DBG("no uas request, local transaction\n");
00533 return;
00534 }
00535
00536 msg = ps->req;
00537 if(msg==NULL) {
00538 LM_DBG("no uas request, local transaction\n");
00539 return;
00540 }
00541
00542 avp = NULL;
00543 if(traced_user_avp.n!=0)
00544 avp=search_first_avp(traced_user_avp_type, traced_user_avp, &avp_value, 0);
00545
00546 if((avp==NULL) && trace_is_off(msg)) {
00547 LM_DBG("trace off...\n");
00548 return;
00549 }
00550
00551 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) {
00552 LM_ERR("cannot parse FROM header\n");
00553 return;
00554 }
00555
00556 if(parse_headers(msg, HDR_CALLID_F, 0)!=0) {
00557 LM_ERR("cannot parse call-id\n");
00558 return;
00559 }
00560
00561 if(tmb.register_tmcb( 0, t, TMCB_REQUEST_BUILT, trace_onreq_out, 0, 0) <=0) {
00562 LM_ERR("can't register trace_onreq_out\n");
00563 return;
00564 }
00565
00566 if(tmb.register_tmcb( 0, t, TMCB_RESPONSE_IN, trace_onreply_in, 0, 0) <=0) {
00567 LM_ERR("can't register trace_onreply_in\n");
00568 return;
00569 }
00570
00571 if(tmb.register_tmcb( 0, t, TMCB_RESPONSE_OUT, trace_onreply_out, 0, 0) <=0) {
00572 LM_ERR("can't register trace_onreply_out\n");
00573 return;
00574 }
00575 }
00576
00577 static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps)
00578 {
00579 db_key_t db_keys[NR_KEYS];
00580 db_val_t db_vals[NR_KEYS];
00581 static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
00582 static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
00583 struct sip_msg* msg;
00584 int_str avp_value;
00585 struct usr_avp *avp;
00586 struct ip_addr to_ip;
00587 int len;
00588 str *sbuf;
00589 struct dest_info *dst;
00590
00591 if(t==NULL || ps==NULL) {
00592 LM_DBG("no uas request, local transaction\n");
00593 return;
00594 }
00595 msg=ps->req;
00596 if(msg==NULL) {
00597 LM_DBG("no uas msg, local transaction\n");
00598 return;
00599 }
00600
00601 avp = NULL;
00602 if(traced_user_avp.n!=0)
00603 avp=search_first_avp(traced_user_avp_type, traced_user_avp, &avp_value, 0);
00604
00605 if((avp==NULL) && trace_is_off(msg) ) {
00606 LM_DBG("trace off...\n");
00607 return;
00608 }
00609
00610 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) {
00611 LM_ERR("cannot parse FROM header\n");
00612 goto error;
00613 }
00614
00615 if(parse_headers(msg, HDR_CALLID_F, 0)!=0) {
00616 LM_ERR("cannot parse call-id\n");
00617 return;
00618 }
00619
00620 db_keys[0] = &msg_column;
00621 db_vals[0].type = DB_BLOB;
00622 db_vals[0].nul = 0;
00623 sbuf = (str*)ps->extra1;
00624 if(sbuf!=NULL && sbuf->len>0) {
00625 db_vals[0].val.blob_val.s = sbuf->s;
00626 db_vals[0].val.blob_val.len = sbuf->len;
00627 } else {
00628 db_vals[0].val.blob_val.s = "No request buffer";
00629 db_vals[0].val.blob_val.len = sizeof("No request buffer")-1;
00630 }
00631
00632
00633 if(msg->callid==NULL || msg->callid->body.s==NULL) {
00634 LM_ERR("cannot find Call-ID header!\n");
00635 goto error;
00636 }
00637
00638 db_keys[1] = &callid_column;
00639 db_vals[1].type = DB_STR;
00640 db_vals[1].nul = 0;
00641 db_vals[1].val.str_val.s = msg->callid->body.s;
00642 db_vals[1].val.str_val.len = msg->callid->body.len;
00643
00644 db_keys[2] = &method_column;
00645 db_vals[2].type = DB_STR;
00646 db_vals[2].nul = 0;
00647 sbuf = (str*)ps->extra1;
00648 if(sbuf!=NULL && sbuf->len > 7 && !strncasecmp(sbuf->s, "CANCEL ", 7)) {
00649 db_vals[2].val.str_val.s = "CANCEL";
00650 db_vals[2].val.str_val.len = 6;
00651 } else {
00652 db_vals[2].val.str_val.s = t->method.s;
00653 db_vals[2].val.str_val.len = t->method.len;
00654 }
00655
00656 db_keys[3] = &status_column;
00657 db_vals[3].type = DB_STR;
00658 db_vals[3].nul = 0;
00659 db_vals[3].val.str_val.s = "";
00660 db_vals[3].val.str_val.len = 0;
00661
00662 memset(&to_ip, 0, sizeof(struct ip_addr));
00663 dst = (struct dest_info*)ps->extra2;
00664
00665 db_keys[4] = &fromip_column;
00666 db_vals[4].type = DB_STRING;
00667 db_vals[4].nul = 0;
00668 if (trace_local_ip.s && trace_local_ip.len > 0) {
00669 db_vals[4].val.string_val = trace_local_ip.s;
00670 } else {
00671 if(dst==0 || dst->send_sock==0 || dst->send_sock->sock_str.s==0) {
00672 siptrace_copy_proto(msg->rcv.proto, fromip_buff);
00673 strcat(fromip_buff, ip_addr2a(&msg->rcv.dst_ip));
00674 strcat(fromip_buff,":");
00675 strcat(fromip_buff, int2str(msg->rcv.dst_port, NULL));
00676 db_vals[4].val.string_val = fromip_buff;
00677 } else {
00678 db_vals[4].type = DB_STR;
00679 db_vals[4].val.str_val = dst->send_sock->sock_str;
00680 }
00681 }
00682
00683 db_keys[5] = &toip_column;
00684 db_vals[5].type = DB_STRING;
00685 db_vals[5].nul = 0;
00686 if(dst==0) {
00687 db_vals[5].val.string_val = "any:255.255.255.255";
00688 } else {
00689 su2ip_addr(&to_ip, &dst->to);
00690 siptrace_copy_proto(dst->proto, toip_buff);
00691 strcat(toip_buff, ip_addr2a(&to_ip));
00692 strcat(toip_buff, ":");
00693 strcat(toip_buff,
00694 int2str((unsigned long)su_getport(&dst->to), &len));
00695 LM_DBG("dest [%s]\n", toip_buff);
00696 db_vals[5].val.string_val = toip_buff;
00697 }
00698
00699 db_keys[6] = &date_column;
00700 db_vals[6].type = DB_DATETIME;
00701 db_vals[6].nul = 0;
00702 db_vals[6].val.time_val = time(NULL);
00703
00704 db_keys[7] = &direction_column;
00705 db_vals[7].type = DB_STRING;
00706 db_vals[7].nul = 0;
00707 db_vals[7].val.string_val = "out";
00708
00709 db_keys[8] = &fromtag_column;
00710 db_vals[8].type = DB_STR;
00711 db_vals[8].nul = 0;
00712 db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
00713 db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
00714
00715 db_funcs.use_table(db_con, siptrace_get_table());
00716
00717 db_keys[9] = &traced_user_column;
00718 db_vals[9].type = DB_STR;
00719 db_vals[9].nul = 0;
00720
00721 if( !trace_is_off(msg) ) {
00722 db_vals[9].val.str_val.s = "";
00723 db_vals[9].val.str_val.len = 0;
00724
00725 LM_DBG("storing info...\n");
00726 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00727 LM_ERR("error storing trace\n");
00728 goto error;
00729 }
00730 #ifdef STATISTICS
00731 update_stat(siptrace_req, 1);
00732 #endif
00733 }
00734
00735 if(avp==NULL)
00736 goto done;
00737
00738 trace_send_duplicate(db_vals[0].val.blob_val.s, db_vals[0].val.blob_val.len);
00739
00740 db_vals[9].val.str_val.s = avp_value.s.s;
00741 db_vals[9].val.str_val.len = avp_value.s.len;
00742
00743 LM_DBG("storing info...\n");
00744 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00745 LM_ERR("error storing trace\n");
00746 goto error;
00747 }
00748
00749 avp = search_next_avp(avp, &avp_value);
00750 while(avp!=NULL) {
00751 db_vals[9].val.str_val.s = avp_value.s.s;
00752 db_vals[9].val.str_val.len = avp_value.s.len;
00753
00754 LM_DBG("storing info...\n");
00755 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00756 LM_ERR("error storing trace\n");
00757 goto error;
00758 }
00759 avp = search_next_avp( avp, &avp_value);
00760 }
00761
00762 done:
00763 return;
00764 error:
00765 return;
00766 }
00767
00768 static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps)
00769 {
00770 db_key_t db_keys[NR_KEYS];
00771 db_val_t db_vals[NR_KEYS];
00772
00773 static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
00774 static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
00775 struct sip_msg* msg;
00776 struct sip_msg* req;
00777 int_str avp_value;
00778 struct usr_avp *avp;
00779 char statusbuf[8];
00780
00781 if(t==NULL || t->uas.request==0 || ps==NULL) {
00782 LM_DBG("no uas request, local transaction\n");
00783 return;
00784 }
00785
00786 req = ps->req;
00787 msg = ps->rpl;
00788 if(msg==NULL || req==NULL) {
00789 LM_DBG("no reply\n");
00790 return;
00791 }
00792
00793 avp = NULL;
00794 if(traced_user_avp.n!=0)
00795 avp=search_first_avp(traced_user_avp_type, traced_user_avp, &avp_value, 0);
00796
00797 if((avp==NULL) && trace_is_off(req)) {
00798 LM_DBG("trace off...\n");
00799 return;
00800 }
00801
00802 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) {
00803 LM_ERR("cannot parse FROM header\n");
00804 goto error;
00805 }
00806
00807 if(parse_headers(msg, HDR_CALLID_F, 0)!=0) {
00808 LM_ERR("cannot parse call-id\n");
00809 return;
00810 }
00811
00812 db_keys[0] = &msg_column;
00813 db_vals[0].type = DB_BLOB;
00814 db_vals[0].nul = 0;
00815 if(msg->len>0) {
00816 db_vals[0].val.blob_val.s = msg->buf;
00817 db_vals[0].val.blob_val.len = msg->len;
00818 } else {
00819 db_vals[0].val.blob_val.s = "No reply buffer";
00820 db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
00821 }
00822
00823
00824 if(msg->callid==NULL || msg->callid->body.s==NULL) {
00825 LM_ERR("cannot find Call-ID header!\n");
00826 goto error;
00827 }
00828
00829 db_keys[1] = &callid_column;
00830 db_vals[1].type = DB_STR;
00831 db_vals[1].nul = 0;
00832 db_vals[1].val.str_val.s = msg->callid->body.s;
00833 db_vals[1].val.str_val.len = msg->callid->body.len;
00834
00835 db_keys[2] = &method_column;
00836 db_vals[2].type = DB_STR;
00837 db_vals[2].nul = 0;
00838 db_vals[2].val.str_val.s = t->method.s;
00839 db_vals[2].val.str_val.len = t->method.len;
00840
00841 db_keys[3] = &status_column;
00842 db_vals[3].type = DB_STRING;
00843 db_vals[3].nul = 0;
00844 strcpy(statusbuf, int2str(ps->code, NULL));
00845 db_vals[3].val.string_val = statusbuf;
00846
00847 db_keys[4] = &fromip_column;
00848 db_vals[4].type = DB_STRING;
00849 db_vals[4].nul = 0;
00850 siptrace_copy_proto(msg->rcv.proto, fromip_buff);
00851 strcat(fromip_buff, ip_addr2a(&msg->rcv.src_ip));
00852 strcat(fromip_buff,":");
00853 strcat(fromip_buff, int2str(msg->rcv.src_port, NULL));
00854 db_vals[4].val.string_val = fromip_buff;
00855
00856 db_keys[5] = &toip_column;
00857 db_vals[5].type = DB_STRING;
00858 db_vals[5].nul = 0;
00859
00860 if(trace_local_ip.s && trace_local_ip.len > 0) {
00861 db_vals[5].val.string_val = trace_local_ip.s;
00862 } else {
00863 siptrace_copy_proto(msg->rcv.proto, toip_buff);
00864 strcat(toip_buff, ip_addr2a(&msg->rcv.dst_ip));
00865 strcat(toip_buff,":");
00866 strcat(toip_buff, int2str(msg->rcv.dst_port, NULL));
00867 db_vals[5].val.string_val = toip_buff;
00868 }
00869
00870 db_keys[6] = &date_column;
00871 db_vals[6].type = DB_DATETIME;
00872 db_vals[6].nul = 0;
00873 db_vals[6].val.time_val = time(NULL);
00874
00875 db_keys[7] = &direction_column;
00876 db_vals[7].type = DB_STRING;
00877 db_vals[7].nul = 0;
00878 db_vals[7].val.string_val = "in";
00879
00880 db_keys[8] = &fromtag_column;
00881 db_vals[8].type = DB_STR;
00882 db_vals[8].nul = 0;
00883 db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
00884 db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
00885
00886 db_funcs.use_table(db_con, siptrace_get_table());
00887
00888 db_keys[9] = &traced_user_column;
00889 db_vals[9].type = DB_STR;
00890 db_vals[9].nul = 0;
00891
00892 if( !trace_is_off(req) ) {
00893 db_vals[9].val.str_val.s = "";
00894 db_vals[9].val.str_val.len = 0;
00895
00896 LM_DBG("storing info...\n");
00897 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00898 LM_ERR("error storing trace\n");
00899 goto error;
00900 }
00901 #ifdef STATISTICS
00902 update_stat(siptrace_rpl, 1);
00903 #endif
00904 }
00905
00906 if(avp==NULL)
00907 goto done;
00908
00909 trace_send_duplicate(db_vals[0].val.blob_val.s, db_vals[0].val.blob_val.len);
00910
00911 db_vals[9].val.str_val.s = avp_value.s.s;
00912 db_vals[9].val.str_val.len = avp_value.s.len;
00913
00914 LM_DBG("storing info...\n");
00915 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00916 LM_ERR("error storing trace\n");
00917 goto error;
00918 }
00919
00920 avp = search_next_avp( avp, &avp_value);
00921 while(avp!=NULL) {
00922 db_vals[9].val.str_val.s = avp_value.s.s;
00923 db_vals[9].val.str_val.len = avp_value.s.len;
00924
00925 LM_DBG("storing info ...\n");
00926 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
00927 LM_ERR("error storing trace\n");
00928 goto error;
00929 }
00930 avp = search_next_avp( avp, &avp_value);
00931 }
00932
00933 done:
00934 return;
00935 error:
00936 return;
00937 }
00938
00939 static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps)
00940 {
00941 db_key_t db_keys[NR_KEYS];
00942 db_val_t db_vals[NR_KEYS];
00943 int faked = 0;
00944 static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
00945 static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
00946 struct sip_msg* msg;
00947 struct sip_msg* req;
00948 int_str avp_value;
00949 struct usr_avp *avp;
00950 struct ip_addr to_ip;
00951 int len;
00952 char statusbuf[8];
00953 str *sbuf;
00954 struct dest_info *dst;
00955
00956 if (t==NULL || t->uas.request==0 || ps==NULL) {
00957 LM_DBG("no uas request, local transaction\n");
00958 return;
00959 }
00960
00961 avp = NULL;
00962 if(traced_user_avp.n!=0)
00963 avp=search_first_avp(traced_user_avp_type, traced_user_avp, &avp_value, 0);
00964
00965 if((avp==NULL) && trace_is_off(t->uas.request)) {
00966 LM_DBG("trace off...\n");
00967 return;
00968 }
00969
00970 req = ps->req;
00971 msg = ps->rpl;
00972 if(msg==NULL || msg==FAKED_REPLY) {
00973 msg = t->uas.request;
00974 faked = 1;
00975 }
00976
00977 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) {
00978 LM_ERR("cannot parse FROM header\n");
00979 goto error;
00980 }
00981
00982 if(parse_headers(msg, HDR_CALLID_F, 0)!=0) {
00983 LM_ERR("cannot parse call-id\n");
00984 return;
00985 }
00986
00987 db_keys[0] = &msg_column;
00988 db_vals[0].type = DB_BLOB;
00989 db_vals[0].nul = 0;
00990 sbuf = (str*)ps->extra1;
00991 if(faked==0) {
00992 if(sbuf!=0 && sbuf->len>0) {
00993 db_vals[0].val.blob_val.s = sbuf->s;
00994 db_vals[0].val.blob_val.len = sbuf->len;
00995 } else if(t->uas.response.buffer.s!=NULL) {
00996 db_vals[0].val.blob_val.s = t->uas.response.buffer.s;
00997 db_vals[0].val.blob_val.len = t->uas.response.buffer.len;
00998 } else if(msg->len>0) {
00999 db_vals[0].val.blob_val.s = msg->buf;
01000 db_vals[0].val.blob_val.len = msg->len;
01001 } else {
01002 db_vals[0].val.blob_val.s = "No reply buffer";
01003 db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
01004 }
01005 } else {
01006 if(sbuf!=0 && sbuf->len>0) {
01007 db_vals[0].val.blob_val.s = sbuf->s;
01008 db_vals[0].val.blob_val.len = sbuf->len;
01009 } else if(t->uas.response.buffer.s==NULL) {
01010 db_vals[0].val.blob_val.s = "No reply buffer";
01011 db_vals[0].val.blob_val.len = sizeof("No reply buffer")-1;
01012 } else {
01013 db_vals[0].val.blob_val.s = t->uas.response.buffer.s;
01014 db_vals[0].val.blob_val.len = t->uas.response.buffer.len;
01015 }
01016 }
01017
01018
01019 if(msg->callid==NULL || msg->callid->body.s==NULL) {
01020 LM_ERR("cannot find Call-ID header!\n");
01021 goto error;
01022 }
01023
01024 db_keys[1] = &callid_column;
01025 db_vals[1].type = DB_STR;
01026 db_vals[1].nul = 0;
01027 db_vals[1].val.str_val.s = msg->callid->body.s;
01028 db_vals[1].val.str_val.len = msg->callid->body.len;
01029
01030 db_keys[2] = &method_column;
01031 db_vals[2].type = DB_STR;
01032 db_vals[2].nul = 0;
01033 db_vals[2].val.str_val.s = t->method.s;
01034 db_vals[2].val.str_val.len = t->method.len;
01035
01036 db_keys[4] = &fromip_column;
01037 db_vals[4].type = DB_STRING;
01038 db_vals[4].nul = 0;
01039
01040 if(trace_local_ip.s && trace_local_ip.len > 0) {
01041 db_vals[4].val.string_val = trace_local_ip.s;
01042 } else {
01043 siptrace_copy_proto(msg->rcv.proto, fromip_buff);
01044
01045 strcat(fromip_buff, ip_addr2a(&req->rcv.dst_ip));
01046 strcat(fromip_buff,":");
01047 strcat(fromip_buff, int2str(req->rcv.dst_port, NULL));
01048 db_vals[4].val.string_val = fromip_buff;
01049 }
01050
01051 db_keys[3] = &status_column;
01052 db_vals[3].type = DB_STRING;
01053 db_vals[3].nul = 0;
01054 strcpy(statusbuf, int2str(ps->code, NULL));
01055 db_vals[3].val.string_val = statusbuf;
01056
01057 db_keys[5] = &toip_column;
01058 db_vals[5].type = DB_STRING;
01059 db_vals[5].nul = 0;
01060 memset(&to_ip, 0, sizeof(struct ip_addr));
01061 dst = (struct dest_info*)ps->extra2;
01062 if(dst==0) {
01063 db_vals[5].val.string_val = "any:255.255.255.255";
01064 } else {
01065 su2ip_addr(&to_ip, &dst->to);
01066 siptrace_copy_proto(dst->proto, toip_buff);
01067 strcat(toip_buff, ip_addr2a(&to_ip));
01068 strcat(toip_buff, ":");
01069 strcat(toip_buff, int2str((unsigned long)su_getport(&dst->to), &len));
01070 LM_DBG("dest [%s]\n", toip_buff);
01071 db_vals[5].val.string_val = toip_buff;
01072 }
01073
01074 db_keys[6] = &date_column;
01075 db_vals[6].type = DB_DATETIME;
01076 db_vals[6].nul = 0;
01077 db_vals[6].val.time_val = time(NULL);
01078
01079 db_keys[7] = &direction_column;
01080 db_vals[7].type = DB_STRING;
01081 db_vals[7].nul = 0;
01082 db_vals[7].val.string_val = "out";
01083
01084 db_keys[8] = &fromtag_column;
01085 db_vals[8].type = DB_STR;
01086 db_vals[8].nul = 0;
01087 db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
01088 db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
01089
01090 db_funcs.use_table(db_con, siptrace_get_table());
01091
01092 db_keys[9] = &traced_user_column;
01093 db_vals[9].type = DB_STR;
01094 db_vals[9].nul = 0;
01095
01096 if( !trace_is_off(req) ) {
01097 db_vals[9].val.str_val.s = "";
01098 db_vals[9].val.str_val.len = 0;
01099
01100 LM_DBG("storing info...\n");
01101 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
01102 LM_ERR("error storing trace\n");
01103 goto error;
01104 }
01105 #ifdef STATISTICS
01106 update_stat(siptrace_rpl, 1);
01107 #endif
01108 }
01109
01110 if(avp==NULL)
01111 goto done;
01112
01113 trace_send_duplicate(db_vals[0].val.blob_val.s, db_vals[0].val.blob_val.len);
01114
01115 db_vals[9].val.str_val.s = avp_value.s.s;
01116 db_vals[9].val.str_val.len = avp_value.s.len;
01117
01118 LM_DBG("storing info...\n");
01119 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
01120 LM_ERR("error storing trace\n");
01121 goto error;
01122 }
01123
01124 avp = search_next_avp( avp, &avp_value);
01125 while(avp!=NULL)
01126 {
01127 db_vals[9].val.str_val.s = avp_value.s.s;
01128 db_vals[9].val.str_val.len = avp_value.s.len;
01129
01130 LM_DBG("### - storing info (%d) ...\n", faked);
01131 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
01132 LM_ERR("error storing trace\n");
01133 goto error;
01134 }
01135 avp = search_next_avp( avp, &avp_value);
01136 }
01137
01138 done:
01139 return;
01140 error:
01141 return;
01142 }
01143
01144 static void trace_sl_ack_in( unsigned int types, struct sip_msg* req, struct sl_cb_param *sl_param)
01145 {
01146 LM_DBG("storing ack...\n");
01147 sip_trace(req, 0, 0);
01148 }
01149
01150 static void trace_sl_onreply_out( unsigned int types, struct sip_msg* req, struct sl_cb_param *sl_param)
01151 {
01152 db_key_t db_keys[NR_KEYS];
01153 db_val_t db_vals[NR_KEYS];
01154 static char fromip_buff[IP_ADDR_MAX_STR_SIZE+12];
01155 static char toip_buff[IP_ADDR_MAX_STR_SIZE+12];
01156 int faked = 0;
01157 struct sip_msg* msg;
01158 int_str avp_value;
01159 struct usr_avp *avp;
01160 struct ip_addr to_ip;
01161 int len;
01162 char statusbuf[5];
01163
01164 if(req==NULL || sl_param==NULL)
01165 {
01166 LM_ERR("bad parameters\n");
01167 goto error;
01168 }
01169
01170 avp = NULL;
01171 if(traced_user_avp.n!=0)
01172 avp=search_first_avp(traced_user_avp_type, traced_user_avp, &avp_value, 0);
01173
01174 if((avp==NULL) && trace_is_off(req)) {
01175 LM_DBG("trace off...\n");
01176 return;
01177 }
01178
01179 msg = req;
01180 faked = 1;
01181
01182 if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) {
01183 LM_ERR("cannot parse FROM header\n");
01184 goto error;
01185 }
01186
01187 if(parse_headers(msg, HDR_CALLID_F, 0)!=0) {
01188 LM_ERR("cannot parse call-id\n");
01189 return;
01190 }
01191
01192 db_keys[0] = &msg_column;
01193 db_vals[0].type = DB_BLOB;
01194 db_vals[0].nul = 0;
01195 db_vals[0].val.blob_val.s = (sl_param->buffer)?sl_param->buffer->s:"";
01196 db_vals[0].val.blob_val.len = (sl_param->buffer)?sl_param->buffer->len:0;
01197
01198
01199 if(msg->callid==NULL || msg->callid->body.s==NULL) {
01200 LM_ERR("cannot find Call-ID header!\n");
01201 goto error;
01202 }
01203
01204 db_keys[1] = &callid_column;
01205 db_vals[1].type = DB_STR;
01206 db_vals[1].nul = 0;
01207 db_vals[1].val.str_val.s = msg->callid->body.s;
01208 db_vals[1].val.str_val.len = msg->callid->body.len;
01209
01210 db_keys[2] = &method_column;
01211 db_vals[2].type = DB_STR;
01212 db_vals[2].nul = 0;
01213 db_vals[2].val.str_val.s = msg->first_line.u.request.method.s;
01214 db_vals[2].val.str_val.len = msg->first_line.u.request.method.len;
01215
01216 db_keys[4] = &fromip_column;
01217 db_vals[4].type = DB_STRING;
01218 db_vals[4].nul = 0;
01219 if(trace_local_ip.s && trace_local_ip.len > 0) {
01220 db_vals[4].val.string_val = trace_local_ip.s;
01221 } else {
01222 siptrace_copy_proto(msg->rcv.proto, fromip_buff);
01223
01224 strcat(fromip_buff, ip_addr2a(&req->rcv.dst_ip));
01225 strcat(fromip_buff,":");
01226 strcat(fromip_buff, int2str(req->rcv.dst_port, NULL));
01227 db_vals[4].val.string_val = fromip_buff;
01228 }
01229
01230 db_keys[3] = &status_column;
01231 db_vals[3].type = DB_STRING;
01232 db_vals[3].nul = 0;
01233 strcpy(statusbuf, int2str(sl_param->code, NULL));
01234 db_vals[3].val.string_val = statusbuf;
01235
01236 db_keys[5] = &toip_column;
01237 db_vals[5].type = DB_STRING;
01238 db_vals[5].nul = 0;
01239 memset(&to_ip, 0, sizeof(struct ip_addr));
01240 if(sl_param->dst==0)
01241 {
01242 db_vals[5].val.string_val = "any:255.255.255.255";
01243 } else {
01244 su2ip_addr(&to_ip, sl_param->dst);
01245 siptrace_copy_proto(req->rcv.proto, toip_buff);
01246
01247 strcat(toip_buff, ip_addr2a(&to_ip));
01248 strcat(toip_buff, ":");
01249 strcat(toip_buff,
01250 int2str((unsigned long)su_getport(sl_param->dst), &len));
01251 LM_DBG("dest [%s]\n", toip_buff);
01252 db_vals[5].val.string_val = toip_buff;
01253 }
01254
01255 db_keys[6] = &date_column;
01256 db_vals[6].type = DB_DATETIME;
01257 db_vals[6].nul = 0;
01258 db_vals[6].val.time_val = time(NULL);
01259
01260 db_keys[7] = &direction_column;
01261 db_vals[7].type = DB_STRING;
01262 db_vals[7].nul = 0;
01263 db_vals[7].val.string_val = "out";
01264
01265 db_keys[8] = &fromtag_column;
01266 db_vals[8].type = DB_STR;
01267 db_vals[8].nul = 0;
01268 db_vals[8].val.str_val.s = get_from(msg)->tag_value.s;
01269 db_vals[8].val.str_val.len = get_from(msg)->tag_value.len;
01270
01271 db_funcs.use_table(db_con, siptrace_get_table());
01272
01273 db_keys[9] = &traced_user_column;
01274 db_vals[9].type = DB_STR;
01275 db_vals[9].nul = 0;
01276
01277 if( !trace_is_off(msg) ) {
01278 db_vals[9].val.str_val.s = "";
01279 db_vals[9].val.str_val.len = 0;
01280
01281 LM_DBG("storing info...\n");
01282 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
01283 LM_ERR("error storing trace\n");
01284 goto error;
01285 }
01286 #ifdef STATISTICS
01287 update_stat(siptrace_rpl, 1);
01288 #endif
01289 }
01290
01291 if(avp==NULL)
01292 goto done;
01293
01294 trace_send_duplicate(db_vals[0].val.blob_val.s, db_vals[0].val.blob_val.len);
01295
01296 db_vals[9].val.str_val.s = avp_value.s.s;
01297 db_vals[9].val.str_val.len = avp_value.s.len;
01298
01299 LM_DBG("storing info...\n");
01300 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
01301 LM_ERR("error storing trace\n");
01302 goto error;
01303 }
01304
01305 avp = search_next_avp( avp, &avp_value);
01306 while(avp!=NULL) {
01307 db_vals[9].val.str_val.s = avp_value.s.s;
01308 db_vals[9].val.str_val.len = avp_value.s.len;
01309
01310 LM_DBG("### - storing info (%d) ...\n", faked);
01311 if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
01312 LM_ERR("error storing trace\n");
01313 goto error;
01314 }
01315 avp = search_next_avp( avp, &avp_value);
01316 }
01317
01318 done:
01319 return;
01320 error:
01321 return;
01322 }
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332 static struct mi_root* sip_trace_mi(struct mi_root* cmd_tree, void* param )
01333 {
01334 struct mi_node* node;
01335
01336 struct mi_node *rpl;
01337 struct mi_root *rpl_tree ;
01338
01339 node = cmd_tree->node.kids;
01340 if(node == NULL) {
01341 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
01342 if (rpl_tree == 0)
01343 return 0;
01344 rpl = &rpl_tree->node;
01345
01346 if (*trace_on_flag == 0 ) {
01347 node = add_mi_node_child(rpl,0,0,0,MI_SSTR("off"));
01348 } else if (*trace_on_flag == 1) {
01349 node = add_mi_node_child(rpl,0,0,0,MI_SSTR("on"));
01350 }
01351 return rpl_tree ;
01352 }
01353 if(trace_on_flag==NULL)
01354 return init_mi_tree( 500, MI_SSTR(MI_INTERNAL_ERR));
01355
01356 if ( node->value.len==2 && (node->value.s[0]=='o'|| node->value.s[0]=='O') &&
01357 (node->value.s[1]=='n'|| node->value.s[1]=='N')) {
01358 *trace_on_flag = 1;
01359 return init_mi_tree( 200, MI_SSTR(MI_OK));
01360 } else if ( node->value.len==3 && (node->value.s[0]=='o'|| node->value.s[0]=='O')
01361 && (node->value.s[1]=='f'|| node->value.s[1]=='F')
01362 && (node->value.s[2]=='f'|| node->value.s[2]=='F')) {
01363 *trace_on_flag = 0;
01364 return init_mi_tree( 200, MI_SSTR(MI_OK));
01365 } else {
01366 return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
01367 }
01368 }
01369
01370
01371 static int trace_send_duplicate(char *buf, int len)
01372 {
01373 union sockaddr_union* to;
01374 struct socket_info* send_sock;
01375 struct proxy_l * p;
01376 int proto;
01377 int ret;
01378
01379 if(buf==NULL || len <= 0)
01380 return -1;
01381
01382 if(dup_uri_str.s==0 || dup_uri==NULL)
01383 return 0;
01384
01385 to=(union sockaddr_union*)pkg_malloc(sizeof(union sockaddr_union));
01386 if (to==0){ LM_ERR("out of pkg memory\n");
01387 return -1;
01388 }
01389
01390
01391 proto = PROTO_UDP;
01392 p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT, proto, 0);
01393 if (p==0) {
01394 LM_ERR("bad host name in uri\n");
01395 pkg_free(to);
01396 return -1;
01397 }
01398
01399 hostent2su(to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
01400
01401 ret = -1;
01402
01403 do {
01404 send_sock=get_send_socket(0, to, proto);
01405 if (send_sock==0){
01406 LM_ERR("can't forward to af %d, proto %d no corresponding listening socket\n",
01407 to->s.sa_family,proto);
01408 continue;
01409 }
01410
01411 if (msg_send(send_sock, proto, to, 0, buf, len)<0) {
01412 LM_ERR("cannot send duplicate message\n");
01413 continue;
01414 }
01415 ret = 0;
01416 break;
01417 } while( get_next_su( p, to, 0)==0 );
01418
01419 free_proxy(p);
01420 pkg_free(p);
01421 pkg_free(to);
01422
01423 return ret;
01424 }