siptrace.c

Go to the documentation of this file.
00001 /* 
00002  * $Id: siptrace.c 5568 2009-02-09 11:39:06Z henningw $ 
00003  *
00004  * siptrace module - helper module to trace sip messages
00005  *
00006  * Copyright (C) 2006 Voice Sistem S.R.L.
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00025 
00026 /*! \file
00027  * siptrace module - helper module to trace sip messages
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 /* module function prototypes */
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");  /* 00 */
00075 static str callid_column      = str_init("callid");      /* 01 */
00076 static str traced_user_column = str_init("traced_user"); /* 02 */
00077 static str msg_column         = str_init("msg");         /* 03 */
00078 static str method_column      = str_init("method");      /* 04 */
00079 static str status_column      = str_init("status");      /* 05 */
00080 static str fromip_column      = str_init("fromip");      /* 06 */
00081 static str toip_column        = str_init("toip");        /* 07 */
00082 static str fromtag_column     = str_init("fromtag");     /* 08 */
00083 static str direction_column   = str_init("direction");   /* 09 */
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;      /*!< database connection */
00106 db_func_t db_funcs;           /*!< Database functions */
00107 
00108 register_slcb_t register_slcb_f=NULL;  /*!< stateless callback registration */
00109 
00110 /*! \brief
00111  * Exported functions
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 /*! \brief
00121  * Exported parameters
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 /*! \brief
00146  * MI commands
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 /*! \brief module exports */
00168 struct module_exports exports = {
00169    "siptrace", 
00170    DEFAULT_DLFLAGS, /*!< dlopen flags */
00171    cmds,       /*!< Exported functions */
00172    params,     /*!< Exported parameters */
00173 #ifdef STATISTICS
00174    siptrace_stats,  /*!< exported statistics */
00175 #else
00176    0,          /*!< exported statistics */
00177 #endif
00178    mi_cmds,    /*!< exported MI functions */
00179    0,          /*!< exported pseudo-variables */
00180    0,          /*!< extra processes */
00181    mod_init,   /*!< module initialization function */
00182    0,          /*!< response function */
00183    destroy,    /*!< destroy function */
00184    child_init  /*!< child initialization function */
00185 };
00186 
00187 
00188 /*! \brief Initialize siptrace module */
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    /* Find a database module */
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    /* register callbacks to TM */
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    /* register sl callback */
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    // db_vals[5].val.string_val = ip_addr2a(&msg->rcv.dst_ip);;
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    /* check Call-ID header */
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    /* check Call-ID header */
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    // db_vals[5].val.string_val = ip_addr2a(&msg->rcv.dst_ip);;
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    /* check Call-ID header */
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    /* check Call-ID header */
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 /*! \brief
01326  * MI Sip_trace command
01327  *
01328  * MI command format:
01329  * name: sip_trace
01330  * attribute: name=none, value=[on|off]
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    /* create a temporary proxy*/
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); /* frees only p content, not p itself */
01420    pkg_free(p);
01421    pkg_free(to);
01422 
01423    return ret;
01424 }

Generated on Thu May 24 12:00:30 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6