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 + -
显示快捷键?