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

📄 dispatcher.c

📁 性能优秀的SIP Proxy
💻 C
字号:
/** * $Id: dispatcher.c,v 1.8 2006/02/10 18:55:46 miconda Exp $ * * dispatcher module -- stateless load balancing * * Copyright (C) 2004-2006 FhG Fokus * * 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 * * History * ------- * 2004-07-31  first version, by daniel *  */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include "../../sr_module.h"#include "../../dprint.h"#include "../../error.h"#include "../../ut.h"#include "../../route.h"#include "../../mem/mem.h"#include "../../fifo_server.h"#include "dispatch.h"MODULE_VERSION/** parameters */char *dslistfile = CFG_DIR"dispatcher.list";int  ds_force_dst   = 0;int  ds_flags       = 0; int  ds_use_default = 0; int  dst_avp_id     = 271;int  grp_avp_id     = 272;int  cnt_avp_id     = 273;/** module functions */static int mod_init(void);static int child_init(int);static int w_ds_select_dst(struct sip_msg*, char*, char*);static int w_ds_select_domain(struct sip_msg*, char*, char*);static int w_ds_next_dst(struct sip_msg*, char*, char*);static int w_ds_next_domain(struct sip_msg*, char*, char*);static int w_ds_mark_dst0(struct sip_msg*, char*, char*);static int w_ds_mark_dst1(struct sip_msg*, char*, char*);void destroy(void);static int ds_fixup(void** param, int param_no);static int ds_fifo_set(FILE *stream, char *response_file);static int ds_fifo_list(FILE *stream, char *response_file);static cmd_export_t cmds[]={	{"ds_select_dst",    w_ds_select_dst,    2, ds_fixup, REQUEST_ROUTE},	{"ds_select_domain", w_ds_select_domain, 2, ds_fixup, REQUEST_ROUTE},	{"ds_next_dst",      w_ds_next_dst,      0,        0, FAILURE_ROUTE},	{"ds_next_domain",   w_ds_next_domain,   0,        0, FAILURE_ROUTE},	{"ds_mark_dst",      w_ds_mark_dst0,     0,        0, FAILURE_ROUTE},	{"ds_mark_dst",      w_ds_mark_dst1,     1,        0, FAILURE_ROUTE},	{0,0,0,0,0}};static param_export_t params[]={	{"list_file",      STR_PARAM, &dslistfile},	{"force_dst",      INT_PARAM, &ds_force_dst},	{"flags",          INT_PARAM, &ds_flags},	{"use_default",    INT_PARAM, &ds_use_default},	{"dst_avp_id",     INT_PARAM, &dst_avp_id},	{"grp_avp_id",     INT_PARAM, &grp_avp_id},	{"cnt_avp_id",     INT_PARAM, &cnt_avp_id},	{0,0,0}};/** module exports */struct module_exports exports= {	"dispatcher",	cmds,	params,	0,          /* exported statistics */	mod_init,   /* module initialization function */	(response_function) 0,	(destroy_function) destroy,	child_init  /* per-child init function */};/** * init module function */static int mod_init(void){	DBG("DISPATCHER: initializing ...\n");	if(register_fifo_cmd(ds_fifo_set, "ds_set_state", 0)<0)	{		LOG(L_ERR,			"DISPATCHER:mod_init:ERROR: cannot register fifo command!\n");		return -1;	}		if(register_fifo_cmd(ds_fifo_list, "ds_list", 0)<0)	{		LOG(L_ERR,			"DISPATCHER:mod_init:ERROR: cannot register fifo command!!\n");		return -1;	}		if(ds_load_list(dslistfile)!=0)	{		LOG(L_ERR, "DISPATCHER:mod_init:ERROR -- couldn't load list file\n");		return -1;	}		return 0;}/** * Initialize children */static int child_init(int rank){	DBG("DISPATCHER:init_child #%d / pid <%d>\n", rank, getpid());	return 0;}static inline int ds_get_ivalue(struct sip_msg* msg, ds_param_p dp, int *val){	xl_value_t value;	if(dp->type==0) {		*val = dp->v.id;		return 0;	}		DBG("DISPATCHER:ds_get_ivalue: searching %d %d %d\n", dp->v.sp.type,			dp->v.sp.p.ind, dp->v.sp.p.val.len);	if(xl_get_spec_value(msg, &dp->v.sp, &value, 0)!=0 			|| value.flags&XL_VAL_NULL || !(value.flags&XL_VAL_INT))	{		LOG(L_ERR,			"DISPATCHER:ds_get_ivalue: no AVP found (error in scripts)\n");		return -1;	}	*val = value.ri;	return 0;}/** * */static int w_ds_select_dst(struct sip_msg* msg, char* set, char* alg){	int a, s;		if(msg==NULL)		return -1;	if(ds_get_ivalue(msg, (ds_param_p)set, &s)!=0)	{		LOG(L_ERR,			"DISPATCHER:w_ds_select_dst: no set value\n");		return -1;	}	if(ds_get_ivalue(msg, (ds_param_p)alg, &a)!=0)	{		LOG(L_ERR,			"DISPATCHER:ds_get_ivalue: no alg value\n");		return -1;	}	return ds_select_dst(msg, s, a, 0 /*set dst uri*/);}/** * */static int w_ds_select_domain(struct sip_msg* msg, char* set, char* alg){	int a, s;	if(msg==NULL)		return -1;	if(ds_get_ivalue(msg, (ds_param_p)set, &s)!=0)	{		LOG(L_ERR,			"DISPATCHER:w_ds_select_dst: no set value\n");		return -1;	}	if(ds_get_ivalue(msg, (ds_param_p)alg, &a)!=0)	{		LOG(L_ERR,			"DISPATCHER:ds_get_ivalue: no alg value\n");		return -1;	}	return ds_select_dst(msg, s, a, 1/*set host port*/);}/** * */static int w_ds_next_dst(struct sip_msg *msg, char *str1, char *str2){	return ds_next_dst(msg, 0/*set dst uri*/);}/** * */static int w_ds_next_domain(struct sip_msg *msg, char *str1, char *str2){	return ds_next_dst(msg, 1/*set host port*/);}/** * */static int w_ds_mark_dst0(struct sip_msg *msg, char *str1, char *str2){	return ds_mark_dst(msg, 0);}/** * */static int w_ds_mark_dst1(struct sip_msg *msg, char *str1, char *str2){	if(str1 && (str1[0]=='i' || str1[0]=='I' || str1[0]=='0'))		return ds_mark_dst(msg, 0);	else		return ds_mark_dst(msg, 1);}/** * destroy function */void destroy(void){	DBG("DISPATCHER: destroy module ...\n");	ds_destroy_list();}/** * */static int ds_fixup(void** param, int param_no){	int err;	ds_param_p dsp;		if(param_no==1 || param_no==2)	{		dsp = (ds_param_p)pkg_malloc(sizeof(ds_param_t));		if(dsp == NULL)		{			LOG(L_ERR, "DISPATCHER:ds_fixup: no more memory\n");			return E_UNSPEC;		}		memset(dsp, 0, sizeof(ds_param_t));		if(((char*)(*param))[0]=='$')		{			dsp->type = 1;			if(xl_parse_spec((char*)*param, &dsp->v.sp,					XL_THROW_ERROR|XL_DISABLE_MULTI|XL_DISABLE_COLORS)==NULL				|| dsp->v.sp.type!=XL_AVP)			{				LOG(L_ERR,					"DISPATCHER:ds_fixup: Unsupported User Field identifier\n");				return E_UNSPEC;			}		} else {			dsp->type = 0;			dsp->v.id = str2s(*param, strlen(*param), &err);			if (err == 0)			{				pkg_free(*param);			} else {				LOG(L_ERR, "DISPATCHER:ds_fixup: Bad number <%s>\n",				    (char*)(*param));				return E_UNSPEC;			}		}		*param = (void*)dsp;	}	return 0;}/** * */static int ds_fifo_set(FILE *stream, char *response_file){	static char tbuf[256];	str sp;	int ret;	unsigned int group, state;		sp.s = tbuf;		if(!read_line(sp.s, 255, stream, &sp.len) || sp.len==0)		{		LOG(L_ERR, "DISPATCHER:ds_fifo_set: could not read state\n");		fifo_reply(response_file, "500 ds_fifo_set - state not found\n");		return 1;	}	if(sp.len<=0)	{		LOG(L_ERR, "DISPATCHER:ds_fifo_set: bad state value\n");		fifo_reply(response_file, "500 ds_fifo_set - bad state value\n");		return 1;	}	state = 1;	if(sp.s[0]=='0' || sp.s[0]=='I' || sp.s[0]=='i')		state = 0;	if(!read_line(sp.s, 255, stream, &sp.len) || sp.len==0)		{		LOG(L_ERR, "DISPATCHER:ds_fifo_set: could not read group\n");		fifo_reply(response_file, "500 ds_fifo_set - group not found\n");		return 1;	}	if(str2int(&sp, &group))	{		LOG(L_ERR, "DISPATCHER:ds_fifo_set: bad group value\n");		fifo_reply(response_file, "500 ds_fifo_set - bad group value\n");		return 1;	}	if(!read_line(sp.s, 255, stream, &sp.len) || sp.len==0)		{		LOG(L_ERR, "DISPATCHER:ds_fifo_set: could not read dst address\n");		fifo_reply(response_file, "500 ds_fifo_set - address not found\n");		return 1;	}	if(state==1)		ret = ds_set_state(group, &sp, DS_INACTIVE_DST, 0);	else		ret = ds_set_state(group, &sp, DS_INACTIVE_DST, 1);	if(ret!=0)	{		fifo_reply(response_file, "404 ds_fifo_set - destination not found\n");		return 1;	}		fifo_reply(response_file, "200 ds_fifo_set - state updated\n");	return 0;}/** * */static int ds_fifo_list(FILE *stream, char *response_file){	FILE *freply=NULL;		freply = open_reply_pipe(response_file);	if(freply == NULL)	{		LOG(L_ERR, "DISPATCHER:ds_fifo_list: can't open reply fifo\n");		return -1;	}		ds_print_list(freply);	fclose(freply);	return 0;}

⌨️ 快捷键说明

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