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

📄 t_fifo.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: t_fifo.c,v 1.15.2.7 2005/08/29 14:27:15 rco Exp $ * * transaction maintenance functions * * 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: * ------- *  2004-02-23  created by splitting it from t_funcs (bogdan) *  2004-11-15  t_write_xxx can print whatever avp/hdr */#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <sys/uio.h>#include <unistd.h>#include <fcntl.h>#include <sys/un.h>#include <ctype.h>#include <string.h>#include "../../str.h"#include "../../ut.h"#include "../../dprint.h"#include "../../mem/mem.h"#include "../../usr_avp.h"#include "../../parser/parser_f.h"#include "../../parser/parse_from.h"#include "../../parser/parse_rr.h"#include "../../parser/parse_nameaddr.h"#include "../../parser/parse_hname2.h"#include "../../parser/contact/parse_contact.h"#include "../../tsend.h"#include "t_lookup.h"#include "t_fwd.h"#include "t_fifo.h"/* AF_LOCAL is not defined on solaris */#if !defined(AF_LOCAL)#define AF_LOCAL AF_UNIX#endif#if !defined(PF_LOCAL)#define PF_LOCAL PF_UNIX#endif/* solaris doesn't have SUN_LEN */#ifndef SUN_LEN#define SUN_LEN(sa)	 ( strlen((sa)->sun_path) + \					 (size_t)(((struct sockaddr_un*)0)->sun_path) )#endifint tm_unix_tx_timeout = 2; /* Default is 2 seconds */#define TWRITE_PARAMS          20#define TWRITE_VERSION_S       "0.3"#define TWRITE_VERSION_LEN     (sizeof(TWRITE_VERSION_S)-1)#define eol_line_s(_i_)        ( iov_lines_eol[2*(_i_)].iov_base )#define eol_line_len(_i_)      ( iov_lines_eol[2*(_i_)].iov_len )#define eol_line(_i_,_s_)      { eol_line_s(_i_) = (_s_).s; \                                 eol_line_len(_i_) = (_s_).len; }#define IDBUF_LEN              128#define ROUTE_BUFFER_MAX       512#define APPEND_BUFFER_MAX      4096#define CMD_BUFFER_MAX         128#define append_str(_dest,_src,_len) \	do{ \		memcpy( (_dest) , (_src) , (_len) );\		(_dest) += (_len) ;\	}while(0);#define append_chr(_dest,_c) \	*((_dest)++) = _c;#define copy_route(s,len,rs,rlen) \	do {\		if(rlen+len+3 >= ROUTE_BUFFER_MAX){\			LOG(L_ERR,"vm: buffer overflow while copying new route\n");\			goto error;\		}\		if(len){\			append_chr(s,','); len++;\		}\		append_chr(s,'<');len++;\		append_str(s,rs,rlen);\		len += rlen; \		append_chr(s,'>');len++;\	} while(0)static struct iovec iov_lines_eol[2*TWRITE_PARAMS];static struct iovec eol={"\n",1};static int sock;struct hdr_avp {	str title;	int type;	str sval;	int ival;	struct hdr_avp *next;};struct tw_append {	str name;	int add_body;	struct hdr_avp *elems;	struct tw_append *next;};struct tw_info {	str action;	struct tw_append *append;};#define ELEM_TYPE_AVP      "avp"#define ELEM_TYPE_AVP_LEN  (sizeof(ELEM_TYPE_AVP)-1)#define ELEM_TYPE_HDR      "hdr"#define ELEM_TYPE_HDR_LEN  (sizeof(ELEM_TYPE_HDR)-1)#define ELEM_TYPE_MSG      "msg"#define ELEM_TYPE_MSG_LEN  (sizeof(ELEM_TYPE_MSG)-1)#define ELEM_IS_AVP        (1<<0)#define ELEM_IS_HDR        (1<<1)#define ELEM_IS_MSG        (1<<2)#define ELEM_VAL_BODY      "body"#define ELEM_VAL_BODY_LEN  (sizeof(ELEM_VAL_BODY)-1)static struct tw_append *tw_appends;static void print_tw_append( struct tw_append *append){	struct hdr_avp *ha;	if (!append)		return;	DBG("DEBUG:tm:print_tw_append: tw_append name=<%.*s>\n",		append->name.len,append->name.s);	for( ha=append->elems ; ha ; ha=ha->next ) {		DBG("\ttitle=<%.*s>\n",ha->title.len,ha->title.s);		DBG("\t\tttype=<%d>\n",ha->type);		DBG("\t\tsval=<%.*s>\n",ha->sval.len,ha->sval.s);		DBG("\t\tival=<%d>\n",ha->ival);	}}/* tw_append syntax: * tw_append = name:element[;element] * element   = [title=]value  * value     = avp[avp_spec] | hdr[hdr_name] | msg[body] */int parse_tw_append( modparam_t type, void* val){	struct hdr_field hdr;	struct hdr_avp *last;	struct hdr_avp *ha;	struct tw_append *app;	int_str avp_name;	char *s;	char bar;	str foo;	int n;		if (val==0 || ((char*)val)[0]==0)		return 0;	s = (char*)val;	/* start parsing - first the name */	while( *s && isspace((int)*s) )  s++;	if ( !*s || *s==':')		goto parse_error;	foo.s = s;	while ( *s && *s!=':' && !isspace((int)*s) ) s++;	if ( !*s || foo.s==s )		goto parse_error;	foo.len = s - foo.s;	/* parse separator */	while( *s && isspace((int)*s) )  s++;	if ( !*s || *s!=':')		goto parse_error;	s++;	while( *s && isspace((int)*s) )  s++;	if ( !*s )		goto parse_error;	/* check for name duplication */	for(app=tw_appends;app;app=app->next)		if (app->name.len==foo.len && !strncasecmp(app->name.s,foo.s,foo.len)){			LOG(L_ERR,"ERROR:tm:parse_tw_append: duplicated tw_append name "				"<%.*s>\n",foo.len,foo.s);			goto error;		}	/* new tw_append structure */	app = (struct tw_append*)pkg_malloc( sizeof(struct tw_append) );	if (app==0) {		LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg memory\n");		goto error;	}	app->name.s = (char*)pkg_malloc( foo.len+1 );	if (app->name.s==0) {		LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg memory\n");		goto error;	}	memcpy( app->name.s, foo.s, foo.len);	app->name.len = foo.len;	app->name.s[app->name.len] = 0;	last = app->elems = 0;	app->next = tw_appends;	tw_appends = app;	/* parse the elements */	while (*s) {		/* parse element title or element type */		foo.s = s;		while( *s && *s!='[' && *s!='=' && *s!=';' && !isspace((int)*s) ) s++;		if ( !*s || foo.s==s)			goto parse_error;		foo.len = s - foo.s;		/* new hdr_avp structure */		ha = (struct hdr_avp*)pkg_malloc( sizeof(struct hdr_avp) );		if (ha==0) {			LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg memory\n");			goto error;		}		memset( ha, 0, sizeof(struct hdr_avp));		if (*s!='[') {			/* foo must by title or some error -> parse separator */			while( *s && isspace((int)*s) )  s++;			if ( !*s || *s!='=')				goto parse_error;			s++;			while( *s && isspace((int)*s) )  s++;			if ( !*s )				goto parse_error;			/* set the title */			ha->title.s = (char*)pkg_malloc( foo.len+1 );			if (ha->title.s==0) {				LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg memory\n");				goto error;			}			memcpy( ha->title.s, foo.s, foo.len);			ha->title.len = foo.len;			ha->title.s[ha->title.len] = 0;			/* parse the type now */			foo.s = s;			while( *s && *s!='[' && *s!=']' && *s!=';' && !isspace((int)*s) )				s++;			if ( *s!='[' || foo.s==s)				goto parse_error;			foo.len = s - foo.s;		}		/* foo containes the elemet type */		if ( foo.len==ELEM_TYPE_AVP_LEN &&		!strncasecmp( foo.s, ELEM_TYPE_AVP, foo.len) ) {			ha->type = ELEM_IS_AVP;		} else if ( foo.len==ELEM_TYPE_HDR_LEN &&		!strncasecmp( foo.s, ELEM_TYPE_HDR, foo.len) ) {			ha->type = ELEM_IS_HDR;		} else if ( foo.len==ELEM_TYPE_MSG_LEN &&		!strncasecmp( foo.s, ELEM_TYPE_MSG, foo.len) ) {			ha->type = ELEM_IS_MSG;		} else {			LOG(L_ERR,"ERROR:tm:parse_tw_append: unknown type <%.*s>\n",				foo.len, foo.s);			goto error;		}		/* parse the element name */		s++;		foo.s = s;		while( *s && *s!=']' && *s!=';' && !isspace((int)*s) ) s++;		if ( *s!=']' || foo.s==s )			goto parse_error;		foo.len = s - foo.s;		s++;		/* process and optimize the element name */		if (ha->type==ELEM_IS_AVP) {			/* element is AVP */			if ( parse_avp_spec( &foo, &n, &avp_name)!=0 ) {				LOG(L_ERR,"ERROR:tm:parse_tw_append: bad alias spec "					"<%.*s>\n",foo.len, foo.s);				goto error;			}			if (n&AVP_NAME_STR) {				/* string name */				ha->sval.s = (char*)pkg_malloc(avp_name.s->len+1);				if (ha->sval.s==0) {					LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg mem\n");					goto error;				}				memcpy( ha->sval.s, avp_name.s->s, avp_name.s->len);				ha->sval.len = avp_name.s->len;				ha->sval.s[ha->sval.len] = 0;				if (ha->title.s==0)					ha->title = ha->sval;			} else {				/* ID name - if title is missing, convert the ID to				 * string and us it a title */				ha->ival = avp_name.n;				if (ha->title.s==0) {					foo.s=int2str((unsigned long)ha->ival, &foo.len);					ha->title.s = (char*)pkg_malloc( n+1 );					if (ha->title.s==0) {						LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg "							"memory\n");						goto error;					}					memcpy( ha->title.s, foo.s, foo.len);					ha->title.len = foo.len;					ha->title.s[ha->title.len] = 0;				}			}		} else if (ha->type==ELEM_IS_HDR) {			/* element is HDR -  try to get it's coded type if defined */			bar = foo.s[foo.len];			foo.s[foo.len] = ':';			/* parse header name */			if (parse_hname2( foo.s, foo.s+foo.len+1, &hdr)==0) {				LOG(L_ERR,"BUG:tm_parse_tw_append: parse header failed\n");				goto error;			}			foo.s[foo.len] = bar;			ha->ival = hdr.type;			if (hdr.type==HDR_OTHER || ha->title.s==0) {				/* duplicate hdr name */				ha->sval.s = (char*)pkg_malloc(foo.len+1);				if (ha->sval.s==0) {					LOG(L_ERR,"ERROR:tm:parse_tw_append: no more pkg mem\n");					goto error;				}				memcpy( ha->sval.s, foo.s, foo.len);				ha->sval.len = foo.len;				ha->sval.s[ha->sval.len] = 0;				if (ha->title.s==0)					ha->title = ha->sval;			}		} else {			/* element is MSG */			if ( !(foo.len==ELEM_VAL_BODY_LEN &&			!strncasecmp(ELEM_VAL_BODY,foo.s,foo.len)) ) {				LOG(L_ERR,"ERROR:tm:parse_tw_append: unsupported value <%.*s>"					" for msg type\n",foo.len,foo.s);				goto error;			}			app->add_body = 1;			pkg_free( ha );			ha = 0;		}		/* parse the element separator, if present */		while( *s && isspace((int)*s) )  s++;		if ( *s && *s!=';')			goto parse_error;		if (*s==';') {			s++;			while( *s && isspace((int)*s) )  s++;			if (!*s)				goto parse_error;		}		/* link the element to tw_append structure */		if (ha) {			if (last==0) {				last = app->elems = ha;			} else {				last->next = ha;				last = ha;			}		}	} /* end while */	print_tw_append( app );	/* free the old string */	pkg_free(val);	return 0;parse_error:	LOG(L_ERR,"ERROR:tm:parse_tw_append: parse error in <%s> around "		"position %ld\n", (char*)val, (long)(s-(char*)val));error:	return -1;}static struct tw_append *search_tw_append(char *name, int len){	struct tw_append * app;	for( app=tw_appends ; app ; app=app->next )		if (app->name.len==len && !strncasecmp(app->name.s,name,len) )			return app;	return 0;}int fixup_t_write( void** param, int param_no){	struct tw_info *twi;	char *s;	if (param_no==2) {		twi = (struct tw_info*)pkg_malloc( sizeof(struct tw_info) );		if (twi==0) {			LOG(L_ERR,"ERROR:tm:fixup_t_write: no more pkg memory\n");			return E_OUT_OF_MEM;		}		memset( twi, 0 , sizeof(struct tw_info));		s = (char*)*param;		twi->action.s = s;		if ( (s=strchr(s,'/'))!=0) {			twi->action.len = s - twi->action.s;			if (twi->action.len==0) {				LOG(L_ERR,"ERROR:tm:fixup_t_write: empty action name\n");				return E_CFG;			}			s++;			if (*s==0) {				LOG(L_ERR,"ERROR:tm:fixup_t_write: empty append name\n");				return E_CFG;			}			twi->append = search_tw_append( s, strlen(s));			if (twi->append==0) {				LOG(L_ERR,"ERROR:tm:fixup_t_write: unknown append name "					"<%s>\n",s);				return E_CFG;			}		} else {			twi->action.len = strlen(twi->action.s);		}		*param=(void*)twi;	}	return 0;}int init_twrite_sock(void){	int flags;	sock = socket(PF_LOCAL, SOCK_DGRAM, 0);	if (sock == -1) {		LOG(L_ERR, "init_twrite_sock: Unable to create socket: %s\n", strerror(errno));		return -1;	}	     /* Turn non-blocking mode on */	flags = fcntl(sock, F_GETFL);	if (flags == -1){		LOG(L_ERR, "init_twrite_sock: fcntl failed: %s\n",		    strerror(errno));		close(sock);		return -1;	}			if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {		LOG(L_ERR, "init_twrite_sock: fcntl: set non-blocking failed:"		    " %s\n", strerror(errno));		close(sock);		return -1;	}

⌨️ 快捷键说明

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