siptrace.c
来自「性能优秀的SIP Proxy」· C语言 代码 · 共 1,245 行 · 第 1/3 页
C
1,245 行
/* * $Id: siptrace.c,v 1.3 2006/07/05 09:03:03 bogdan_iancu Exp $ * * siptrace module - helper module to trace sip messages * * Copyright (C) 2006 Voice Sistem S.R.L. * * This file is part of openser, a free SIP server. * * openser is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * * openser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "../../sr_module.h"#include "../../dprint.h"#include "../../ut.h"#include "../../ip_addr.h"#include "../../mem/mem.h"#include "../../mem/shm_mem.h"#include "../../db/db.h"#include "../../parser/parse_content.h"#include "../../parser/parse_from.h"#include "../../fifo_server.h"#include "../tm/tm_load.h"#include "../sl/sl_cb.h"MODULE_VERSIONstruct tm_binds tmb;/* module function prototypes */static int mod_init(void);static int child_init(int rank);static void destroy(void);static int sip_trace(struct sip_msg*, char*, char*);static int trace_send_duplicate(char *buf, int len);static void trace_onreq_in(struct cell* t, int type, struct tmcb_params *ps);static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps);static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps);static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps);static void trace_sl_onreply_out(struct sip_msg* req, struct sl_cb_param *sl_param);static int sip_trace_fifo(FILE *stream, char *file);char* db_url = DEFAULT_RODB_URL;char* table = "sip_trace";char* date_column = "date"; /* 00 */char* callid_column = "callid"; /* 01 */char* traced_user_column = "traced_user"; /* 02 */char* msg_column = "msg"; /* 03 */char* method_column = "method"; /* 04 */char* status_column = "status"; /* 05 */char* fromip_column = "fromip"; /* 06 */char* toip_column = "toip"; /* 07 */char* fromtag_column = "fromtag"; /* 08 */char* direction_column = "direction"; /* 09 */#define NR_KEYS 10int trace_flag = 0;int trace_on = 0; str dup_uri_str = {0, 0};struct sip_uri *dup_uri = 0;int *trace_on_flag = NULL; int traced_user_avp = 6843;/** database connection */db_con_t *db_con = NULL;db_func_t db_funcs; /* Database functions *//* sl callback registration */register_slcb_t register_slcb_f=NULL;/* * Exported functions */static cmd_export_t cmds[] = { {"sip_trace", sip_trace, 0, 0, REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE}, {0, 0, 0, 0, 0}};/* * Exported parameters */static param_export_t params[] = { {"db_url", STR_PARAM, &db_url }, {"table", STR_PARAM, &table }, {"date_column", STR_PARAM, &date_column }, {"callid_column", STR_PARAM, &callid_column }, {"traced_user_column", STR_PARAM, &traced_user_column }, {"msg_column", STR_PARAM, &msg_column }, {"method_column", STR_PARAM, &method_column }, {"status_column", STR_PARAM, &status_column }, {"fromip_column", STR_PARAM, &fromip_column }, {"toip_column", STR_PARAM, &toip_column }, {"fromtag_column", STR_PARAM, &fromtag_column }, {"direction_column", STR_PARAM, &direction_column }, {"trace_flag", INT_PARAM, &trace_flag }, {"trace_on", INT_PARAM, &trace_on }, {"traced_user_avp", INT_PARAM, &traced_user_avp }, {"duplicate_uri", STR_PARAM, &dup_uri_str.s }, {0, 0, 0}};#ifdef STATISTICS#include "../../statistics.h"stat_var* siptrace_req;stat_var* siptrace_rpl;stat_export_t siptrace_stats[] = { {"traced_requests" , 0, &siptrace_req }, {"traced_replies" , 0, &siptrace_rpl }, {0,0,0}};#endif/* module exports */struct module_exports exports = { "siptrace", cmds, /* Exported functions */ params, /* Exported parameters */#ifdef STATISTICS siptrace_stats,#else 0, /* exported statistics */#endif mod_init, /* module initialization function */ 0, /* response function */ destroy, /* destroy function */ child_init /* child initialization function */};static int mod_init(void){ DBG("siptrace - initializing\n"); /* Find a database module */ if (bind_dbmod(db_url, &db_funcs)) { LOG(L_ERR, "siptrace:mod_init: Unable to bind database module\n"); return -1; } if (!DB_CAPABILITY(db_funcs, DB_CAP_INSERT)) { LOG(L_ERR, "siptrace:mod_init: Database modules does not " "provide all functions needed by module\n"); return -1; } trace_on_flag = (int*)shm_malloc(sizeof(int)); if(trace_on_flag==NULL) { LOG(L_ERR, "siptrace:mod_init:ERROR: no more shm\n"); return -1; } *trace_on_flag = trace_on; /* register callbacks to TM */ if (load_tm_api(&tmb)!=0) { LOG(L_ERR, "siptrace:mod_init:ERROR: can't load tm api\n"); return -1; } if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0) <=0) { LOG(L_ERR,"siptrace:mod_init:ERROR: can't register trace_onreq_in\n"); return -1; } if(register_fifo_cmd(sip_trace_fifo, "sip_trace", 0)<0) { LOG(L_ERR,"siptrace:mod_init:ERROR: cannot register fifo command'\n"); return -1; } /* register sl callback */ register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0); if(register_slcb_f==NULL) { LOG(L_ERR, "siptrace:mod_init:ERROR: can't load sl api\n"); return -1; } if(register_slcb_f(trace_sl_onreply_out, NULL)!=0) { LOG(L_ERR, "siptrace:mod_init:ERROR: can't register trace_sl_onreply_out\n"); return -1; } if(dup_uri_str.s!=0) { dup_uri_str.len = strlen(dup_uri_str.s); dup_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri)); if(dup_uri==0) { LOG(L_ERR, "siptrace:mod_init:ERROR: no more pkg memory\n"); return -1; } memset(dup_uri, 0, sizeof(struct sip_uri)); if(parse_uri(dup_uri_str.s, dup_uri_str.len, dup_uri)<0) { LOG(L_ERR, "siptrace:mod_init:ERROR: bad dup uri\n"); return -1; } } return 0;}static int child_init(int rank){ db_con = db_funcs.init(db_url); if (!db_con) { LOG(L_ERR, "siptrace:init_child: Unable to connect database\n"); return -1; } return 0;}static void destroy(void){ if (db_con!=NULL) db_funcs.close(db_con); if (trace_on_flag) shm_free(trace_on_flag);}static int sip_trace(struct sip_msg *msg, char *s1, char *s2){ db_key_t db_keys[NR_KEYS]; db_val_t db_vals[NR_KEYS]; static char fromip_buff[IP_ADDR_MAX_STR_SIZE+6]; int_str avp_name; int_str avp_value; struct usr_avp *avp; if(msg==NULL) { DBG("sip_trace: no uas request, local transaction\n"); return -1; } avp = NULL; avp_name.n = traced_user_avp; avp=search_first_avp(0, avp_name, &avp_value, 0); if((avp==NULL) && (trace_on_flag==NULL || *trace_on_flag==0)) { DBG("sip_trace: trace off...\n"); return -1; } if(parse_from_header(msg)==-1 || msg->from==NULL || get_from(msg)==NULL) { LOG(L_ERR, "sip_trace: ERROR cannot parse FROM header\n"); goto error; } if(parse_headers(msg, HDR_CALLID_F, 0)!=0 || msg->callid==NULL || msg->callid->body.s==NULL) { LOG(L_ERR, "sip_trace: ERROR cannot parse call-id\n"); goto error; } db_keys[0] = msg_column; db_vals[0].type = DB_BLOB; db_vals[0].nul = 0; db_vals[0].val.blob_val.s = msg->buf; db_vals[0].val.blob_val.len = msg->len; db_keys[1] = callid_column; db_vals[1].type = DB_STR; db_vals[1].nul = 0; db_vals[1].val.str_val.s = msg->callid->body.s; db_vals[1].val.str_val.len = msg->callid->body.len; db_keys[2] = method_column; db_vals[2].type = DB_STR; db_vals[2].nul = 0; if(msg->first_line.type==SIP_REQUEST) { db_vals[2].val.str_val.s = msg->first_line.u.request.method.s; db_vals[2].val.str_val.len = msg->first_line.u.request.method.len; } else { db_vals[2].val.str_val.s = ""; db_vals[2].val.str_val.len = 0; } db_keys[3] = status_column; db_vals[3].type = DB_STR; db_vals[3].nul = 0; if(msg->first_line.type==SIP_REPLY) { db_vals[3].val.str_val.s = msg->first_line.u.reply.status.s; db_vals[3].val.str_val.len = msg->first_line.u.reply.status.len; } else { db_vals[3].val.str_val.s = ""; db_vals[3].val.str_val.len = 0; } db_keys[4] = fromip_column; db_vals[4].type = DB_STRING; db_vals[4].nul = 0; strcpy(fromip_buff, ip_addr2a(&msg->rcv.src_ip)); strcat(fromip_buff,":"); strcat(fromip_buff, int2str(msg->rcv.src_port, NULL)); db_vals[4].val.string_val = fromip_buff; db_keys[5] = toip_column; db_vals[5].type = DB_STRING; db_vals[5].nul = 0; // db_vals[5].val.string_val = ip_addr2a(&msg->rcv.dst_ip);; db_vals[5].val.string_val = "255.255.255.255"; db_keys[6] = date_column; db_vals[6].type = DB_DATETIME; db_vals[6].nul = 0; db_vals[6].val.int_val = time(NULL); db_keys[7] = direction_column; db_vals[7].type = DB_STRING; db_vals[7].nul = 0; db_vals[7].val.string_val = "in"; db_keys[8] = fromtag_column; db_vals[8].type = DB_STR; db_vals[8].nul = 0; db_vals[8].val.str_val.s = get_from(msg)->tag_value.s; db_vals[8].val.str_val.len = get_from(msg)->tag_value.len; db_funcs.use_table(db_con, table); db_keys[9] = traced_user_column; db_vals[9].type = DB_STR; db_vals[9].nul = 0; if(trace_on_flag!=NULL && *trace_on_flag!=0) { db_vals[9].val.str_val.s = ""; db_vals[9].val.str_val.len = 0; DBG("sip_trace: storing info...\n"); if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) { LOG(L_ERR, "sip_trace: error storing trace\n"); goto error; }#ifdef STATISTICS update_stat(siptrace_req, 1);#endif } if(avp==NULL) goto done; trace_send_duplicate(db_vals[0].val.blob_val.s, db_vals[0].val.blob_val.len); db_vals[9].val.str_val.s = avp_value.s.s; db_vals[9].val.str_val.len = avp_value.s.len; DBG("sip_trace: storing info...\n"); if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) { LOG(L_ERR, "sip_trace: error storing trace\n"); goto error; } avp = search_next_avp( avp, &avp_value); while(avp!=NULL) { db_vals[9].val.str_val.s = avp_value.s.s; db_vals[9].val.str_val.len = avp_value.s.len; DBG("sip_trace: storing info...\n"); if(db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) { LOG(L_ERR, "sip_trace: error storing trace\n"); goto error; } avp = search_next_avp( avp, &avp_value); }done: return 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?