⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msilo.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * $Id: msilo.c,v 1.42 2004/12/03 19:09:32 andrei Exp $ * * MSILO module * * Copyright (C) 2001-2003 FhG Fokus * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: *    info@iptel.org * * ser 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 *//** * History * ------- * * 2003-01-23: switched from t_uac to t_uac_dlg (dcm) * 2003-02-28: protocolization of t_uac_dlg completed (jiri) * 2003-03-11: updated to the new module interface (andrei) *             removed non-constant initializers to some strs (andrei) * 2003-03-16: flags parameter added (janakj) * 2003-04-05: default_uri #define used (jiri) * 2003-04-06: db_init removed from mod_init, will be called from child_init *             now (janakj) * 2003-04-07: m_dump takes a parameter which sets the way the outgoing URI *             is computed (dcm) * 2003-08-05 adapted to the new parse_content_type_hdr function (bogdan) * 2004-06-07 updated to the new DB api (andrei) */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/ipc.h>#include <unistd.h>#include <fcntl.h>#include <time.h>#include "../../sr_module.h"#include "../../dprint.h"#include "../../ut.h"#include "../../timer.h"#include "../../mem/shm_mem.h"#include "../../db/db.h"#include "../../parser/parse_from.h"#include "../../parser/parse_content.h"#include "../../parser/contact/parse_contact.h"#include "../../resolve.h"#include "../tm/tm_load.h"#define CONTACT_PREFIX "Content-Type: text/plain"CRLF"Contact: <"#define CONTACT_SUFFIX  ">;msilo=yes"CRLF#define CONTACT_PREFIX_LEN (sizeof(CONTACT_PREFIX)-1)#define CONTACT_SUFFIX_LEN  (sizeof(CONTACT_SUFFIX)-1)#define OFFLINE_MESSAGE	"] is offline. The message will be delivered when user goes online."#define OFFLINE_MESSAGE_LEN	(sizeof(OFFLINE_MESSAGE)-1)#include "ms_msg_list.h"#include "msfuncs.h"#define MAX_DEL_KEYS	1	#define NR_KEYS			9char *sc_mid      = "mid";       /* 0 */char *sc_from     = "src_addr";  /* 1 */char *sc_to       = "dst_addr";  /* 2 */char *sc_uri_user = "username";  /* 3 */char *sc_uri_host = "domain";    /* 4 */char *sc_body     = "body";      /* 5 */char *sc_ctype    = "ctype";     /* 6 */char *sc_exp_time = "exp_time";  /* 7 */char *sc_inc_time = "inc_time";  /* 8 */#define SET_STR_VAL(_str, _res, _r, _c)	\	if (RES_ROWS(_res)[_r].values[_c].nul == 0) \	{ \		switch(RES_ROWS(_res)[_r].values[_c].type) \		{ \		case DB_STRING: \			(_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.string_val; \			(_str).len=strlen((_str).s); \			break; \		case DB_STR: \			(_str).len=RES_ROWS(_res)[_r].values[_c].val.str_val.len; \			(_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.str_val.s; \			break; \		case DB_BLOB: \			(_str).len=RES_ROWS(_res)[_r].values[_c].val.blob_val.len; \			(_str).s=(char*)RES_ROWS(_res)[_r].values[_c].val.blob_val.s; \			break; \		default: \			(_str).len=0; \			(_str).s=NULL; \		} \	}MODULE_VERSION#define S_TABLE_VERSION 3/** database connection */static db_con_t *db_con = NULL;static db_func_t msilo_dbf;/** precessed msg list - used for dumping the messages */msg_list ml = NULL;/** TM bind */struct tm_binds tmb;/** parameters */char *ms_db_url=DEFAULT_DB_URL;char *ms_db_table="silo";char *ms_registrar=NULL; //"sip:registrar@iptel.org";int  ms_expire_time=259200;int  ms_check_time=30;int  ms_clean_period=5;int  ms_use_contact=1;str msg_type = { "MESSAGE", 7 };str reg_addr;/** module functions */static int mod_init(void);static int child_init(int);static int m_store(struct sip_msg*, char*, char*);static int m_dump(struct sip_msg*, char*, char*);void destroy(void);void m_clean_silo(unsigned int ticks, void *);/** TM callback function */static void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps);static cmd_export_t cmds[]={	{"m_store",  m_store, 1, 0, REQUEST_ROUTE | FAILURE_ROUTE},	{"m_dump",   m_dump,  0, 0, REQUEST_ROUTE},	{0,0,0,0,0}};static param_export_t params[]={	{"db_url",       STR_PARAM, &ms_db_url},	{"db_table",     STR_PARAM, &ms_db_table},	{"registrar",    STR_PARAM, &ms_registrar},	{"expire_time",  INT_PARAM, &ms_expire_time},	{"check_time",   INT_PARAM, &ms_check_time},	{"clean_period", INT_PARAM, &ms_clean_period},	{"use_contact",  INT_PARAM, &ms_use_contact},	{"sc_mid",       STR_PARAM, &sc_mid},	{"sc_from",      STR_PARAM, &sc_from},	{"sc_to",        STR_PARAM, &sc_to},	{"sc_uri_user",  STR_PARAM, &sc_uri_user},	{"sc_uri_host",  STR_PARAM, &sc_uri_host},	{"sc_body",      STR_PARAM, &sc_body},	{"sc_ctype",     STR_PARAM, &sc_ctype},	{"sc_exp_time",  STR_PARAM, &sc_exp_time},	{"sc_inc_time",  STR_PARAM, &sc_inc_time},	{0,0,0}};/** module exports */struct module_exports exports= {	"msilo",    /* module id */	cmds,       /* module's exported functions */	params,     /* module's exported parameters */		mod_init,   /* module initialization function */	(response_function) 0,       /* response handler */	(destroy_function) destroy,  /* module destroy function */	0,	child_init  /* per-child init function */};/** * init module function */static int mod_init(void){	str _s;	int ver = 0;	load_tm_f  load_tm;	DBG("MSILO: initializing ...\n");	/* binding to mysql module  */	if (bind_dbmod(ms_db_url, &msilo_dbf))	{		DBG("MSILO: ERROR: Database module not found\n");		return -1;	}	if (!DB_CAPABILITY(msilo_dbf, DB_CAP_ALL)) {		LOG(L_ERR, "MSILO: ERROR: Database module does not implement "		    "all functions needed by the module\n");		return -1;	}	db_con = msilo_dbf.init(ms_db_url);	if (!db_con)	{		LOG(L_ERR,"MSILO:mod_init: Error while connecting database\n");		return -1;	}	_s.s = ms_db_table;	_s.len = strlen(ms_db_table);	ver =  table_version(&msilo_dbf, db_con, &_s);	if(ver!=3)	{		LOG(L_ERR,"MSILO:mod_init: Wrong version v%d for table <%s>,"				" need v%d\n", ver, ms_db_table, S_TABLE_VERSION);		return -1;	}	if(db_con)		msilo_dbf.close(db_con);	db_con = NULL;	/* import the TM auto-loading function */	if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT, 0))) {		LOG(L_ERR, "ERROR: msilo: mod_init: can't import load_tm\n");		return -1;	}	/* let the auto-loading function load all TM stuff */	if (load_tm( &tmb )==-1)		return -1;	ml = msg_list_init();	if(!ml)	{		DBG("ERROR: msilo: mod_init: can't initialize msg list\n");		return -1;	}	register_timer( m_clean_silo, 0, ms_check_time);	reg_addr.s = ms_registrar;	reg_addr.len = (ms_registrar)?strlen(ms_registrar):0;	return 0;}/** * Initialize children */static int child_init(int rank){	DBG("MSILO: init_child #%d / pid <%d>\n", rank, getpid());	if (msilo_dbf.init==0)	{		LOG(L_CRIT, "BUG: msilo: child_init: database not bound\n");		return -1;	}	db_con = msilo_dbf.init(ms_db_url);	if (!db_con)	{		LOG(L_ERR,"MSILO: child %d: Error while connecting database\n", rank);		return -1;	}	else	{		if (msilo_dbf.use_table(db_con, ms_db_table) < 0) {			LOG(L_ERR, "MSILO: child %d: Error in use_table\n", rank);			return -1;		}				DBG("MSILO: child %d: Database connection opened successfully\n", rank);	}	return 0;}/** * store message * mode = "0" -- look for outgoing URI starting with new_uri * 		= "1" -- look for outgoing URI starting with r-uri * 		= "2" -- look for outgoing URI only at to header */static int m_store(struct sip_msg* msg, char* mode, char* str2){	str body, str_hdr, ctaddr;	struct to_body to, *pto, *pfrom;	struct sip_uri puri;	db_key_t db_keys[NR_KEYS-1];	db_val_t db_vals[NR_KEYS-1];		int nr_keys = 0, val, lexpire;	t_content_type ctype;	static char buf[512];	static char buf1[1024];	int mime;	DBG("MSILO: m_store: ------------ start ------------\n");	/* get message body - after that whole SIP MESSAGE is parsed */	body.s = get_body( msg );	if (body.s==0) 	{		LOG(L_ERR,"MSILO:m_store: ERROR cannot extract body from msg\n");		goto error;	}		/* content-length (if present) must be already parsed */	if (!msg->content_length) 	{		LOG(L_ERR,"MSILO:m_store: ERROR no Content-Length header found!\n");		goto error;	}	body.len = get_content_length( msg );	/* check if the body of message contains something */	if(body.len <= 0)	{		DBG("MSILO:m_store: body of the message is empty!\n");		goto error;	}		/* get TO URI */	if(!msg->to || !msg->to->body.s)	{		DBG("MSILO:m_store: cannot find 'to' header!\n");		goto error;	}	if(msg->to->parsed != NULL)	{		pto = (struct to_body*)msg->to->parsed;		DBG("MSILO:m_store: 'To' header ALREADY PARSED: <%.*s>\n",			pto->uri.len, pto->uri.s );		}	else	{		DBG("MSILO:m_store: 'To' header NOT PARSED ->parsing ...\n");		memset( &to , 0, sizeof(to) );		parse_to(msg->to->body.s, msg->to->body.s+msg->to->body.len+1, &to);		if(to.uri.len > 0) /* && to.error == PARSE_OK) */		{			DBG("MSILO:m_store: 'To' parsed OK <%.*s>.\n", 				to.uri.len, to.uri.s);			pto = &to;		}		else		{			DBG("MSILO:m_store: ERROR 'To' cannot be parsed\n");			goto error;		}	}		if(pto->uri.len == reg_addr.len && 			!strncasecmp(pto->uri.s, reg_addr.s, reg_addr.len))	{		DBG("MSILO:m_store: message to MSILO REGISTRAR!\n");		goto error;	}	db_keys[nr_keys] = sc_to;		db_vals[nr_keys].type = DB_STR;	db_vals[nr_keys].nul = 0;	db_vals[nr_keys].val.str_val.s = pto->uri.s;	db_vals[nr_keys].val.str_val.len = pto->uri.len;	nr_keys++;	/* check FROM URI */	if(!msg->from || !msg->from->body.s)	{		DBG("MSILO:m_store: ERROR cannot find 'from' header!\n");		goto error;	}	if(msg->from->parsed == NULL)	{		DBG("MSILO:m_store: 'From' header not parsed\n");		/* parsing from header */		if ( parse_from_header( msg )==-1 ) 		{			DBG("MSILO:m_store: ERROR cannot parse From header\n");			goto error;		}	}	pfrom = (struct to_body*)msg->from->parsed;	DBG("MSILO:m_store: 'From' header: <%.*s>\n", pfrom->uri.len,			pfrom->uri.s);			if(reg_addr.s && pfrom->uri.len == reg_addr.len && 			!strncasecmp(pfrom->uri.s, reg_addr.s, reg_addr.len))	{		DBG("MSILO:m_store: message from MSILO REGISTRAR!\n");		goto error;	}	db_keys[nr_keys] = sc_from;		db_vals[nr_keys].type = DB_STR;	db_vals[nr_keys].nul = 0;	db_vals[nr_keys].val.str_val.s = pfrom->uri.s;	db_vals[nr_keys].val.str_val.len = pfrom->uri.len;	nr_keys++;	/* get the R-URI */	puri.user.len = 0;	if(mode && mode[0]=='0' && msg->new_uri.len > 0)	{		DBG("MSILO:m_store: NEW R-URI found - check if is AoR!\n");		if(parse_uri(msg->new_uri.s, msg->new_uri.len, &puri)!=0)		{			LOG(L_ERR, "MSILO:m_store: bad new R-URI!\n");			goto error;		}		if(puri.user.len>0 && puri.user.s!=NULL				&& puri.host.len>0 && puri.host.s!=NULL)		{			if(str2ip(&puri.host)!=NULL || str2ip6(&puri.host)!=NULL)			{ /* it is a IPv4 or IPv6 address */				puri.user.len = 0;			}		}		else			puri.user.len = 0;	}		if(mode && mode[0]<='1' && puri.user.len == 0 			&& msg->first_line.u.request.uri.len > 0 )	{		DBG("MSILO:m_store: R-URI found - check if is AoR!\n");		if(parse_uri(msg->first_line.u.request.uri.s,			msg->first_line.u.request.uri.len, &puri)!=0)		{			LOG(L_ERR, "MSILO:m_store: bad R-URI!\n");			goto error;		}		if(puri.user.len>0 && puri.user.s!=NULL				&& puri.host.len>0 && puri.host.s!=NULL)		{			if(str2ip(&puri.host)!=NULL || str2ip6(&puri.host)!=NULL)			{ /* it is a IPv4 or IPv6 address */				puri.user.len = 0;			}		}		else			puri.user.len = 0;	}		if (puri.user.len == 0)	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -