예제 #1
0
파일: hash.c 프로젝트: 4N7HR4X/kamailio
/*
 * Parse and set tag AVP specs
 */
int init_tag_avp(str *tag_avp_param)
{
	pv_spec_t avp_spec;
	unsigned short avp_flags;

	if (tag_avp_param->s && tag_avp_param->len > 0) {
		if (pv_parse_spec(tag_avp_param, &avp_spec)==0
				|| avp_spec.type != PVT_AVP) {
			LM_ERR("malformed or non "
					"AVP %.*s peer_tag_avp definition\n", tag_avp_param->len, tag_avp_param->s);
			return -1;
		}
		if(pv_get_avp_name(0, &avp_spec.pvp, &tag_avp, &avp_flags)!=0) {
			LM_ERR("[%.*s]- invalid "
					"peer_tag_avp AVP definition\n", tag_avp_param->len, tag_avp_param->s);
			return -1;
		}
		tag_avp_type = avp_flags;
	} else {
		tag_avp.n = 0;
	}
	return 0;
}
예제 #2
0
int fix_parameters() {
	str s;
	pv_spec_t avp_spec;

	if (rcv_avp_param && *rcv_avp_param) {
		s.s = rcv_avp_param; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0)
		{
			LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param);
			return -1;
		}
	} else {
		rcv_avp_name.n = 0;
		rcv_avp_type = 0;
	}

	return 1;
}
예제 #3
0
파일: exec.c 프로젝트: btriller/kamailio
int exec_avp(struct sip_msg *msg, char *cmd, pvname_list_p avpl)
{
	int_str avp_val;
	int_str avp_name;
	unsigned short avp_type;
	FILE *pipe;
	int ret;
	char res_line[MAX_URI_SIZE + 1];
	str res;
	int exit_status;
	int i;
	pvname_list_t *crt;

	/* pessimist: assume error by default */
	ret = -1;

	pipe = popen(cmd, "r");
	if(pipe == NULL) {
		LM_ERR("cannot open pipe: %s\n", cmd);
		ser_error = E_EXEC;
		return ret;
	}

	/* read now line by line */
	i = 0;
	crt = avpl;
	while(fgets(res_line, MAX_URI_SIZE, pipe) != NULL) {
		res.s = res_line;
		res.len = strlen(res.s);
		/* trim from right */
		while(res.len
				&& (res.s[res.len - 1] == '\r' || res.s[res.len - 1] == '\n'
						   || res.s[res.len - 1] == '\t'
						   || res.s[res.len - 1] == ' ')) {
			res.len--;
		}
		/* skip empty line */
		if(res.len == 0)
			continue;
		/* ZT */
		res.s[res.len] = 0;

		avp_type = 0;
		if(crt == NULL) {
			avp_name.n = i + 1;
		} else {
			if(pv_get_avp_name(msg, &(crt->sname.pvp), &avp_name, &avp_type)
					!= 0) {
				LM_ERR("can't get item name [%d]\n", i);
				goto error;
			}
		}

		avp_type |= AVP_VAL_STR;
		avp_val.s = res;

		if(add_avp(avp_type, avp_name, avp_val) != 0) {
			LM_ERR("unable to add avp\n");
			goto error;
		}

		if(crt)
			crt = crt->next;

		i++;
	}
	if(i == 0)
		LM_DBG("no result from %s\n", cmd);
	/* success */
	ret = 1;

error:
	if(ferror(pipe)) {
		LM_ERR("pipe: %d/%s\n", errno, strerror(errno));
		ser_error = E_EXEC;
		ret = -1;
	}
	exit_status = pclose(pipe);
	if(WIFEXITED(exit_status)) { /* exited properly .... */
		/* return false if script exited with non-zero status */
		if(WEXITSTATUS(exit_status) != 0)
			ret = -1;
	} else { /* exited erroneously */
		LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n", cmd,
				exit_status, errno, strerror(errno));
		ret = -1;
	}
	return ret;
}
예제 #4
0
/**
 * init module function
 */
static int mod_init(void)
{
	bind_pua_t bind_pua;

	str s;
	pv_spec_t avp_spec;
	
	bind_pua= (bind_pua_t)find_export("bind_pua", 1,0);
	if (!bind_pua)
	{
		LM_ERR("Can't bind pua\n");
		return -1;
	}
	
	if (bind_pua(&pua) < 0)
	{
		LM_ERR("Can't bind pua\n");
		return -1;
	}
	if(pua.send_publish == NULL)
	{
		LM_ERR("Could not import send_publish\n");
		return -1;
	}
	pua_send_publish= pua.send_publish;

	/* bind to the dialog API */
	if (load_dlg_api(&dlg_api)!=0) {
		LM_ERR("failed to find dialog API - is dialog module loaded?\n");
		return -1;
	}
	/* register dialog creation callback */
	if (dlg_api.register_dlgcb(NULL, DLGCB_CREATED, __dialog_created, NULL, NULL) != 0) {
		LM_ERR("cannot register callback for dialog creation\n");
		return -1;
	}

	if(use_pubruri_avps) {

		if(!(pubruri_caller_avp && *pubruri_caller_avp) && (pubruri_callee_avp && *pubruri_callee_avp)) {
			LM_ERR("pubruri_caller_avp and pubruri_callee_avp must be set, if use_pubruri_avps is enabled\n");
			return -1;
		}

		s.s = pubruri_caller_avp; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0	|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", pubruri_caller_avp);
			return -1;
		}
		if(pv_get_avp_name(0, &avp_spec.pvp, &pubruri_caller_avp_name, &pubruri_caller_avp_type)!=0) {
			LM_ERR("[%s]- invalid AVP definition\n", pubruri_caller_avp);
			return -1;
		}

		s.s = pubruri_callee_avp; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0	|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", pubruri_callee_avp);
			return -1;
		}
		if(pv_get_avp_name(0, &avp_spec.pvp, &pubruri_callee_avp_name, &pubruri_callee_avp_type)!=0) {
			LM_ERR("[%s]- invalid AVP definition\n", pubruri_callee_avp);
			return -1;
		}

	}

	return 0;
}
예제 #5
0
파일: reg_mod.c 프로젝트: asitm9/opensips
/*! \brief
 * Initialize parent
 */
static int mod_init(void)
{
	pv_spec_t avp_spec;
	str s;
	bind_usrloc_t bind_usrloc;

	LM_INFO("initializing...\n");

	/* load SIGNALING API */
	if(load_sig_api(&sigb)< 0) {
		LM_ERR("can't load signaling functions\n");
		return -1;
	}

	/* load TM API */
	memset(&tmb, 0, sizeof(struct tm_binds));
	load_tm_api(&tmb);

	realm_prefix.s = realm_pref;
	realm_prefix.len = strlen(realm_pref);

	rcv_param.len = strlen(rcv_param.s);

	if (rcv_avp_param && *rcv_avp_param) {
		s.s = rcv_avp_param; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0)
		{
			LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param);
			return -1;
		}
	} else {
		rcv_avp_name = -1;
		rcv_avp_type = 0;
	}

	if (mct_avp_param && *mct_avp_param) {
		s.s = mct_avp_param; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", mct_avp_param);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &mct_avp_name, &mct_avp_type)!=0)
		{
			LM_ERR("[%s]- invalid AVP definition\n", mct_avp_param);
			return -1;
		}
	} else {
		mct_avp_name = -1;
		mct_avp_type = 0;
	}

	if (attr_avp_param && *attr_avp_param) {
		s.s = attr_avp_param; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", attr_avp_param);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &attr_avp_name, &attr_avp_type)!=0)
		{
			LM_ERR("[%s]- invalid AVP definition\n", attr_avp_param);
			return -1;
		}
	} else {
		attr_avp_name = -1;
		attr_avp_type = 0;
	}

	bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
	if (!bind_usrloc) {
		LM_ERR("can't bind usrloc\n");
		return -1;
	}

	/* Normalize default_q parameter */
	if (default_q != Q_UNSPECIFIED) {
		if (default_q > MAX_Q) {
			LM_DBG("default_q = %d, lowering to MAX_Q: %d\n", default_q, MAX_Q);
			default_q = MAX_Q;
		} else if (default_q < MIN_Q) {
			LM_DBG("default_q = %d, raising to MIN_Q: %d\n", default_q, MIN_Q);
			default_q = MIN_Q;
		}
	}


	if (bind_usrloc(&ul) < 0) {
		return -1;
	}

	/*
	 * Import use_domain parameter from usrloc
	 */
	reg_use_domain = ul.use_domain;

	if (sock_hdr_name.s)
		sock_hdr_name.len = strlen(sock_hdr_name.s);

	if (gruu_secret.s)
		gruu_secret.len = strlen(gruu_secret.s);

	/* fix the flags */
	fix_flag_name(tcp_persistent_flag_s, tcp_persistent_flag);
	tcp_persistent_flag = get_flag_id_by_name(FLAG_TYPE_MSG, tcp_persistent_flag_s);
	tcp_persistent_flag = (tcp_persistent_flag!=-1)?(1<<tcp_persistent_flag):0;

	return 0;
}
예제 #6
0
/*
 * Initialize parameters containing the ID of
 * AVPs with various timers
 */
int init_avp_params(char *fr_timer_param, char *fr_inv_timer_param)
{
	pv_spec_t avp_spec;
	unsigned short avp_type;

	if (fr_timer_param && *fr_timer_param) {
		fr_timer_str.s = fr_timer_param;
		fr_timer_str.len = strlen(fr_timer_str.s);
		LM_WARN("using AVP for TM fr_timer is deprecated,"
				" use t_set_fr(...) instead\n");

		if(fr_timer_str.s[0]==PV_MARKER) {
			if (pv_parse_spec(&fr_timer_str, &avp_spec)==0
			        || avp_spec.type!=PVT_AVP) {
			        LM_ERR("malformed or non AVP %s AVP definition\n",
							fr_timer_param);
				return -1;
			}

			if(pv_get_avp_name(0, &avp_spec.pvp, &fr_timer_avp, &avp_type)!=0)
			{
				LM_ERR("[%s]- invalid AVP definition\n", fr_timer_param);
				return -1;
			}
			fr_timer_avp_type = avp_type;
		} else {
			if (parse_avp_spec( &fr_timer_str, &fr_timer_avp_type,
			&fr_timer_avp, &fr_timer_index)<0) {
				LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_timer "
					"AVP specs \"%s\"\n", fr_timer_param);
				return -1;
			}
			/* ser flavour uses the To track of AVPs */
			fr_timer_avp_type |= AVP_TRACK_TO;
		}
	}

	if (fr_inv_timer_param && *fr_inv_timer_param) {
		fr_inv_timer_str.s = fr_inv_timer_param;
		fr_inv_timer_str.len = strlen(fr_inv_timer_str.s);
		LM_WARN("using AVP for TM fr_inv_timer is deprecated,"
				" use t_set_fr(...) instead\n");

		if(fr_inv_timer_str.s[0]==PV_MARKER) {
			if (pv_parse_spec(&fr_inv_timer_str, &avp_spec)==0
					|| avp_spec.type!=PVT_AVP) {
				LM_ERR("malformed or non AVP %s AVP definition\n",
					fr_inv_timer_param);
				return -1;
			}

			if(pv_get_avp_name(0, &avp_spec.pvp, &fr_inv_timer_avp,
								&avp_type)!=0)
			{
				LM_ERR("[%s]- invalid AVP definition\n", fr_inv_timer_param);
				return -1;
			}
			fr_inv_timer_avp_type = avp_type;
		} else {
			if (parse_avp_spec( &fr_inv_timer_str, &fr_inv_timer_avp_type, 
			&fr_inv_timer_avp, &fr_inv_timer_index)<0) {
				LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_inv_timer "
					"AVP specs \"%s\"\n", fr_inv_timer_param);
				return -1;
			}
			/* ser flavour uses the To track of AVPs */
			fr_inv_timer_avp_type |= AVP_TRACK_TO;
		}
	}

	return 0;
}
예제 #7
0
/* ret= 0! if action -> end of list(e.g DROP), 
      > 0 to continue processing next actions
   and <0 on error */
int do_action(struct action* a, struct sip_msg* msg)
{
	int ret;
	int v;
	int sec,usec;
	union sockaddr_union* to;
	struct proxy_l* p;
	char* tmp;
	char *new_uri, *end, *crt;
	int len,i;
	int user = 0;
	int expires = 0;
	str vals[5];
	str result;
	struct sip_uri uri, next_hop;
	struct sip_uri *u;
	unsigned short port;
	int cmatch;
	struct action *aitem;
	struct action *adefault;
	pv_spec_t *spec;
	pv_elem_p model;
	pv_value_t val;
	pv_elem_t *pve;
	str name_s;
	struct timeval start;
	int end_time;
	action_elem_t *route_params_bak;
	int route_params_number_bak;

	/* reset the value of error to E_UNSPEC so avoid unknowledgable
	   functions to return with error (status<0) and not setting it
	   leaving there previous error; cache the previous value though
	   for functions which want to process it */
	prev_ser_error=ser_error;
	ser_error=E_UNSPEC;

	start_expire_timer(start,execmsgthreshold);

	ret=E_BUG;
	switch ((unsigned char)a->type){
		case DROP_T:
				script_trace("core", "drop", msg, a->line) ;
				action_flags |= ACT_FL_DROP;
		case EXIT_T:
				script_trace("core", "exit", msg, a->line) ;
				ret=0;
				action_flags |= ACT_FL_EXIT;
			break;
		case RETURN_T:
				script_trace("core", "return", msg, a->line) ;
				if (a->elem[0].type == SCRIPTVAR_ST)
				{
					spec = (pv_spec_t*)a->elem[0].u.data;
					if(pv_get_spec_value(msg, spec, &val)!=0
						|| (val.flags&PV_VAL_NULL))
					{
						ret=-1;
					} else {
						if(!(val.flags&PV_VAL_INT))
							ret = 1;
						else
							ret = val.ri;
					}
					pv_value_destroy(&val);
				} else {
					ret=a->elem[0].u.number;
				}
				action_flags |= ACT_FL_RETURN;
			break;
		case FORWARD_T:
			script_trace("core", "forward", msg, a->line) ;
			if (a->elem[0].type==NOSUBTYPE){
				/* parse uri and build a proxy */
				if (msg->dst_uri.len) {
					ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
						&next_hop);
					u = &next_hop;
				} else {
					ret = parse_sip_msg_uri(msg);
					u = &msg->parsed_uri;
				}
				if (ret<0) {
					LM_ERR("forward: bad_uri dropping packet\n");
					break;
				}
				/* create a temporary proxy*/
				p=mk_proxy(u->maddr_val.len?&u->maddr_val:&u->host,
					u->port_no, u->proto, (u->type==SIPS_URI_T)?1:0 );
				if (p==0){
					LM_ERR("bad host name in uri, dropping packet\n");
					ret=E_BAD_ADDRESS;
					goto error_fwd_uri;
				}
				ret=forward_request(msg, p);
				free_proxy(p); /* frees only p content, not p itself */
				pkg_free(p);
				if (ret==0) ret=1;
			}else if ((a->elem[0].type==PROXY_ST)) {
				ret=forward_request(msg,(struct proxy_l*)a->elem[0].u.data);
				if (ret==0) ret=1;
			}else{
				LM_ALERT("BUG in forward() types %d, %d\n",
						a->elem[0].type, a->elem[1].type);
				ret=E_BUG;
			}
			break;
		case SEND_T:
			script_trace("core", "send", msg, a->line) ;
			if (a->elem[0].type!= PROXY_ST){
				LM_ALERT("BUG in send() type %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if (a->elem[1].u.data) {
				if (a->elem[1].type != SCRIPTVAR_ELEM_ST){
					LM_ALERT("BUG in send() header type %d\n",a->elem[1].type);
					ret=E_BUG;
					break;
				} else {
					pve = (pv_elem_t *)a->elem[1].u.data;
				}
			} else {
				pve = NULL;
			}
			to=(union sockaddr_union*)
					pkg_malloc(sizeof(union sockaddr_union));
			if (to==0){
				LM_ERR("memory allocation failure\n");
				ret=E_OUT_OF_MEM;
				break;
			}
			
			p=(struct proxy_l*)a->elem[0].u.data;
			
			ret=hostent2su(to, &p->host, p->addr_idx,
						(p->port)?p->port:SIP_PORT );
			if (ret==0){
				if (pve) {
					if ( pv_printf_s(msg, pve, &name_s)!=0 || 
							name_s.len == 0 || name_s.s == NULL) {
						LM_WARN("cannot get string for value\n");
						ret=E_UNSPEC;
						break;
					}
					/* build new msg */
					tmp = pkg_malloc(msg->len + name_s.len);
					if (!tmp) {
						LM_ERR("memory allocation failure\n");
						ret = E_OUT_OF_MEM;
						break;
					}
					LM_DBG("searching for first line %d\n",
							msg->first_line.len);
					/* search first line of previous msg */
					/* copy headers */
					len = msg->first_line.len;
					memcpy(tmp, msg->buf, len);
					memcpy(tmp + len, name_s.s, name_s.len);
					memcpy(tmp + len + name_s.len,
							msg->buf + len, msg->len - len);
					ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/,
							tmp, msg->len + name_s.len);
					pkg_free(tmp);
				} else {
					ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/,
							msg->buf, msg->len);
				}
				if (ret!=0 && p->host.h_addr_list[p->addr_idx+1])
					p->addr_idx++;
			}
			pkg_free(to);
			if (ret==0)
				ret=1;
			break;
		case LOG_T:
			script_trace("core", "log", msg, a->line) ;
			if ((a->elem[0].type!=NUMBER_ST)|(a->elem[1].type!=STRING_ST)){
				LM_ALERT("BUG in log() types %d, %d\n",
						a->elem[0].type, a->elem[1].type);
				ret=E_BUG;
				break;
			}
			LM_GEN1(a->elem[0].u.number, "%s", a->elem[1].u.string);
			ret=1;
			break;
		case APPEND_BRANCH_T:
			script_trace("core", "append_branch", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in append_branch %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[0].u.s.s==NULL) {
				ret = append_branch(msg, 0, &msg->dst_uri, &msg->path_vec,
					get_ruri_q(), getb0flags(), msg->force_send_socket);
				/* reset all branch info */
				msg->force_send_socket = 0;
				setb0flags(0);
				set_ruri_q(Q_UNSPECIFIED);
				if(msg->dst_uri.s!=0)
					pkg_free(msg->dst_uri.s);
				msg->dst_uri.s = 0;
				msg->dst_uri.len = 0;
				if(msg->path_vec.s!=0)
					pkg_free(msg->path_vec.s);
				msg->path_vec.s = 0;
				msg->path_vec.len = 0;
			} else {
				ret = append_branch(msg, &a->elem[0].u.s, &msg->dst_uri, 
					&msg->path_vec, a->elem[1].u.number, getb0flags(),
					msg->force_send_socket);
			}
			break;
		case REMOVE_BRANCH_T:
			script_trace("core", "remove_branch", msg, a->line) ;
			if (a->elem[0].type == SCRIPTVAR_ST) {
				spec = (pv_spec_t*)a->elem[0].u.data;
				if( pv_get_spec_value(msg, spec, &val)!=0
				|| (val.flags&PV_VAL_NULL) || !(val.flags&PV_VAL_INT) ) {
					ret=-1;
					break;
				}
				i = val.ri;
			} else {
				i=a->elem[0].u.number;
			}
			ret = (remove_branch((unsigned int)i)==0)?1:-1;
			break;
		case LEN_GT_T:
			script_trace("core", "len_gt", msg, a->line) ;
			if (a->elem[0].type!=NUMBER_ST) {
				LM_ALERT("BUG in len_gt type %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			ret = (msg->len >= (unsigned int)a->elem[0].u.number) ? 1 : -1;
			break;
		case SET_DEBUG_T:
			script_trace("core", "set_debug", msg, a->line) ;
			if (a->elem[0].type==NUMBER_ST)
				set_proc_debug_level(a->elem[0].u.number);
			else
				reset_proc_debug_level();
			ret = 1;
			break;
		case SETFLAG_T:
			script_trace("core", "setflag", msg, a->line) ;
			ret = setflag( msg, a->elem[0].u.number );
			break;
		case RESETFLAG_T:
			script_trace("core", "resetflag", msg, a->line) ;
			ret = resetflag( msg, a->elem[0].u.number );
			break;
		case ISFLAGSET_T:
			script_trace("core", "isflagset", msg, a->line) ;
			ret = isflagset( msg, a->elem[0].u.number );
			break;
		case SETSFLAG_T:
			script_trace("core", "setsflag", msg, a->line) ;
			ret = setsflag( a->elem[0].u.number );
			break;
		case RESETSFLAG_T:
			script_trace("core", "resetsflag", msg, a->line) ;
			ret = resetsflag( a->elem[0].u.number );
			break;
		case ISSFLAGSET_T:
			script_trace("core", "issflagset", msg, a->line) ;
			ret = issflagset( a->elem[0].u.number );
			break;
		case SETBFLAG_T:
			script_trace("core", "setbflag", msg, a->line) ;
			ret = setbflag( a->elem[0].u.number, a->elem[1].u.number );
			break;
		case RESETBFLAG_T:
			script_trace("core", "resetbflag", msg, a->line) ;
			ret = resetbflag( a->elem[0].u.number, a->elem[1].u.number  );
			break;
		case ISBFLAGSET_T:
			script_trace("core", "isbflagset", msg, a->line) ;
			ret = isbflagset( a->elem[0].u.number, a->elem[1].u.number  );
			break;
		case ERROR_T:
			script_trace("core", "error", msg, a->line) ;
			if ((a->elem[0].type!=STRING_ST)|(a->elem[1].type!=STRING_ST)){
				LM_ALERT("BUG in error() types %d, %d\n",
						a->elem[0].type, a->elem[1].type);
				ret=E_BUG;
				break;
			}
			LM_ERR("error(\"%s\", \"%s\") not implemented yet\n",
				a->elem[0].u.string, a->elem[1].u.string);
			ret=1;
			break;
		case ROUTE_T:
			script_trace("route", rlist[a->elem[0].u.number].name, msg, a->line) ;
			if (a->elem[0].type!=NUMBER_ST){
				LM_ALERT("BUG in route() type %d\n",
						a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if ((a->elem[0].u.number>RT_NO)||(a->elem[0].u.number<0)){
				LM_ALERT("BUG - invalid routing table number in"
							"route(%lu)\n", a->elem[0].u.number);
				ret=E_CFG;
				break;
			}
			/* check if the route has parameters */
			if (a->elem[1].type != 0) {
				if (a->elem[1].type != NUMBER_ST || a->elem[2].type != SCRIPTVAR_ELEM_ST) {
					LM_ALERT("BUG in route() type %d/%d\n",
							a->elem[1].type, a->elem[2].type);
					ret=E_BUG;
					break;
				}
				route_params_bak = route_params;
				route_params = (action_elem_t *)a->elem[2].u.data;
				route_params_number_bak = route_params_number;
				route_params_number = a->elem[1].u.number;

				return_code=run_actions(rlist[a->elem[0].u.number].a, msg);
				route_params = route_params_bak;
				route_params_number = route_params_number_bak;
			} else {
				return_code=run_actions(rlist[a->elem[0].u.number].a, msg);
			}
			ret=return_code;
			break;
		case REVERT_URI_T:
			script_trace("core", "revert_uri", msg, a->line) ;
			if (msg->new_uri.s) {
				pkg_free(msg->new_uri.s);
				msg->new_uri.len=0;
				msg->new_uri.s=0;
				msg->parsed_uri_ok=0; /* invalidate current parsed uri*/
			};
			ret=1;
			break;
		case SET_HOST_T:
		case SET_HOSTPORT_T:
		case SET_USER_T:
		case SET_USERPASS_T:
		case SET_PORT_T:
		case SET_URI_T:
		case PREFIX_T:
		case STRIP_T:
		case STRIP_TAIL_T:
				script_trace("core", 
					(unsigned char)a->type == SET_HOST_T     ? "set_host" :
					(unsigned char)a->type == SET_HOSTPORT_T ? "set_hostport" : 
					(unsigned char)a->type == SET_USER_T     ? "set_user" :
					(unsigned char)a->type == SET_USERPASS_T ? "set_userpass" : 
					(unsigned char)a->type == SET_PORT_T     ? "set_port" :
					(unsigned char)a->type == SET_URI_T      ? "set_uri" : 
					(unsigned char)a->type == PREFIX_T       ? "prefix" :
					(unsigned char)a->type == STRIP_T  ? "strip" : "strip_tail",
					msg, a->line);
				user=0;
				if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
					if (a->elem[0].type!=NUMBER_ST) {
						LM_ALERT("BUG in set*() type %d\n",
							a->elem[0].type);
						break;
					}
				} else if (a->elem[0].type!=STR_ST){
					LM_ALERT("BUG in set*() type %d\n",
							a->elem[0].type);
					ret=E_BUG;
					break;
				}
				if (a->type==SET_URI_T) {
					if (set_ruri( msg, &a->elem[0].u.s) ) {
						LM_ERR("failed to set new RURI\n");
						ret=E_OUT_OF_MEM;
						break;
					}
					ret=1;
					break;
				}
				if (msg->new_uri.s) {
					tmp=msg->new_uri.s;
					len=msg->new_uri.len;
				}else{
					tmp=msg->first_line.u.request.uri.s;
					len=msg->first_line.u.request.uri.len;
				}
				if (parse_uri(tmp, len, &uri)<0){
					LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp);
					ret=E_UNSPEC;
					break;
				}
				
				new_uri=pkg_malloc(MAX_URI_SIZE);
				if (new_uri==0){
					LM_ERR("memory allocation failure\n");
					ret=E_OUT_OF_MEM;
					break;
				}
				end=new_uri+MAX_URI_SIZE;
				crt=new_uri;
				/* begin copying */
				len = (uri.user.len?uri.user.s:uri.host.s) - tmp;
				if (crt+len>end) goto error_uri;
				memcpy(crt,tmp,len);crt+=len;

				if (a->type==PREFIX_T) {
					if (crt+a->elem[0].u.s.len>end) goto error_uri;
					memcpy( crt, a->elem[0].u.s.s, a->elem[0].u.s.len);
					crt+=a->elem[0].u.s.len;
					/* whatever we had before, with prefix we have username 
					   now */
					user=1;
				}

				if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
					tmp=a->elem[0].u.s.s;
					len=a->elem[0].u.s.len;
				} else if (a->type==STRIP_T) {
					if (a->elem[0].u.number>uri.user.len) {
						LM_WARN("too long strip asked; "
								" deleting username: %lu of <%.*s>\n",
								a->elem[0].u.number, uri.user.len, uri.user.s);
						len=0;
					} else if (a->elem[0].u.number==uri.user.len) {
						len=0;
					} else {
						tmp=uri.user.s + a->elem[0].u.number;
						len=uri.user.len - a->elem[0].u.number;
					}
				} else if (a->type==STRIP_TAIL_T) {
					if (a->elem[0].u.number>uri.user.len) {
						LM_WARN("too long strip_tail asked;"
								" deleting username: %lu of <%.*s>\n",
								a->elem[0].u.number, uri.user.len, uri.user.s);
						len=0;
					} else if (a->elem[0].u.number==uri.user.len) {
						len=0;
					} else {
						tmp=uri.user.s;
						len=uri.user.len - a->elem[0].u.number;
					}
				} else {
					tmp=uri.user.s;
					len=uri.user.len;
				}

				if (len){
					if(crt+len>end) goto error_uri;
					memcpy(crt,tmp,len);crt+=len;
					user=1; /* we have an user field so mark it */
				}

				if (a->type==SET_USERPASS_T) tmp=0;
				else tmp=uri.passwd.s;
				/* passwd */
				if (tmp){
					len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
					*crt=':'; crt++;
					memcpy(crt,tmp,len);crt+=len;
				}
				/* host */
				if (user || tmp){ /* add @ */
					if(crt+1>end) goto error_uri;
					*crt='@'; crt++;
				}
				if ((a->type==SET_HOST_T) ||(a->type==SET_HOSTPORT_T)) {
					tmp=a->elem[0].u.s.s;
					len=a->elem[0].u.s.len;
				} else {
					tmp=uri.host.s;
					len = uri.host.len;
				}
				if (tmp){
					if(crt+len>end) goto error_uri;
					memcpy(crt,tmp,len);crt+=len;
				}
				/* port */
				if (a->type==SET_HOSTPORT_T) tmp=0;
				else if (a->type==SET_PORT_T) {
					tmp=a->elem[0].u.s.s;
					len=a->elem[0].u.s.len;
				} else {
					tmp=uri.port.s;
					len = uri.port.len;
				}
				if (tmp && len>0){
					if(crt+len+1>end) goto error_uri;
					*crt=':'; crt++;
					memcpy(crt,tmp,len);crt+=len;
				}
				/* params */
				tmp=uri.params.s;
				if (tmp){
					/* include in param string the starting ';' */
					len=uri.params.len+1;
					tmp--;
					if(crt+len+1>end) goto error_uri;
					/* if a maddr param is present, strip it out */
					if (uri.maddr.len &&
					(a->type==SET_HOSTPORT_T || a->type==SET_HOST_T)) {
						memcpy(crt,tmp,uri.maddr.s-tmp-1);
						crt+=uri.maddr.s-tmp-1;
						memcpy(crt,uri.maddr_val.s+uri.maddr_val.len,
							tmp+len-uri.maddr_val.s-uri.maddr_val.len);
						crt+=tmp+len-uri.maddr_val.s-uri.maddr_val.len;
					} else {
						memcpy(crt,tmp,len);crt+=len;
					}
				}
				/* headers */
				tmp=uri.headers.s;
				if (tmp){
					len=uri.headers.len; if(crt+len+1>end) goto error_uri;
					*crt='?'; crt++;
					memcpy(crt,tmp,len);crt+=len;
				}
				*crt=0; /* null terminate the thing */
				/* copy it to the msg */
				if (msg->new_uri.s) pkg_free(msg->new_uri.s);
				msg->new_uri.s=new_uri;
				msg->new_uri.len=crt-new_uri;
				msg->parsed_uri_ok=0;
				ret=1;
				break;
		case SET_DSTURI_T:
			script_trace("core", "set_dsturi", msg, a->line) ;
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in setdsturi() type %d\n",
							a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if(set_dst_uri(msg, &a->elem[0].u.s)!=0)
				ret = -1;
			else
				ret = 1;
			break;
		case SET_DSTHOST_T:
		case SET_DSTPORT_T:
			script_trace("core", (unsigned char) a->type == SET_DSTHOST_T ?
						 "set_dsturi" : "set_dstport", msg, a->line);
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in domain setting type %d\n",
							a->elem[0].type);
				ret=E_BUG;
				break;
			}

			tmp = msg->dst_uri.s;
			len = msg->dst_uri.len;

			if (tmp == NULL || len == 0) {
				LM_ERR("failure - null uri\n");
				ret = E_UNSPEC;
				break;
			}
			if (a->type == SET_DSTHOST_T &&
					(a->elem[0].u.s.s == NULL || a->elem[0].u.s.len == 0)) {
				LM_ERR("cannot set a null uri domain\n");
				break;
			}
			if (parse_uri(tmp, len, &uri)<0) {
				LM_ERR("bad uri <%.*s>, dropping packet\n", len, tmp);
				break;
			}
			new_uri=pkg_malloc(MAX_URI_SIZE);
			if (new_uri == NULL) {
				LM_ERR("memory allocation failure\n");
				ret=E_OUT_OF_MEM;
				break;
			}
			end=new_uri+MAX_URI_SIZE;
			crt=new_uri;
			len = (uri.user.len?uri.user.s:uri.host.s) - tmp;
			if (crt+len>end) goto error_uri;
			memcpy(crt,tmp,len);
			crt += len;
			/* user */
			tmp = uri.user.s;
			len = uri.user.len;
			if (tmp) {
				if (crt+len>end) goto error_uri;
				memcpy(crt,tmp,len);
				crt += len;
				user = 1;
			}
			/* passwd */
			tmp = uri.passwd.s;
			len = uri.passwd.len;
			if (user || tmp) {
				if (crt+len+1>end) goto error_uri;
				*crt++=':';
				memcpy(crt, tmp, len);
				crt += len;
			}
			/* host */
			if (a->type==SET_DSTHOST_T) {
				tmp = a->elem[0].u.s.s;
				len = a->elem[0].u.s.len;
			} else {
				tmp = uri.host.s;
				len = uri.host.len;
			}
			if (tmp) {
				if (user) {
					if (crt+1>end) goto error_uri;
					*crt++='@';
				}
				if (crt+len+1>end) goto error_uri;
				memcpy(crt, tmp, len);
				crt += len;
			}
			/* port */
			if (a->type==SET_DSTPORT_T) {
				tmp = a->elem[0].u.s.s;
				len = a->elem[0].u.s.len;
			} else {
				tmp = uri.port.s;
				len = uri.port.len;
			}
			if (tmp) {
				if (crt+len+1>end) goto error_uri;
				*crt++=':';
				memcpy(crt, tmp, len);
				crt += len;
			}
			/* params */
			tmp=uri.params.s;
			if (tmp){
				len=uri.params.len; if(crt+len+1>end) goto error_uri;
				*crt++=';';
				memcpy(crt,tmp,len);
				crt += len;
			}
			/* headers */
			tmp=uri.headers.s;
			if (tmp){
				len=uri.headers.len; if(crt+len+1>end) goto error_uri;
				*crt++='?';
				memcpy(crt,tmp,len);
				crt += len;
			}
			*crt=0; /* null terminate the thing */
			/* copy it to the msg */
			pkg_free(msg->dst_uri.s);
			msg->dst_uri.s=new_uri;
			msg->dst_uri.len=crt-new_uri;
			ret = 1;
			break;
		case RESET_DSTURI_T:
			script_trace("core", "reset_dsturi", msg, a->line) ;
			if(msg->dst_uri.s!=0)
				pkg_free(msg->dst_uri.s);
			msg->dst_uri.s = 0;
			msg->dst_uri.len = 0;
			ret = 1;
			break;
		case ISDSTURISET_T:
			script_trace("core", "isdsturiset", msg, a->line) ;
			if(msg->dst_uri.s==0 || msg->dst_uri.len<=0)
				ret = -1;
			else
				ret = 1;
			break;
		case IF_T:
			script_trace("core", "if", msg, a->line) ;
				/* if null expr => ignore if? */
				if ((a->elem[0].type==EXPR_ST)&&a->elem[0].u.data){
					v=eval_expr((struct expr*)a->elem[0].u.data, msg, 0);
					/* set return code to expr value */
					if (v<0 || (action_flags&ACT_FL_RETURN)
							|| (action_flags&ACT_FL_EXIT) ){
						if (v==EXPR_DROP || (action_flags&ACT_FL_RETURN)
								|| (action_flags&ACT_FL_EXIT) ){ /* hack to quit on DROP*/
							ret=0;
							return_code = 0;
							break;
						}else{
							LM_WARN("error in expression (l=%d)\n", a->line);
						}
					}
					
					ret=1;  /*default is continue */
					if (v>0) {
						if ((a->elem[1].type==ACTIONS_ST)&&a->elem[1].u.data){
							ret=run_action_list(
									(struct action*)a->elem[1].u.data,msg );
							return_code = ret;
						} else return_code = v;
					}else{
						if ((a->elem[2].type==ACTIONS_ST)&&a->elem[2].u.data){
							ret=run_action_list(
								(struct action*)a->elem[2].u.data,msg);
							return_code = ret;
						} else return_code = v;
					}
				}
			break;
		case WHILE_T:
			script_trace("core", "while", msg, a->line) ;
				/* if null expr => ignore if? */
				if ((a->elem[0].type==EXPR_ST)&&a->elem[0].u.data){
					len = 0;
					while(1)
					{
						if(len++ >= max_while_loops)
						{
							LM_INFO("max while loops are encountered\n");
							break;
						}
						v=eval_expr((struct expr*)a->elem[0].u.data, msg, 0);
						/* set return code to expr value */
						if (v<0 || (action_flags&ACT_FL_RETURN)
								|| (action_flags&ACT_FL_EXIT) ){
							if (v==EXPR_DROP || (action_flags&ACT_FL_RETURN)
									|| (action_flags&ACT_FL_EXIT) ){
								ret=0;
								return_code = 0;
								break;
							}else{
								LM_WARN("error in expression (l=%d)\n",
										a->line);
							}
						}
					
						ret=1;  /*default is continue */
						if (v>0) {
							if ((a->elem[1].type==ACTIONS_ST)
									&&a->elem[1].u.data){
								ret=run_action_list(
									(struct action*)a->elem[1].u.data,msg );
								/* check if return was done */
								if ((action_flags&ACT_FL_RETURN)
								|| (action_flags&ACT_FL_EXIT) ){
									break;
								}
								return_code = ret;
							} else {
								/* we should not get here */
								return_code = v;
								break;
							}
						} else {
							/* condition was false */
							return_code = v;
							break;
						}
					}
				}
			break;
		case CACHE_STORE_T:
			script_trace("core", "cache_store", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_store() - first argument not of"
						" type string [%d]\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_store()  - second argument not of "
						"type string [%d]\n", a->elem[1].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[2].type!=STR_ST)) {
				LM_ALERT("BUG in cache_store() - third argument not of type"
						" string%d\n", a->elem[2].type );
				ret=E_BUG;
				break;
			}

			str val_s;

			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			/* parse the value argument */
			pve = (pv_elem_t *)a->elem[2].u.data;
			if ( pv_printf_s(msg, pve, &val_s)!=0 || 
			val_s.len == 0 || val_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			/* get the expires value */
			if ( a->elem[3].type == SCRIPTVAR_ST )
			{
				spec = (pv_spec_t*)a->elem[3].u.data;
				memset(&val, 0, sizeof(pv_value_t));
				if(pv_get_spec_value(msg, spec, &val) < 0)
				{
					LM_DBG("Failed to get scriptvar value while executing cache_store\n");
					ret=E_BUG;
					break;
				}
				if (!(val.flags&PV_VAL_INT))
				{
					LM_ERR("Wrong value for cache_store expires, not an integer [%.*s]\n",
							val.rs.len, val.rs.s);
				}
				expires = val.ri;
			}
			else
			if ( a->elem[3].type == NUMBER_ST )
			{
				expires = (int)a->elem[3].u.number;
			}

			ret = cachedb_store( &a->elem[0].u.s, &name_s, &val_s,expires);

			break;
		case CACHE_REMOVE_T:
			script_trace("core", "cache_remove", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_remove() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_remove() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}
			ret = cachedb_remove( &a->elem[0].u.s, &name_s);
			break;
		case CACHE_FETCH_T:
			script_trace("core", "cache_fetch", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[2].type!=SCRIPTVAR_ST){
				LM_ALERT("BUG in cache_fetch() type %d\n",
						a->elem[2].type);
				ret=E_BUG;
				break;
			}
			str aux = {0, 0};
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			ret = cachedb_fetch( &a->elem[0].u.s, &name_s, &aux);
			if(ret > 0)
			{
				val.rs = aux;
				val.flags = PV_VAL_STR;

				spec = (pv_spec_t*)a->elem[2].u.data;
				if (pv_set_value(msg, spec, 0, &val) < 0) {
					LM_ERR("cannot set the variable value\n");
					pkg_free(aux.s);
					return -1;
				}
				pkg_free(aux.s);
			}
			
			break;
		case CACHE_COUNTER_FETCH_T:
			script_trace("core", "cache_counter_fetch", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[2].type!=SCRIPTVAR_ST){
				LM_ALERT("BUG in cache_fetch() type %d\n",
						a->elem[2].type);
				ret=E_BUG;
				break;
			}
			int aux_counter;
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			ret = cachedb_counter_fetch( &a->elem[0].u.s, &name_s, &aux_counter);
			if(ret > 0)
			{
				val.ri = aux_counter;
				val.flags = PV_TYPE_INT|PV_VAL_INT;

				spec = (pv_spec_t*)a->elem[2].u.data;
				if (pv_set_value(msg, spec, 0, &val) < 0) {
					LM_ERR("cannot set the variable value\n");
					pkg_free(aux.s);
					return -1;
				}
			}
			break;
		case CACHE_ADD_T:
			script_trace("core", "cache_add", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_add() - first argument not of"
						" type string [%d]\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_add()  - second argument not of "
						"type string [%d]\n", a->elem[1].type );
				ret=E_BUG;
				break;
			}

			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			int increment=0;

			/* get the increment value */
			if ( a->elem[2].type == SCRIPTVAR_ST )
			{
				spec = (pv_spec_t*)a->elem[2].u.data;
				memset(&val, 0, sizeof(pv_value_t));
				if(pv_get_spec_value(msg, spec, &val) < 0)
				{
					LM_DBG("Failed to get scriptvar value while executing cache_add\n");
					ret=E_BUG;
					break;
				}
				if (!(val.flags&PV_VAL_INT))
				{
					LM_ERR("Wrong value for cache_add, not an integer [%.*s]\n",
							val.rs.len, val.rs.s);
				}
				increment = val.ri;
			}
			else if ( a->elem[2].type == NUMBER_ST )
			{
				increment = (int)a->elem[2].u.number;
			}

			expires = (int)a->elem[3].u.number;

			/* TODO - return the new value to script ? */
			ret = cachedb_add(&a->elem[0].u.s, &name_s, increment,expires,NULL);
			break;
		case CACHE_SUB_T:
			script_trace("core", "cache_sub", msg, a->line) ;
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_sub() - first argument not of"
						" type string [%d]\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}

			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_sub()  - second argument not of "
						"type string [%d]\n", a->elem[1].type );
				ret=E_BUG;
				break;
			}

			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			int decrement=0;

			/* get the increment value */
			if ( a->elem[2].type == SCRIPTVAR_ST )
			{
				spec = (pv_spec_t*)a->elem[2].u.data;
				memset(&val, 0, sizeof(pv_value_t));
				if(pv_get_spec_value(msg, spec, &val) < 0)
				{
					LM_DBG("Failed to get scriptvar value while executing cache_sub\n");
					ret=E_BUG;
					break;
				}
				if (!(val.flags&PV_VAL_INT))
				{
					LM_ERR("Wrong value for cache_sub, not an integer [%.*s]\n",
							val.rs.len, val.rs.s);
				}
				decrement = val.ri;
			}
			else if ( a->elem[2].type == NUMBER_ST )
			{
				decrement = (int)a->elem[2].u.number;
			}

			expires = (int)a->elem[3].u.number;

			/* TODO - return new value to script ? */
			ret = cachedb_sub(&a->elem[0].u.s, &name_s, decrement,expires,NULL);
			break;
		case CACHE_RAW_QUERY_T:
			if ((a->elem[0].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[0].type );
				ret=E_BUG;
				break;
			}
			if ((a->elem[1].type!=STR_ST)) {
				LM_ALERT("BUG in cache_fetch() %d\n",
					a->elem[1].type );
				ret=E_BUG;
				break;
			}
			if (a->elem[2].u.data != NULL && 
				a->elem[2].type!=STR_ST){
				LM_ALERT("BUG in cache_raw_query() type %d\n",
						a->elem[2].type);
				ret=E_BUG;
				break;
			}
			/* parse the name argument */
			pve = (pv_elem_t *)a->elem[1].u.data;
			if ( pv_printf_s(msg, pve, &name_s)!=0 || 
			name_s.len == 0 || name_s.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}

			cdb_raw_entry **cdb_reply;
			int val_number=0,i,j;
			int key_number=0;
			pvname_list_t *cdb_res,*it;
			int_str avp_val;
			int_str avp_name;
			unsigned short avp_type;

			if (a->elem[2].u.data) {
				cdb_res = (pvname_list_t*)a->elem[2].u.data;
				for (it=cdb_res;it;it=it->next)
					val_number++;

				LM_DBG("The query expects %d results back\n",val_number);

				ret = cachedb_raw_query( &a->elem[0].u.s, &name_s, &cdb_reply,val_number,&key_number);
				if (ret >= 0 && val_number > 0) {
					for (i=key_number-1; i>=0;i--) {
						it=cdb_res;
						for (j=0;j < val_number;j++) {
							avp_type = 0;
							if (pv_get_avp_name(msg,&it->sname.pvp,&avp_name.n,
								&avp_type) != 0) {
								LM_ERR("cannot get avp name [%d/%d]\n",i,j);
								goto next_avp;
							}
							
							switch (cdb_reply[i][j].type) {
								case CDB_INT:
									avp_val.n = cdb_reply[i][j].val.n; 
									break;
								case CDB_STR:
									avp_type |= AVP_VAL_STR;
									avp_val.s = cdb_reply[i][j].val.s;
									break;
								default:
									LM_WARN("Unknown type %d\n",cdb_reply[i][j].type);
									goto next_avp;
							}
							if (add_avp(avp_type,avp_name.n,avp_val) != 0) {
								LM_ERR("Unable to add AVP\n");
								free_raw_fetch(cdb_reply,val_number,key_number);
								return -1;
							}
next_avp:
							if (it) {
								it = it->next;
								if (it==NULL);
									break;
							}
						}
					}
					free_raw_fetch(cdb_reply,val_number,key_number);
				}
			}
			else
				ret = cachedb_raw_query( &a->elem[0].u.s, &name_s, NULL,0,NULL);
			break;
		case XDBG_T:
			script_trace("core", "xdbg", msg, a->line) ;
			if (a->elem[0].type == SCRIPTVAR_ELEM_ST)
			{
				if (xdbg(msg, a->elem[0].u.data, val.rs.s) < 0)
				{
					LM_ALERT("Cannot print message");
					break;
				}
			}
			else
			{
				LM_ALERT("BUG in xdbg() type %d\n", a->elem[0].type);
				ret=E_BUG;
			}
			break;
		case XLOG_T:
			script_trace("core", "xlog", msg, a->line) ;
			if (a->elem[1].u.data != NULL)
			{
				if (a->elem[1].type != SCRIPTVAR_ELEM_ST)
				{
					LM_ALERT("BUG in xlog() type %d\n", a->elem[1].type);
					ret=E_BUG;
					break;
				}
				if (a->elem[0].type != STR_ST)
				{
					LM_ALERT("BUG in xlog() type %d\n", a->elem[0].type);
					ret=E_BUG;
					break;
				}
				if (xlog_2(msg,a->elem[0].u.data, a->elem[1].u.data) < 0)
				{
					LM_ALERT("Cannot print xlog debug message");
					break;
				}
			}
			else
			{
				if (a->elem[0].type != SCRIPTVAR_ELEM_ST)
				{
					LM_ALERT("BUG in xlog() type %d\n", a->elem[0].type);
					ret=E_BUG;
					break;
				}
				if (xlog_1(msg,a->elem[0].u.data, val.rs.s) < 0)
				{
					LM_ALERT("Cannot print xlog debug message");
					break;
				}
			}

			break;
		case RAISE_EVENT_T:
			script_trace("core", "raise_event", msg, a->line) ;
			if (a->elem[0].type != NUMBER_ST) {
				LM_ERR("invalid event id\n");
				ret=E_BUG;
				break;
			}
			if (a->elem[2].u.data) {
				/* three parameters specified */
				ret = evi_raise_script_event(msg, (event_id_t)a->elem[0].u.number,
						a->elem[1].u.data, a->elem[2].u.data);
			} else {
				/* two parameters specified */
				ret = evi_raise_script_event(msg, (event_id_t)a->elem[0].u.number,
						NULL, a->elem[1].u.data);
			}
			if (ret <= 0) {
				LM_ERR("cannot raise event\n");
				ret=E_UNSPEC;
				break;
			}
			break;
		case SUBSCRIBE_EVENT_T:
			script_trace("core", "subscribe_event", msg, a->line) ;
			if (a->elem[0].type != STR_ST || a->elem[1].type != STR_ST) {
				LM_ERR("BUG in subscribe arguments\n");
				ret=E_BUG;
				break;
			}
			if (a->elem[2].u.data) {
				if (a->elem[2].type != NUMBER_ST) {
					LM_ERR("BUG in subscribe expiration time\n");
					ret=E_BUG;
					break;
				} else {
					i = a->elem[2].u.number;
				}
			} else {
				i = 0;
			}

			name_s.s = a->elem[0].u.data;
			name_s.len = strlen(name_s.s);
			/* result should be the socket */
			result.s = a->elem[1].u.data;
			result.len = strlen(result.s);
			ret = evi_event_subscribe(name_s, result, i, 0);
			break;

		case CONSTRUCT_URI_T:
			script_trace("core", "construct_uri", msg, a->line) ;
			for (i=0;i<5;i++)
			{
				pve = (pv_elem_t *)a->elem[i].u.data;
				if (pve->spec.getf)
				{
					if ( pv_printf_s(msg, pve, &vals[i])!=0 || 
						vals[i].len == 0 || vals[i].s == NULL) 
					{
						LM_WARN("cannot get string for value\n");
						ret=E_BUG;
						return -1;
					}
				}
				else
					vals[i] = pve->text;
			}
			
			result.s = construct_uri(&vals[0],&vals[1],&vals[2],&vals[3],&vals[4],
					&result.len);

			if (result.s)
			{
				int_str res;
				int avp_name;
				unsigned short avp_type;

				spec = (pv_spec_t*)a->elem[5].u.data;
				if (pv_get_avp_name( msg, &(spec->pvp), &avp_name,
						&avp_type)!=0){
					LM_CRIT("BUG in getting AVP name\n");
					return -1;
				}

				res.s = result;
				if (add_avp(AVP_VAL_STR|avp_type, avp_name, res)<0){
					LM_ERR("cannot add AVP\n");
					return -1;
				}
			}

			break;
		case GET_TIMESTAMP_T:
			script_trace("core", "get_timestamp", msg, a->line) ;
			if (get_timestamp(&sec,&usec) == 0) {
				int avp_name;
				int_str res;
				unsigned short avp_type;

				spec = (pv_spec_t*)a->elem[0].u.data;
				if (pv_get_avp_name(msg, &(spec->pvp), &avp_name,
						&avp_type) != 0) {
					LM_CRIT("BUG in getting AVP name\n");
					return -1;
				}

				res.n = sec;
				if (add_avp(avp_type, avp_name, res) < 0) {
					LM_ERR("cannot add AVP\n");
					return -1;
				}

				spec = (pv_spec_t*)a->elem[1].u.data;
				if (pv_get_avp_name(msg, &(spec->pvp), &avp_name,
						&avp_type) != 0) {
					LM_CRIT("BUG in getting AVP name\n");
					return -1;
				}

				res.n = usec;
				if (add_avp(avp_type, avp_name, res) < 0) {
					LM_ERR("cannot add AVP\n");
					return -1;
				}
			} else {
				LM_ERR("failed to get time\n");
				return -1;
			}
			break;
		case SWITCH_T:
			script_trace("core", "switch", msg, a->line) ;
			if (a->elem[0].type!=SCRIPTVAR_ST){
				LM_ALERT("BUG in switch() type %d\n",
						a->elem[0].type);
				ret=E_BUG;
				break;
			}
			spec = (pv_spec_t*)a->elem[0].u.data;
			if(pv_get_spec_value(msg, spec, &val)!=0)
			{
				LM_ALERT("BUG - no value in switch()\n");
				ret=E_BUG;
				break;
			}

			/* get the value of pvar */
			if(a->elem[1].type!=ACTIONS_ST) {
				LM_ALERT("BUG in switch() actions\n");
				ret=E_BUG;
				break;
			}
			return_code=1;
			adefault = NULL;
			aitem = (struct action*)a->elem[1].u.data;
			cmatch=0;
			while(aitem)
			{
				if((unsigned char)aitem->type==DEFAULT_T)
					adefault=aitem;
				if(cmatch==0)
				{
					if(aitem->elem[0].type==STR_ST)
					{
						if(val.flags&PV_VAL_STR
								&& val.rs.len==aitem->elem[0].u.s.len
								&& strncasecmp(val.rs.s, aitem->elem[0].u.s.s,
									val.rs.len)==0)
							cmatch = 1;
					} else { /* number */
						if(val.flags&PV_VAL_INT && 
								val.ri==aitem->elem[0].u.number)
							cmatch = 1;
					}
				}
				if(cmatch==1)
				{
					if(aitem->elem[1].u.data)
					{
						return_code=run_action_list(
							(struct action*)aitem->elem[1].u.data, msg);
						if ((action_flags&ACT_FL_RETURN) ||
						(action_flags&ACT_FL_EXIT))
							break;
					}
					if(aitem->elem[2].u.number==1)
						break;
				}
				aitem = aitem->next;
			}
			if((cmatch==0) && (adefault!=NULL))
			{
				LM_DBG("switch: running default statement\n");
				if(adefault->elem[0].u.data)
					return_code=run_action_list(
						(struct action*)adefault->elem[0].u.data, msg);
			}
			ret=return_code;
			break;
		case MODULE_T:
			script_trace("module", ((cmd_export_t*)(a->elem[0].u.data))->name,
				msg, a->line) ;
			if ( (a->elem[0].type==CMD_ST) && a->elem[0].u.data ) {
				ret=((cmd_export_t*)(a->elem[0].u.data))->function(msg,
						 (char*)a->elem[1].u.data, (char*)a->elem[2].u.data,
						 (char*)a->elem[3].u.data, (char*)a->elem[4].u.data,
						 (char*)a->elem[5].u.data, (char*)a->elem[6].u.data);
			}else{
				LM_ALERT("BUG in module call\n");
			}
			break;
		case FORCE_RPORT_T:
			script_trace("core", "force_rport", msg, a->line) ;
			msg->msg_flags|=FL_FORCE_RPORT;
			ret=1; /* continue processing */
			break;
		case FORCE_LOCAL_RPORT_T:
			script_trace("core", "force_local_rport", msg, a->line) ;
			msg->msg_flags|=FL_FORCE_LOCAL_RPORT;
			ret=1; /* continue processing */
			break;
		case SET_ADV_ADDR_T:
			script_trace("core", "set_adv_addr", msg, a->line) ;
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in set_advertised_address() "
						"type %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			str adv_addr;
			pve = (pv_elem_t *)a->elem[0].u.data;
			if ( pv_printf_s(msg, pve, &adv_addr)!=0 || 
			adv_addr.len == 0 || adv_addr.s == NULL) {
				LM_WARN("cannot get string for value\n");
				ret=E_BUG;
				break;
			}
			LM_DBG("adv address = [%.*s]\n",adv_addr.len,adv_addr.s);
			msg->set_global_address=adv_addr;
			ret=1; /* continue processing */
			break;
		case SET_ADV_PORT_T:
			script_trace("core", "set_adv_port", msg, a->line) ;
			if (a->elem[0].type!=STR_ST){
				LM_ALERT("BUG in set_advertised_port() "
						"type %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}

			msg->set_global_port=*((str*)a->elem[0].u.data);
			ret=1; /* continue processing */
			break;
#ifdef USE_TCP
		case FORCE_TCP_ALIAS_T:
			script_trace("core", "force_tcp_alias", msg, a->line) ;
			if ( msg->rcv.proto==PROTO_TCP
#ifdef USE_TLS
					|| msg->rcv.proto==PROTO_TLS
#endif
			   ){
				
				if (a->elem[0].type==NOSUBTYPE)	port=msg->via1->port;
				else if (a->elem[0].type==NUMBER_ST)
					port=(int)a->elem[0].u.number;
				else{
					LM_ALERT("BUG in force_tcp_alias"
							" port type %d\n", a->elem[0].type);
					ret=E_BUG;
					break;
				}
						
				if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
									msg->rcv.proto)!=0){
					LM_ERR("tcp alias failed\n");
					ret=E_UNSPEC;
					break;
				}
			}
#endif
			ret=1; /* continue processing */
			break;
		case FORCE_SEND_SOCKET_T:
			script_trace("core", "force_send_socket", msg, a->line) ;
			if (a->elem[0].type!=SOCKETINFO_ST){
				LM_ALERT("BUG in force_send_socket argument"
						" type: %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			msg->force_send_socket=(struct socket_info*)a->elem[0].u.data;
			ret=1; /* continue processing */
			break;
		case SERIALIZE_BRANCHES_T:
			script_trace("core", "serialize_branches", msg, a->line) ;
			if (a->elem[0].type!=NUMBER_ST){
				LM_ALERT("BUG in serialize_branches argument"
						" type: %d\n", a->elem[0].type);
				ret=E_BUG;
				break;
			}
			if (serialize_branches(msg,(int)a->elem[0].u.number)!=0) {
				LM_ERR("serialize_branches failed\n");
				ret=E_UNSPEC;
				break;
			}
			ret=1; /* continue processing */
			break;
		case NEXT_BRANCHES_T:
			script_trace("core", "next_branches", msg, a->line) ;
			if ((ret=next_branches(msg))<0) {
				LM_ERR("next_branches failed\n");
				ret=E_UNSPEC;
				break;
			}
			/* continue processing */
			break;
		case EQ_T:
		case COLONEQ_T:
		case PLUSEQ_T:
		case MINUSEQ_T:
		case DIVEQ_T:
		case MULTEQ_T:
		case MODULOEQ_T:
		case BANDEQ_T:
		case BOREQ_T:
		case BXOREQ_T:
			ret = do_assign(msg, a);
			break;
		case USE_BLACKLIST_T:
			script_trace("core", "use_blacklist", msg, a->line) ;
			mark_for_search((struct bl_head*)a->elem[0].u.data, 1);
			break;
		case UNUSE_BLACKLIST_T:
			script_trace("core", "unuse_blacklist", msg, a->line);
			mark_for_search((struct bl_head*)a->elem[0].u.data, 0);
			break;
		case PV_PRINTF_T:
			script_trace("core", "pv_printf", msg, a->line);
			ret = -1;
			spec = (pv_spec_p)a->elem[0].u.data;
			if(!pv_is_w(spec))
			{
				LM_ERR("read only PV in first parameter of pv_printf\n");
				goto error;
			}

			model = (pv_elem_p)a->elem[1].u.data;

			memset(&val, 0, sizeof(pv_value_t));
			if(pv_printf_s(msg, model, &val.rs)!=0)
			{
				LM_ERR("cannot eval second parameter\n");
				goto error;
			}
			val.flags = PV_VAL_STR;
			if(pv_set_value(msg, spec, EQ_T, &val)<0)
			{
				LM_ERR("setting PV failed\n");
				goto error;
			}
			
			ret = 1;
			break;
		case SCRIPT_TRACE_T:
			script_trace("core", "script_trace", msg, a->line);
			if (a->elem[0].type==NOSUBTYPE) {
				use_script_trace = 0;
			} else {
				
				use_script_trace = 1;
				
				if (a->elem[0].type != NUMBER_ST ||
					a->elem[1].type != SCRIPTVAR_ELEM_ST) {

					LM_ERR("BUG in use_script_trace() arguments\n");
					ret=E_BUG;
					break;
				}

				if (a->elem[2].type!=NOSUBTYPE) {
					script_trace_info = (char *)a->elem[2].u.data;
				} else {
					script_trace_info = NULL;
				}

				script_trace_log_level = (int)a->elem[0].u.number;
				script_trace_elem = *(pv_elem_p)a->elem[1].u.data;
			}

			break;
		default:
			LM_ALERT("BUG - unknown type %d\n", a->type);
			goto error;
	}

	if((unsigned char)a->type!=IF_T && (unsigned char)a->type!=ROUTE_T)
		return_code = ret;
/*skip:*/

	update_longest_action();
	return ret;

error:
	LM_ERR("error at line: %d\n", a->line);
	update_longest_action();
	return ret;
	
error_uri:
	LM_ERR("set*: uri too long\n");
	if (new_uri) pkg_free(new_uri);
	update_longest_action();
	return E_UNSPEC;
error_fwd_uri:
	update_longest_action();
	return ret;
}
예제 #8
0
static int
mod_init(void)
{
    pv_spec_t avp_spec;
    int *param;
	 modparam_t type;


    // initialize the canonical_uri_avp structure
    if (canonical_uri_avp.spec.s==NULL || canonical_uri_avp.spec.len<=0) {
        LOG(L_ERR, "missing/empty canonical_uri_avp parameter. using default.\n");
        canonical_uri_avp.spec.s = CANONICAL_URI_AVP_SPEC;
    }

    if (pv_parse_spec(&(canonical_uri_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LOG(L_CRIT, "invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(canonical_uri_avp.name), &(canonical_uri_avp.type))!=0) {
        LOG(L_CRIT, "invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s);
        return -1;
    }

    // initialize the signaling_ip_avp structure
    if (signaling_ip_avp.spec.s==NULL || signaling_ip_avp.spec.len<=0) {
        LOG(L_ERR, "missing/empty signaling_ip_avp parameter. using default.\n");
        signaling_ip_avp.spec.s = SIGNALING_IP_AVP_SPEC;
    }

    if (pv_parse_spec(&(signaling_ip_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LOG(L_CRIT, "invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(signaling_ip_avp.name), &(signaling_ip_avp.type))!=0) {
        LOG(L_CRIT, "invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s);
        return -1;
    }

    // initialize the sip_application_avp structure
    if (sip_application_avp.spec.s==NULL || sip_application_avp.spec.len<=0) {
        LOG(L_ERR, "missing/empty sip_application_avp parameter. using default.\n");
        sip_application_avp.spec.s = SIP_APPLICATION_AVP_SPEC;
    }

    if (pv_parse_spec(&(sip_application_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LOG(L_CRIT, "invalid AVP specification for sip_application_avp: `%s'\n", sip_application_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(sip_application_avp.name), &(sip_application_avp.type))!=0) {
        LOG(L_CRIT, "invalid AVP specification for sip_application_avp: `%s'\n", sip_application_avp.spec.s);
        return -1;
    }

    // bind to the dialog API
    if (load_dlg_api(&dlg_api)!=0) {
        LOG(L_CRIT, "cannot load the dialog module API\n");
        return -1;
    }

    // load dlg_flag and default_timeout parameters from the dialog module
    param = find_param_export(find_module_by_name("dialog"), "dlg_flag", INT_PARAM, &type);
    if (!param) {
        LOG(L_CRIT, "cannot find dlg_flag parameter in the dialog module\n");
        return -1;
    }
    if (type != INT_PARAM) {
        LOG(L_CRIT, "dlg_flag parameter found but with wrong type: %d\n", type);
        return -1;
    }

    dialog_flag = *param;

    // register dialog creation callback
    if (dlg_api.register_dlgcb(NULL, DLGCB_CREATED, __dialog_created, NULL, NULL) != 0) {
        LOG(L_CRIT, "cannot register callback for dialog creation\n");
        return -1;
    }

    // register dialog loading callback
    if (dlg_api.register_dlgcb(NULL, DLGCB_LOADED, __dialog_loaded, NULL, NULL) != 0) {
        LOG(L_ERR, "cannot register callback for dialogs loaded from the database\n");
    }

    // register a pre-script callback to automatically enable dialog tracing
    if (register_script_cb(postprocess_request, POST_SCRIPT_CB|REQUEST_CB, 0) != 0) {
        LOG(L_CRIT, "ERROR:call_control:mod_init: could not register request postprocessing callback\n");
        return -1;
    }

    return 0;
}
예제 #9
0
파일: uac.c 프로젝트: AlessioCasco/kamailio
static int mod_init(void)
{
	pv_spec_t avp_spec;

	if (restore_mode_str && *restore_mode_str) {
		if (strcasecmp(restore_mode_str,"none")==0) {
	    	restore_mode = UAC_NO_RESTORE;
	    } else if (strcasecmp(restore_mode_str,"manual")==0) {
	    	restore_mode = UAC_MANUAL_RESTORE;
	    } else if (strcasecmp(restore_mode_str,"auto")==0) {
			restore_mode = UAC_AUTO_RESTORE;
		} else {
			LM_ERR("unsupported value '%s' for restore_mode\n",  restore_mode_str);
			goto error;
		}
	}

	if ( (rr_from_param.len==0 || rr_to_param.len==0) && restore_mode!=UAC_NO_RESTORE)
	{
		LM_ERR("rr_store_param cannot be empty if FROM is restoreable\n");
		goto error;
	}

	/* parse the auth AVP spesc, if any */
	if ( auth_username_avp || auth_password_avp || auth_realm_avp) {
		if (!auth_username_avp || !auth_password_avp || !auth_realm_avp) {
			LM_ERR("partial definition of auth AVP!");
			goto error;
		}
		if ( parse_auth_avp(auth_realm_avp, &auth_realm_spec, "realm")<0
		|| parse_auth_avp(auth_username_avp, &auth_username_spec, "username")<0
		|| parse_auth_avp(auth_password_avp, &auth_password_spec, "password")<0
		) {
			goto error;
		}
	} else {
		memset( &auth_realm_spec, 0, sizeof(pv_spec_t));
		memset( &auth_password_spec, 0, sizeof(pv_spec_t));
		memset( &auth_username_spec, 0, sizeof(pv_spec_t));
	}

	/* load the TM API - FIXME it should be loaded only
	 * if NO_RESTORE and AUTH */
	if (load_tm_api(&uac_tmb)!=0) {
		LM_ERR("can't load TM API\n");
		goto error;
	}

	if (restore_mode!=UAC_NO_RESTORE) {
		/* load the RR API */
		if (load_rr_api(&uac_rrb)!=0) {
			LM_ERR("can't load RR API\n");
			goto error;
		}


		if(restore_from_avp.s) {

			if (pv_parse_spec(&restore_from_avp, &avp_spec)==0	|| avp_spec.type!=PVT_AVP) {
				LM_ERR("malformed or non AVP %.*s AVP definition\n", restore_from_avp.len, restore_from_avp.s);
				return -1;
			}

			if(pv_get_avp_name(0, &avp_spec.pvp, &restore_from_avp_name, &restore_from_avp_type)!=0) {
				LM_ERR("[%.*s]- invalid AVP definition\n", restore_from_avp.len, restore_from_avp.s);
				return -1;
			}

			restore_from_avp_type |= AVP_VAL_STR;

		}

		if(restore_to_avp.s) {

			if (pv_parse_spec(&restore_to_avp, &avp_spec)==0	|| avp_spec.type!=PVT_AVP) {
				LM_ERR("malformed or non AVP %.*s AVP definition\n", restore_to_avp.len, restore_to_avp.s);
				return -1;
			}

			if(pv_get_avp_name(0, &avp_spec.pvp, &restore_to_avp_name, &restore_to_avp_type)!=0) {
				LM_ERR("[%.*s]- invalid AVP definition\n", restore_to_avp.len, restore_to_avp.s);
				return -1;
			}

			restore_to_avp_type |= AVP_VAL_STR;

		}


		if (restore_mode==UAC_AUTO_RESTORE) {
			/* we need the append_fromtag on in RR */

			memset(&dlg_api, 0, sizeof(struct dlg_binds));
			if (uac_restore_dlg==0 || load_dlg_api(&dlg_api)!=0) {
				if (!uac_rrb.append_fromtag) {
					LM_ERR("'append_fromtag' RR param is not enabled!"
						" - required by AUTO restore mode\n");
					goto error;
				}
				if (uac_restore_dlg!=0)
					LM_DBG("failed to find dialog API - is dialog module loaded?\n");
			}

			/* get all requests doing loose route */
			if (uac_rrb.register_rrcb( rr_checker, 0)!=0) {
				LM_ERR("failed to install RR callback\n");
				goto error;
			}
		}
	}

	if(reg_db_url.s && reg_db_url.len>=0)
	{
		if(!reg_contact_addr.s || reg_contact_addr.len<=0)
		{
			LM_ERR("contact address parameter not set\n");
			goto error;
		}
		if(reg_htable_size>14)
			reg_htable_size = 14;
		if(reg_htable_size<2)
			reg_htable_size = 2;

		reg_htable_size = 1<<reg_htable_size;
		if(uac_reg_init_rpc()!=0)
		{
			LM_ERR("failed to register RPC commands\n");
			goto error;
		}
		if(uac_reg_init_ht(reg_htable_size)<0)
		{
			LM_ERR("failed to init reg htable\n");
			goto error;
		}

		register_procs(1);
		/* add child to update local config framework structures */
		cfg_register_child(1);
	}
	init_from_replacer();

	uac_req_init();

	return 0;
error:
	return -1;
}
예제 #10
0
static int mod_init(void)
{
	pv_spec_t avp_spec;
	str s;

	LM_INFO("initializing...\n");
	
	if(siptrace_table==0 || strlen(siptrace_table)<=0)
	{
		LM_ERR("invalid table name\n");
		return -1;
	}

	if (flag_idx2mask(&trace_flag)<0)
		return -1;

	/* Find a database module */
	if (bind_dbmod(db_url, &db_funcs))
	{
		LM_ERR("unable to bind database module\n");
		return -1;
	}
	if (!DB_CAPABILITY(db_funcs, DB_CAP_INSERT))
	{
		LM_ERR("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)
	{
		LM_ERR("no more shm memory left\n");
		return -1;
	}
	
	*trace_on_flag = trace_on;
	
	/* register callbacks to TM */
	if (load_tm_api(&tmb)!=0)
	{
		LM_ERR("can't load tm api\n");
		return -1;
	}

	if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0) <=0)
	{
		LM_ERR("can't register trace_onreq_in\n");
		return -1;
	}

	/* register sl callback */
	register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0);
	if(register_slcb_f==NULL)
	{
		LM_ERR("can't load sl api\n");
		return -1;
	}
	if(register_slcb_f(SLCB_REPLY_OUT,trace_sl_onreply_out, NULL)!=0)
	{
		LM_ERR("can't register trace_sl_onreply_out\n");
		return -1;
	}
	if(register_slcb_f(SLCB_ACK_IN,trace_sl_ack_in, NULL)!=0)
	{
		LM_ERR("can't register trace_sl_ack_in\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) {
			LM_ERR("no more pkg memory left\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) {
			LM_ERR("bad dup uri\n");
			return -1;
		}
	}

	if(traced_user_avp_str && *traced_user_avp_str)
	{
		s.s = traced_user_avp_str; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", traced_user_avp_str);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp,
					&traced_user_avp_type)!=0)
		{
			LM_ERR("[%s] - invalid AVP definition\n", traced_user_avp_str);
			return -1;
		}
	} else {
		traced_user_avp.n = 0;
		traced_user_avp_type = 0;
	}
	if(trace_table_avp_str && *trace_table_avp_str)
	{
		s.s = trace_table_avp_str; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", trace_table_avp_str);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp,
					&trace_table_avp_type)!=0)
		{
			LM_ERR("[%s] - invalid AVP definition\n", trace_table_avp_str);
			return -1;
		}
	} else {
		trace_table_avp.n = 0;
		trace_table_avp_type = 0;
	}

	return 0;
}
예제 #11
0
/** Module init function */
static int mod_init(void)
{
	char* p = NULL;
	char* flags = NULL;
	int regexp_flags = 0;
	int i = 0, j;
	pv_spec_t avp_spec;

	LM_DBG("start\n");

	/* load b2b_entities api */
	if(load_b2b_api(&b2b_api)< 0)
	{
		LM_ERR("Failed to load b2b api\n");
		return -1;
	}

	if(b2bl_hsize< 1 || b2bl_hsize> 20)
	{
		LM_ERR("Wrong hash size. Needs to be greater than 1"
				" and smaller than 20. Be aware that you should set the log 2"
				" value of the real size\n");
		return -1;
	}
	b2bl_hsize = 1<<b2bl_hsize;

	if(server_address.s == NULL)
	{
		if(extern_scenarios)
		{
			LM_ERR("'server_address' parameter not set. This parameter is"
				" compulsory if you want to use extern scenarios. It must"
				" be set to the IP address of the machine\n");
			return -1;
		}
	}
	else
		server_address.len = strlen(server_address.s);

	if(init_b2bl_htable() < 0)
	{
		LM_ERR("Failed to initialize b2b logic hash table\n");
		return -1;
	}

	if(b2b_clean_period < 0)
	{
		LM_ERR("Wrong parameter - b2b_clean_period [%d]\n", b2b_clean_period);
		return -1;
	}
	if(b2b_update_period < 0)
	{
		LM_ERR("Wrong parameter - b2b_update_period [%d]\n", b2b_update_period);
		return -1;
	}

	if(b2bl_db_mode && db_url.s)
	{
		db_url.len = strlen(db_url.s);
		b2bl_dbtable.len = strlen(b2bl_dbtable.s);
		/* binding to database module  */
		if (db_bind_mod(&db_url, &b2bl_dbf))
		{
			LM_ERR("Database module not found\n");
			return -1;
		}

		if (!DB_CAPABILITY(b2bl_dbf, DB_CAP_ALL))
		{
			LM_ERR("Database module does not implement all functions"
					" needed by b2b_entities module\n");
			return -1;
		}
		b2bl_db = b2bl_dbf.init(&db_url);
		if(!b2bl_db)
		{
			LM_ERR("connecting to database failed\n");
			return -1;
		}

		/*verify table versions */
		if(db_check_table_version(&b2bl_dbf, b2bl_db, &b2bl_dbtable, TABLE_VERSION) < 0)
		{
			LM_ERR("error during table version check\n");
			return -1;
		}

		b2bl_db_init();

		/* reload data */
		if(b2b_logic_restore() < 0)
		{
			LM_ERR("Failed to restore data from database\n");
			return -1;
		}

		if(b2bl_db)
			b2bl_dbf.close(b2bl_db);
		b2bl_db = NULL;
	}
	else
		b2bl_db_mode = 0;

	if (b2bl_key_avp_param.s)
		b2bl_key_avp_param.len = strlen(b2bl_key_avp_param.s);

	if (b2bl_key_avp_param.s && b2bl_key_avp_param.len > 0)
	{
		if (pv_parse_spec(&b2bl_key_avp_param, &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
				b2bl_key_avp_param.len, b2bl_key_avp_param.s);
			return -1;
		}
		if (pv_get_avp_name(0, &(avp_spec.pvp), &b2bl_key_avp_name, &b2bl_key_avp_type)!=0){
			LM_ERR("[%.*s]- invalid AVP definition\n", b2bl_key_avp_param.len,
					b2bl_key_avp_param.s);
			return -1;
		}
	} else {
		b2bl_key_avp_name = -1;
		b2bl_key_avp_type = 0;
	}

	if(b2bl_from_spec_param.s)
	{
		b2bl_from_spec_param.len = strlen(b2bl_from_spec_param.s);
		if(pv_parse_spec(&b2bl_from_spec_param, &b2bl_from_spec)==NULL)
		{
			LM_ERR("failed to parse b2bl_from spec\n");
			return E_CFG;
		}
		switch(b2bl_from_spec.type) {
			case PVT_NONE:
			case PVT_EMPTY:
			case PVT_NULL:
			case PVT_MARKER:
			case PVT_COLOR:
				LM_ERR("invalid b2bl_from spec\n");
				return -1;
			default: ;
		}
	}

	/* parse extra headers */
	if(custom_headers.s)
		custom_headers.len = strlen(custom_headers.s);

	memset(custom_headers_lst, 0, HDR_LST_LEN*sizeof(str));
	custom_headers_lst[i].s = custom_headers.s;
	if(custom_headers.s)
	{
		p = strchr(custom_headers.s, ';');
		while(p)
		{
			custom_headers_lst[i].len = p - custom_headers_lst[i].s;
			/* check if this is among the default headers */
			for(j = 0; j< HDR_DEFAULT_LEN; j++)
			{
				if(custom_headers_lst[i].len == default_headers[j].len &&
						strncmp(custom_headers_lst[i].s, default_headers[j].s,
							default_headers[j].len)== 0)
					goto next_hdr;
			}
			/* check if defined twice */
			for(j = 0; j< i; j++)
			{
				if(custom_headers_lst[i].len == custom_headers_lst[j].len &&
						strncmp(custom_headers_lst[i].s, custom_headers_lst[j].s,
							custom_headers_lst[j].len)== 0)
					goto next_hdr;
			}
			i++;
			if(i == HDR_LST_LEN)
			{
				LM_ERR("Too many extra headers defined."
						" The maximum value is %d\n.", HDR_LST_LEN);
				return -1;
			}
next_hdr:
			p++;
			if(p-custom_headers.s >= custom_headers.len)
				break;
			custom_headers_lst[i].s = p;
			p = strchr(p, ';');
		}
	}

	if(p == NULL)
	{
		custom_headers_lst[i].len = custom_headers.s + custom_headers.len
			- custom_headers_lst[i].s;
		if(custom_headers_lst[i].len == 0)
			i--;
	}
	custom_headers_lst_len = i +1;

	if(custom_headers_regexp.s)
	{
		custom_headers_regexp.len = strlen(custom_headers_regexp.s);
		if ((custom_headers_re=pkg_malloc(sizeof(regex_t)))==0) {
			LM_ERR("no more pkg memory\n");
			return -1;
		}
		if (*custom_headers_regexp.s == '/')
		{
			flags = (char *)memchr(custom_headers_regexp.s+1, '/',
				custom_headers_regexp.len-1);
			if (flags)
			{
				custom_headers_regexp.s++;
				custom_headers_regexp.len = flags - custom_headers_regexp.s;
				custom_headers_regexp.s[custom_headers_regexp.len] = '\0';
				flags++;
				while(*flags != '\0')
				{
					switch (*flags) {
						case 'i':
							regexp_flags |= REG_ICASE;
							break;
						case 'e':
							regexp_flags |= REG_EXTENDED;
							break;
						default:
							LM_ERR("Unknown option '%c'\n", *flags);
					}
					flags++;
				}
			} else {
				LM_ERR("Second '/' missing from regexp\n");
				return -1;
			}
		}
		if (regcomp(custom_headers_re, custom_headers_regexp.s,
		regexp_flags) != 0) {
			pkg_free(custom_headers_re);
			LM_ERR("bad regexp '%.*s'\n",
				custom_headers_regexp.len, custom_headers_regexp.s);
			return -1;
		}
	}

	if(init_callid_hdr.s)
		init_callid_hdr.len = strlen(init_callid_hdr.s);

	register_timer("b2bl-clean", b2bl_clean, 0, b2b_clean_period,
		TIMER_FLAG_DELAY_ON_DELAY);
	if(b2bl_db_mode == WRITE_BACK)
		register_timer("b2bl-dbupdate", b2bl_db_timer_update, 0,
			b2b_update_period, TIMER_FLAG_SKIP_ON_DELAY);

	return 0;
}
예제 #12
0
파일: exec.c 프로젝트: nikbyte/opensips
int exec_avp(struct sip_msg *msg, char *cmd, pvname_list_p avpl)
{
	int_str avp_val;
	int_str avp_name;
	unsigned short avp_type;
	FILE *pipe;
	int ret;
	char res_line[MAX_URI_SIZE+1];
	str res;
	int exit_status;
	int i;
	pvname_list_t* crt;
	pid_t pid;

	/* pessimist: assume error by default */
	ret=-1;

	pid = __popen3(cmd, NULL, &pipe, NULL);
	if (pid < 0) {
		LM_ERR("failed to run command: %s\n", cmd);
		ser_error=E_EXEC;
		return ret;
	}

	LM_DBG("Forked pid %d\n", pid);
	schedule_to_kill(pid);
	wait(&exit_status);

	/* read now line by line */
	i=0;
	crt = avpl;
	while (fgets(res_line, MAX_URI_SIZE, pipe)) {
		res.s = res_line;
		res.len=strlen(res.s);
		trim_trailing(&res);

		/* skip empty line */
		if (res.len==0) continue;
		/* ZT */
		res.s[res.len]=0;

		avp_type = 0;
		if(crt==NULL)
		{
			avp_name.s.s = int2str(i + 1, &avp_name.s.len);
			if (!avp_name.s.s) {
				LM_ERR("cannot convert %d to string\n", i + 1);
				goto error;
			}
			avp_name.n = get_avp_id(&avp_name.s);
			if (avp_name.n < 0) {
				LM_ERR("cannot get avp id\n");
				goto error;
			}
		} else {
			if(pv_get_avp_name(msg, &(crt->sname.pvp), &avp_name.n, &avp_type)!=0)
			{
				LM_ERR("can't get item name [%d]\n",i);
				goto error;
			}
		}

		avp_type |= AVP_VAL_STR;
		avp_val.s = res;

		if(add_avp(avp_type, avp_name.n, avp_val)!=0)
		{
			LM_ERR("unable to add avp\n");
			goto error;
		}

		if(crt)
			crt = crt->next;

		i++;
	}
	if (i==0)
		LM_DBG("no result from %s\n", cmd);
	/* success */
	ret=1;

error:
	if (ferror(pipe)) {
		LM_ERR("pipe: %d/%s\n",	errno, strerror(errno));
		ser_error=E_EXEC;
		ret=-1;
	}

	pclose(pipe);
	if (WIFEXITED(exit_status)) { /* exited properly .... */
		/* return false if script exited with non-zero status */
		if (WEXITSTATUS(exit_status)!=0) ret=-1;
	} else { /* exited erroneously */
		LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n",
			cmd, exit_status, errno, strerror(errno) );
		ret=-1;
	}
	return ret;
}
예제 #13
0
int h350_auth_lookup(
        struct sip_msg* _msg,
        pv_elem_t* _digest_username,
        struct h350_auth_lookup_avp_params* _avp_specs)
{
	str                digest_username,
	                   digest_username_escaped,
	                   digest_password;
	static char        digest_username_buf[DIGEST_USERNAME_BUF_SIZE];
	struct berval      **attr_vals = NULL;
	int                username_avp_name, password_avp_name;
	int_str avp_val;
	unsigned short     username_avp_type, password_avp_type;
	int                rc, ld_result_count;

	/*
	 * get digest_username str
	 */
	if (_digest_username)
	{
                if (pv_printf_s(_msg, _digest_username, &digest_username) != 0)
		{
                        LM_ERR("pv_printf_s failed\n");
                        return E_H350_INTERNAL;
                }
        } else
	{
		LM_ERR("empty digest username\n");
		return E_H350_NO_SUCCESS;
	}

	/*
	 * get AVP names for username and password
	 */

	if (pv_get_avp_name(	_msg,
				&(_avp_specs->username_avp_spec.pvp),
				&username_avp_name,
				&username_avp_type)
		!= 0)
	{
		LM_ERR("error getting AVP name - pv_get_avp_name failed\n");
		return E_H350_INTERNAL;
	}

	if (pv_get_avp_name(_msg,
						&(_avp_specs->password_avp_spec.pvp),
						&password_avp_name,
						&password_avp_type)
                != 0)
        {
                LM_ERR("error getting AVP name - pv_get_avp_name failed\n");
                return E_H350_INTERNAL;
        }

	/*
	 * search for sip digest username in H.350, store digest password
	 */

	/* ldap filter escape digest username */
	digest_username_escaped.s = digest_username_buf;
	digest_username_escaped.len = DIGEST_USERNAME_BUF_SIZE - 1;
	if (ldap_api.ldap_rfc4515_escape(
		&digest_username,
		&digest_username_escaped,
		0)
	   )
        {
                LM_ERR("ldap_rfc4515_escape() failed\n");
                return E_H350_INTERNAL;
        }

	/* do ldap search */
	if (ldap_api.ldap_params_search(&ld_result_count,
                                        h350_ldap_session.s,
                                        h350_base_dn.s,
                                        h350_search_scope_int,
                                        NULL,
                                        H350_AUTH_FILTER_PATTERN,
                                        digest_username_escaped.s)
            != 0)
        {
                LM_ERR("LDAP search failed\n");
		return E_H350_INTERNAL;
        }

	if (ld_result_count < 1)
	{
		LM_INFO("no H.350 entry found for username [%s]\n",
			digest_username_escaped.s);
		return E_H350_NO_SUCCESS;
	}
	if (ld_result_count > 1)
	{
		LM_WARN("more than one [%d] H.350 entry found for username [%s]\n",
			ld_result_count,
			digest_username_escaped.s);
	}

	/* get ldap result values */
	rc = ldap_api.ldap_result_attr_vals(&h350_sip_pwd_name, &attr_vals);
	if (rc < 0)
	{
                LM_ERR("getting LDAP attribute values failed\n");
                ldap_api.ldap_value_free_len(attr_vals);
		return E_H350_INTERNAL;
        }
        if ((rc > 0) || (attr_vals == NULL))
	{
                LM_INFO("no values found in LDAP entry for username [%s]\n",
			digest_username_escaped.s);
		ldap_api.ldap_value_free_len(attr_vals);
		return E_H350_INTERNAL;
        }

	digest_password.s = attr_vals[0]->bv_val;
        digest_password.len = attr_vals[0]->bv_len;

	/*
	 * write AVPs
	 */

	avp_val.s = digest_username;
	if (add_avp(	username_avp_type | AVP_VAL_STR,
			username_avp_name,
			avp_val)
		< 0)
	{
		LM_ERR("failed to create new AVP\n");
		ldap_api.ldap_value_free_len(attr_vals);
		return E_H350_INTERNAL;
	}

	avp_val.s = digest_password;
	if (add_avp(    password_avp_type | AVP_VAL_STR,
                        password_avp_name,
                        avp_val)
                < 0)
        {
                LM_ERR("failed to create new AVP\n");
                ldap_api.ldap_value_free_len(attr_vals);
                return E_H350_INTERNAL;
        }

	ldap_api.ldap_value_free_len(attr_vals);
	return E_H350_SUCCESS;
}
예제 #14
0
int w_insert_avp(struct sip_msg* msg, char* name, char* value,
		char *index_char)
{
	int              index = *(int*)index_char;
	int              avp_name;
	struct usr_avp   *avp= NULL, *prev_avp= NULL;
	struct usr_avp   *avp_new;
	unsigned short   name_type;
	pv_value_t       xvalue;
	int              flags = 0;
	int_str          avp_val;
	pv_elem_t*       pv_dest = (pv_elem_t*)name;
	pv_elem_t*       pv_src = (pv_elem_t*)value;

	/* get avp name */
	if(pv_get_avp_name(msg, &pv_dest->spec.pvp, &avp_name, &name_type)< 0)
	{
		LM_ERR("failed to get src AVP name\n");
		return -1;
	}

	/* get value to be inserted */
	avp = NULL;
	flags = 0;
	if(pv_src->spec.type == PVT_NONE)
	{
		avp_val.s = pv_src->text;
		flags = AVP_VAL_STR;
	}
	else
	{
		if(pv_get_spec_value(msg, &(pv_src->spec), &xvalue)!=0)
		{
			LM_ERR("cannot get src value\n");
			return -1;
		}
		if(xvalue.flags&PV_TYPE_INT)
		{
			avp_val.n = xvalue.ri;
		} else {
			flags = AVP_VAL_STR;
			avp_val.s = xvalue.rs;
		}
	}
	name_type |= flags;
	/* insert it at the right place */
	if(index == 0)
	{
		if(add_avp(name_type, avp_name, avp_val) < 0)
		{
			LM_ERR("Failed to add new avp\n");
			return -1;
		}
		return 1;
	}

	/* search the previous avp */
	index--;
	avp = NULL;
	while ( (avp=search_first_avp( name_type, avp_name, 0, avp))!=0 )
	{
		if( index == 0 )
		{
			break;
		}
		index--;
		prev_avp = avp;
	}

	/* if the index is greater then the count */
	if(avp == NULL)
	{
		if(prev_avp == NULL)
		{
			if(add_avp(name_type, avp_name, avp_val) < 0)
			{
				LM_ERR("Failed to add new avp\n");
				return -1;
			}
			return 1;
		}
		avp = prev_avp;
	}

	/* if a previous record was found -> insert the new avp after it */
	avp_new = new_avp(name_type, avp_name, avp_val);
	if(avp_new == NULL)
	{
		LM_ERR("Failed to allocate new avp structure\n");
		return -1;
	}
	LM_DBG("am alocat un avp nou\n");
	avp_new->next = avp->next;
	avp->next = avp_new;

	return 1;
}
예제 #15
0
파일: mtree.c 프로젝트: tsudot/kamailio
int mt_match_prefix(struct sip_msg *msg, m_tree_t *it,
		str *tomatch, int mode)
{
	int l, len, n;
	int i, j;
	mt_node_t *itn;
	is_t *tvalue;
	int_str dstid_avp_name;
	unsigned short dstid_name_type;
	int_str weight_avp_name;
	unsigned short weight_name_type;
	int_str avp_value;
	mt_dw_t *dw;
	pv_value_t val;

#define MT_MAX_DST_LIST	64
	unsigned int tmp_list[2*(MT_MAX_DST_LIST+1)];

	if(it==NULL || tomatch == NULL
			|| tomatch->s == NULL)
	{
		LM_ERR("bad parameters\n");
		return -1;
	}

	l = len = 0;
	n = 0;
	if ((it->type==MT_TREE_SVAL) || (it->type==MT_TREE_IVAL)) {
		if (mode == 2) 
			return mt_add_tvalues(msg, it, tomatch);
		tvalue = mt_get_tvalue(it, tomatch);
		if (tvalue == NULL) {
			LM_DBG("no match for: %.*s\n", tomatch->len, tomatch->s);
			return -1;
		}
		memset(&val, 0, sizeof(pv_value_t));
		if (it->type==MT_TREE_SVAL) {
			val.flags = PV_VAL_STR;
			val.rs = tvalue->s;
			if(pv_value.setf(msg, &pv_value.pvp, (int)EQ_T, &val)<0) {
				LM_ERR("setting PV failed\n");
				return -2;
			}
		} else {
			val.flags = PV_VAL_INT;
			val.ri = tvalue->n;
			if(pv_value.setf(msg, &pv_value.pvp, (int)EQ_T, &val)<0) {
				LM_ERR("setting PV failed\n");
				return -2;
			}
		}
		return 0;
	}

	if(it->type!=MT_TREE_DW)
		return -1; /* wrong tree type */

	if(pv_get_avp_name(msg, &pv_dstid.pvp, &dstid_avp_name,
				&dstid_name_type)<0)
	{
		LM_ERR("cannot get dstid avp name\n");
		return -1;
	}
	if(pv_get_avp_name(msg, &pv_weight.pvp, &weight_avp_name,
				&weight_name_type)<0)
	{
		LM_ERR("cannot get weight avp name\n");
		return -1;
	}

	itn = it->head;
	memset(tmp_list, 0, sizeof(unsigned int)*2*(MT_MAX_DST_LIST+1));

	while(itn!=NULL && l < tomatch->len && l < MT_MAX_DEPTH)
	{
		/* check validity */
		if(_mt_char_table[(unsigned int)tomatch->s[l]]==255)
		{
			LM_ERR("invalid char at %d in [%.*s]\n",
					l, tomatch->len, tomatch->s);
			return -1;
		}

		if(itn[_mt_char_table[(unsigned int)tomatch->s[l]]].tvalues!=NULL)
		{
			dw = (mt_dw_t*)itn[_mt_char_table[(unsigned int)tomatch->s[l]]].data;
			while(dw) {
				tmp_list[2*n]=dw->dstid;
				tmp_list[2*n+1]=dw->weight;
				n++;
				if(n==MT_MAX_DST_LIST)
					break;
				dw = dw->next;
			}
			len = l+1;
		}
		if(n==MT_MAX_DST_LIST)
			break;

		itn = itn[_mt_char_table[(unsigned int)tomatch->s[l]]].child;
		l++;	
	}

	if(n==0)
		return -1; /* no match */
	/* invalidate duplicated dstid, keeping longest match */
	for(i=(n-1); i>0; i--)
	{
		if (tmp_list[2*i]!=0)
		{
			for(j=0; j<i; j++)
				if(tmp_list[2*i]==tmp_list[2*j])
					tmp_list[2*j] = 0;
		}
	}
	/* sort the table -- bubble sort -- reverse order */
	for (i = (n - 1); i >= 0; i--)
	{
		for (j = 1; j <= i; j++)
		{
			if (tmp_list[2*(j-1)+1] < tmp_list[2*j+1])
			{
				tmp_list[2*MT_MAX_DST_LIST]   = tmp_list[2*(j-1)];
				tmp_list[2*MT_MAX_DST_LIST+1] = tmp_list[2*(j-1)+1];
				tmp_list[2*(j-1)]   = tmp_list[2*j];
				tmp_list[2*(j-1)+1] = tmp_list[2*j+1];
				tmp_list[2*j]   = tmp_list[2*MT_MAX_DST_LIST];
				tmp_list[2*j+1] = tmp_list[2*MT_MAX_DST_LIST+1];
			}
		}
	}
	/* add as avp */
	for(i=0; i<n; i++)
	{
		if(tmp_list[2*i]!=0)
		{
			avp_value.n = (int)tmp_list[2*i+1];
			add_avp(weight_name_type, weight_avp_name, avp_value);
			avp_value.n = (int)tmp_list[2*i];
			add_avp(dstid_name_type, dstid_avp_name, avp_value);
		}
	}

	return 0;
}
예제 #16
0
int ldap_write_result(
	struct sip_msg* _msg,
	struct ldap_result_params* _lrp,
	struct subst_expr* _se)
{
	int                        dst_avp_name;
	int_str dst_avp_val;
	unsigned short             dst_avp_type;
	int                        nmatches, rc, i, added_avp_count = 0;
	struct berval              **attr_vals;
	str                        avp_val_str, *subst_result = NULL;
	int                        avp_val_int;
	
	/*
	* get dst AVP name (dst_avp_name)
	*/
	
	if (pv_get_avp_name(	_msg,
				&(_lrp->dst_avp_spec.pvp), 
				&dst_avp_name, 
				&dst_avp_type)
			!= 0) 
	{
		LM_ERR("error getting dst AVP name\n");
		return -2;
	}

	/*
	* get LDAP attr values
	*/
	if ((rc = ldap_get_attr_vals(&_lrp->ldap_attr_name, &attr_vals)) != 0)
	{
		if (rc > 0) {
			return -1;
		} else {
			return -2;
		}
	}

	/*
	* add AVPs
	*/
	for (i = 0; attr_vals[i] != NULL; i++)
	{
		if (_se == NULL)
		{
			avp_val_str.s = attr_vals[i]->bv_val;
			avp_val_str.len = attr_vals[i]->bv_len;
		}
		else
		{
			subst_result = subst_str(attr_vals[i]->bv_val, _msg, _se,
					&nmatches);
			if ((subst_result == NULL) || (nmatches < 1))
			{
				continue;
			}
			avp_val_str = *subst_result;
		}

		if (_lrp->dst_avp_val_type == 1)
		{
			/* try to convert ldap value to integer */
			if (!str2sint(&avp_val_str, &avp_val_int)) 
			{
				dst_avp_val.n = avp_val_int;
				rc = add_avp(dst_avp_type, dst_avp_name, dst_avp_val);
			} else
			{
				continue;
			}
		} else
		{
			/* save ldap value as string */
			dst_avp_val.s = avp_val_str;
			rc = add_avp(dst_avp_type|AVP_VAL_STR, dst_avp_name, dst_avp_val);
		}
		
		if (subst_result != NULL) {
			if (subst_result->s != 0) {
				pkg_free(subst_result->s);
			}
			pkg_free(subst_result);
			subst_result = NULL;
		}
		
		if (rc < 0) 
		{
			LM_ERR("failed to create new AVP\n");
			ldap_value_free_len(attr_vals);
			return -2;
		}
		added_avp_count++;
	}
	ldap_value_free_len(attr_vals);
	
	if (added_avp_count > 0)
	{
		return added_avp_count;
	} else
	{
		return -1;
	}
}
예제 #17
0
파일: reg_mod.c 프로젝트: gnufreex/kamailio
static int mod_init(void) {
    pv_spec_t avp_spec;
    str s;
    bind_usrloc_t bind_usrloc;
    qvalue_t dq;
    
    callback_singleton = shm_malloc(sizeof (int));
    *callback_singleton = 0;

    /*build the required strings */
    scscf_serviceroute_uri_str.s =
            (char*) pkg_malloc(orig_prefix.len + scscf_name_str.len);

    if (!scscf_serviceroute_uri_str.s) {
        LM_ERR("Unable to allocate memory for service route uri\n");
        return -1;
    }
    
    if (contact_expires_buffer_percentage < 0 || contact_expires_buffer_percentage > 90) {
        LM_ERR("contact expires percentage not valid, must be >0 and <=90");
        return -1;
    }

    memcpy(scscf_serviceroute_uri_str.s, orig_prefix.s, orig_prefix.len);
    scscf_serviceroute_uri_str.len = orig_prefix.len;
    if (scscf_name_str.len > 4
            && strncasecmp(scscf_name_str.s, "sip:", 4) == 0) {
        memcpy(scscf_serviceroute_uri_str.s + scscf_serviceroute_uri_str.len,
                scscf_name_str.s + 4, scscf_name_str.len - 4);
        scscf_serviceroute_uri_str.len += scscf_name_str.len - 4;
    } else {
        memcpy(scscf_serviceroute_uri_str.s + scscf_serviceroute_uri_str.len,
                scscf_name_str.s, scscf_name_str.len);
        scscf_serviceroute_uri_str.len += scscf_name_str.len;
    }
    
    pv_tmx_data_init();

    /* </build required strings> */

#ifdef STATISTICS
    /* register statistics */
    if (register_module_stats(exports.name, mod_stats) != 0) {
        LM_ERR("failed to register core statistics\n");
        return -1;
    }
    if (!register_stats()) {
        LM_ERR("Unable to register statistics\n");
        return -1;
    }
#endif

    /*register space for notification processors*/
    register_procs(notification_processes);
    cfg_register_child(notification_processes);
    
    /* bind the SL API */
    if (sl_load_api(&slb) != 0) {
        LM_ERR("cannot bind to SL API\n");
        return -1;
    }

    /* load the TM API */
    if (load_tm_api(&tmb) != 0) {
        LM_ERR("can't load TM API\n");
        return -1;
    }

    /* load the CDP API */
    if (load_cdp_api(&cdpb) != 0) {
        LM_ERR("can't load CDP API\n");
        return -1;
    }

    cdp_avp = load_cdp_avp();
    if (!cdp_avp) {
        LM_ERR("can't load CDP_AVP API\n");
        return -1;
    }

    if (cfg_declare("registrar", registrar_cfg_def, &default_registrar_cfg,
            cfg_sizeof(registrar), &registrar_cfg)) {
        LM_ERR("Fail to declare the configuration\n");
        return -1;
    }

    if (rcv_avp_param && *rcv_avp_param) {
        s.s = rcv_avp_param;
        s.len = strlen(s.s);
        if (pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) {
            LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param);
            return -1;
        }

        if (pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)
                != 0) {
            LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param);
            return -1;
        }
    } else {
        rcv_avp_name.n = 0;
        rcv_avp_type = 0;
    }
    if (aor_avp_param && *aor_avp_param) {
        s.s = aor_avp_param;
        s.len = strlen(s.s);
        if (pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) {
            LM_ERR("malformed or non AVP %s AVP definition\n", aor_avp_param);
            return -1;
        }

        if (pv_get_avp_name(0, &avp_spec.pvp, &aor_avp_name, &aor_avp_type)
                != 0) {
            LM_ERR("[%s]- invalid AVP definition\n", aor_avp_param);
            return -1;
        }
    } else {
        aor_avp_name.n = 0;
        aor_avp_type = 0;
    }

    if (reg_callid_avp_param && *reg_callid_avp_param) {
        s.s = reg_callid_avp_param;
        s.len = strlen(s.s);
        if (pv_parse_spec(&s, &avp_spec) == 0 || avp_spec.type != PVT_AVP) {
            LM_ERR("malformed or non AVP %s AVP definition\n", reg_callid_avp_param);
            return -1;
        }

        if (pv_get_avp_name(0, &avp_spec.pvp, &reg_callid_avp_name,
                &reg_callid_avp_type) != 0) {
            LM_ERR("[%s]- invalid AVP definition\n", reg_callid_avp_param);
            return -1;
        }
    } else {
        reg_callid_avp_name.n = 0;
        reg_callid_avp_type = 0;
    }

    bind_usrloc = (bind_usrloc_t) find_export("ul_bind_usrloc", 1, 0);
    if (!bind_usrloc) {
        LM_ERR("can't bind usrloc\n");
        return -1;
    }

    /* Normalize default_q parameter */
    dq = cfg_get(registrar, registrar_cfg, default_q);
    if (dq != Q_UNSPECIFIED) {
        if (dq > MAX_Q) {
            LM_DBG("default_q = %d, lowering to MAX_Q: %d\n", dq, MAX_Q);
            dq = MAX_Q;
        } else if (dq < MIN_Q) {
            LM_DBG("default_q = %d, raising to MIN_Q: %d\n", dq, MIN_Q);
            dq = MIN_Q;
        }
    }
    cfg_get(registrar, registrar_cfg, default_q) = dq;

    if (bind_usrloc(&ul) < 0) {
        return -1;
    }

    /*Register for callback of URECORD being deleted - so we can send a SAR*/

    if (ul.register_ulcb == NULL) {
        LM_ERR("Could not import ul_register_ulcb\n");
        return -1;
    }
    
    if (ul.register_ulcb(0, 0, UL_IMPU_INSERT, ul_impu_inserted, 0) < 0) {
        LM_ERR("can not register callback for insert\n");
        return -1;
    }

    if (sock_hdr_name.s) {
        if (sock_hdr_name.len == 0 || sock_flag == -1) {
            LM_WARN("empty sock_hdr_name or sock_flag no set -> reseting\n");
            sock_hdr_name.len = 0;
            sock_flag = -1;
        }
    } else if (sock_flag != -1) {
        LM_WARN("sock_flag defined but no sock_hdr_name -> reseting flag\n");
        sock_flag = -1;
    }

    /* fix the flags */
    sock_flag = (sock_flag != -1) ? (1 << sock_flag) : 0;
    tcp_persistent_flag =
            (tcp_persistent_flag != -1) ? (1 << tcp_persistent_flag) : 0;

    /* init the registrar notifications */
    if (!notify_init()) return -1;

    /* register the registrar notifications timer */
    //Currently we do not use this - we send notifies immediately
    //if (register_timer(notification_timer, notification_list, 5) < 0) return -1;

    return 0;
}
예제 #18
0
/**
 * init module function
 */
static int mod_init(void)
{
	pv_spec_t avp_spec;

	if(register_mi_mod(exports.name, mi_cmds)!=0)
	{
		LM_ERR("failed to register MI commands\n");
		return -1;
	}
	if(ds_init_rpc()<0)
	{
		LM_ERR("failed to register RPC commands\n");
		return -1;
	}

	if (dst_avp_param.s)
		dst_avp_param.len = strlen(dst_avp_param.s);
	if (grp_avp_param.s)
		grp_avp_param.len = strlen(grp_avp_param.s);
	if (cnt_avp_param.s)
		cnt_avp_param.len = strlen(cnt_avp_param.s);	
	if (dstid_avp_param.s)
		dstid_avp_param.len = strlen(dstid_avp_param.s);
	if (attrs_avp_param.s)
		attrs_avp_param.len = strlen(attrs_avp_param.s);
	if (hash_pvar_param.s)
		hash_pvar_param.len = strlen(hash_pvar_param.s);
	if (ds_setid_pvname.s)
		ds_setid_pvname.len = strlen(ds_setid_pvname.s);
	if (ds_attrs_pvname.s)
		ds_attrs_pvname.len = strlen(ds_attrs_pvname.s);
	if (ds_ping_from.s) ds_ping_from.len = strlen(ds_ping_from.s);
	if (ds_ping_method.s) ds_ping_method.len = strlen(ds_ping_method.s);
	if (ds_outbound_proxy.s) ds_outbound_proxy.len = strlen(ds_outbound_proxy.s);

	if(cfg_declare("dispatcher", dispatcher_cfg_def,
				&default_dispatcher_cfg, cfg_sizeof(dispatcher),
				&dispatcher_cfg)){
		LM_ERR("Fail to declare the configuration\n");
		return -1;
	}

	/* Initialize the counter */
	ds_ping_reply_codes = (int**)shm_malloc(sizeof(unsigned int*));
	*ds_ping_reply_codes = 0;
	ds_ping_reply_codes_cnt = (int*)shm_malloc(sizeof(int));
	*ds_ping_reply_codes_cnt = 0;
	if(ds_ping_reply_codes_str.s) {
		ds_ping_reply_codes_str.len = strlen(ds_ping_reply_codes_str.s);
		cfg_get(dispatcher, dispatcher_cfg, ds_ping_reply_codes_str)
			= ds_ping_reply_codes_str;
		if(ds_parse_reply_codes()< 0)
		{
			return -1;
		}
	}	
	/* Copy Threshhold to Config */
	cfg_get(dispatcher, dispatcher_cfg, probing_threshhold)
		= probing_threshhold;


	if(init_data()!= 0)
		return -1;

	if(ds_db_url.s)
	{
		ds_db_url.len     = strlen(ds_db_url.s);
		ds_table_name.len = strlen(ds_table_name.s);
		ds_set_id_col.len        = strlen(ds_set_id_col.s);
		ds_dest_uri_col.len      = strlen(ds_dest_uri_col.s);
		ds_dest_flags_col.len    = strlen(ds_dest_flags_col.s);
		ds_dest_priority_col.len = strlen(ds_dest_priority_col.s);
		ds_dest_attrs_col.len    = strlen(ds_dest_attrs_col.s);

		if(init_ds_db()!= 0)
		{
			LM_ERR("could not initiate a connect to the database\n");
			return -1;
		}
	} else {
		if(ds_load_list(dslistfile)!=0) {
			LM_ERR("no dispatching list loaded from file\n");
			return -1;
		} else {
			LM_DBG("loaded dispatching list\n");
		}
	}

	if (dst_avp_param.s && dst_avp_param.len > 0)
	{
		if (pv_parse_spec(&dst_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					dst_avp_param.len, dst_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &dst_avp_name, &dst_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", dst_avp_param.len,
					dst_avp_param.s);
			return -1;
		}
	} else {
		dst_avp_name.n = 0;
		dst_avp_type = 0;
	}
	if (grp_avp_param.s && grp_avp_param.len > 0)
	{
		if (pv_parse_spec(&grp_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					grp_avp_param.len, grp_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &grp_avp_name, &grp_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", grp_avp_param.len,
					grp_avp_param.s);
			return -1;
		}
	} else {
		grp_avp_name.n = 0;
		grp_avp_type = 0;
	}
	if (cnt_avp_param.s && cnt_avp_param.len > 0)
	{
		if (pv_parse_spec(&cnt_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					cnt_avp_param.len, cnt_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &cnt_avp_name, &cnt_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", cnt_avp_param.len,
					cnt_avp_param.s);
			return -1;
		}
	} else {
		cnt_avp_name.n = 0;
		cnt_avp_type = 0;
	}
	if (dstid_avp_param.s && dstid_avp_param.len > 0)
	{
		if (pv_parse_spec(&dstid_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					dstid_avp_param.len, dstid_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &dstid_avp_name,
					&dstid_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", dstid_avp_param.len,
					dstid_avp_param.s);
			return -1;
		}
	} else {
		dstid_avp_name.n = 0;
		dstid_avp_type = 0;
	}

	if (attrs_avp_param.s && attrs_avp_param.len > 0)
	{
		if (pv_parse_spec(&attrs_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					attrs_avp_param.len, attrs_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &attrs_avp_name,
					&attrs_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", attrs_avp_param.len,
					attrs_avp_param.s);
			return -1;
		}
	} else {
		attrs_avp_name.n = 0;
		attrs_avp_type = 0;
	}

	if (hash_pvar_param.s && *hash_pvar_param.s) {
		if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0
				|| hash_param_model==NULL) {
			LM_ERR("malformed PV string: %s\n", hash_pvar_param.s);
			return -1;
		}		
	} else {
		hash_param_model = NULL;
	}

	if(ds_setid_pvname.s!=0)
	{
		if(pv_parse_spec(&ds_setid_pvname, &ds_setid_pv)==NULL
				|| !pv_is_w(&ds_setid_pv))
		{
			LM_ERR("[%s]- invalid setid_pvname\n", ds_setid_pvname.s);
			return -1;
		}
	}

	if(ds_attrs_pvname.s!=0)
	{
		if(pv_parse_spec(&ds_attrs_pvname, &ds_attrs_pv)==NULL
				|| !pv_is_w(&ds_attrs_pv))
		{
			LM_ERR("[%s]- invalid attrs_pvname\n", ds_attrs_pvname.s);
			return -1;
		}
	}

	if (dstid_avp_param.s && dstid_avp_param.len > 0)
	{
		if(ds_hash_size>0)
		{
			if(ds_hash_load_init(1<<ds_hash_size, ds_hash_expire,
						ds_hash_initexpire)<0)
				return -1;
			register_timer(ds_ht_timer, NULL, ds_hash_check_interval);
		} else {
			LM_ERR("call load dispatching DSTID_AVP set but no size"
					" for hash table\n");
			return -1;
		}
	}
	/* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */
	if (ds_ping_interval > 0)
	{
		/*****************************************************
		 * TM-Bindings
		 *****************************************************/
		if (load_tm_api( &tmb ) == -1)
		{
			LM_ERR("could not load the TM-functions - disable DS ping\n");
			return -1;
		}
		/*****************************************************
		 * Register the PING-Timer
		 *****************************************************/
		register_timer(ds_check_timer, NULL, ds_ping_interval);
	}

	return 0;
}
예제 #19
0
/*! \brief
 * Initialize parent
 */
static int mod_init(void)
{
	pv_spec_t avp_spec;
	str s;
	bind_usrloc_t bind_usrloc;
	qvalue_t dq;


	if(sruid_init(&_reg_sruid, '-', "uloc", SRUID_INC)<0)
		return -1;

#ifdef STATISTICS
	/* register statistics */
	if (register_module_stats( exports.name, mod_stats)!=0 ) {
		LM_ERR("failed to register core statistics\n");
		return -1;
	}
#endif

	/* bind the SL API */
	if (sl_load_api(&slb)!=0) {
		LM_ERR("cannot bind to SL API\n");
		return -1;
	}
	
	if(cfg_declare("registrar", registrar_cfg_def, &default_registrar_cfg, cfg_sizeof(registrar), &registrar_cfg)){
		LM_ERR("Fail to declare the configuration\n");
	        return -1;
	}
	                                                
	                                                

	if (rcv_avp_param && *rcv_avp_param) {
		s.s = rcv_avp_param; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0)
		{
			LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param);
			return -1;
		}
	} else {
		rcv_avp_name.n = 0;
		rcv_avp_type = 0;
	}

	if (reg_callid_avp_param && *reg_callid_avp_param) {
		s.s = reg_callid_avp_param; s.len = strlen(s.s);
		if (pv_parse_spec(&s, &avp_spec)==0
			|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %s AVP definition\n", reg_callid_avp_param);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &reg_callid_avp_name, &reg_callid_avp_type)!=0)
		{
			LM_ERR("[%s]- invalid AVP definition\n", reg_callid_avp_param);
			return -1;
		}
	} else {
		reg_callid_avp_name.n = 0;
		reg_callid_avp_type = 0;
	}

	bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
	if (!bind_usrloc) {
		LM_ERR("can't bind usrloc\n");
		return -1;
	}

	/* Normalize default_q parameter */
	dq = cfg_get(registrar, registrar_cfg, default_q);
	if ( dq!= Q_UNSPECIFIED) {
		if (dq > MAX_Q) {
			LM_DBG("default_q = %d, lowering to MAX_Q: %d\n", dq, MAX_Q);
			dq = MAX_Q;
		} else if (dq < MIN_Q) {
			LM_DBG("default_q = %d, raising to MIN_Q: %d\n", dq, MIN_Q);
			dq = MIN_Q;
		}
	}
	cfg_get(registrar, registrar_cfg, default_q) = dq;

	if (bind_usrloc(&ul) < 0) {
		return -1;
	}

	if(ul.register_ulcb != NULL)
	{
		reg_expire_event_rt = route_lookup(&event_rt, "usrloc:contact-expired");
		if (reg_expire_event_rt>=0 && event_rt.rlist[reg_expire_event_rt]==0)
			reg_expire_event_rt=-1; /* disable */
		if (reg_expire_event_rt>=0) {
			set_child_rpc_sip_mode();
			if(ul.register_ulcb(UL_CONTACT_EXPIRE, reg_ul_expired_contact, 0)< 0)
			{
				LM_ERR("can not register callback for expired contacts\n");
				return -1;
			}
		}
	}
	/*
	 * Import use_domain parameter from usrloc
	 */
	reg_use_domain = ul.use_domain;

	if (sock_hdr_name.s) {
		if (sock_hdr_name.len==0 || sock_flag==-1) {
			LM_WARN("empty sock_hdr_name or sock_flag no set -> reseting\n");
			sock_hdr_name.len = 0;
			sock_flag = -1;
		}
	} else if (sock_flag!=-1) {
		LM_WARN("sock_flag defined but no sock_hdr_name -> reseting flag\n");
		sock_flag = -1;
	}

	if (reg_outbound_mode < 0 || reg_outbound_mode > 2) {
		LM_ERR("outbound_mode modparam must be 0 (not supported), 1 (supported), or 2 (supported and required)\n");
		return -1;
	}

	if (reg_regid_mode < 0 || reg_regid_mode > 1) {
		LM_ERR("regid_mode modparam must be 0 (use with outbound), 1 (use always)\n");
		return -1;
	}

	if (reg_flow_timer < 0 || reg_flow_timer > REG_FLOW_TIMER_MAX
			|| (reg_flow_timer > 0 && reg_outbound_mode == REG_OUTBOUND_NONE)) {
		LM_ERR("bad value for flow_timer\n");
		return -1;
	}

	/* fix the flags */
	sock_flag = (sock_flag!=-1)?(1<<sock_flag):0;
	tcp_persistent_flag = (tcp_persistent_flag!=-1)?(1<<tcp_persistent_flag):0;

	return 0;
}
예제 #20
0
static int
mod_init(void)
{
    pv_spec_t avp_spec;

    // initialize the canonical_uri_avp structure
    if (canonical_uri_avp.spec.s==NULL || *(canonical_uri_avp.spec.s)==0) {
        LM_ERR("missing/empty canonical_uri_avp parameter. using default.\n");
        canonical_uri_avp.spec.s = CANONICAL_URI_AVP_SPEC;
    }
    canonical_uri_avp.spec.len = strlen(canonical_uri_avp.spec.s);
    if (pv_parse_spec(&(canonical_uri_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LM_CRIT("invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(canonical_uri_avp.name), &(canonical_uri_avp.type))!=0) {
        LM_CRIT("invalid AVP specification for canonical_uri_avp: `%s'\n", canonical_uri_avp.spec.s);
        return -1;
    }

    // initialize the signaling_ip_avp structure
    if (signaling_ip_avp.spec.s==NULL || *(signaling_ip_avp.spec.s)==0) {
        LM_ERR("missing/empty signaling_ip_avp parameter. using default.\n");
        signaling_ip_avp.spec.s = SIGNALING_IP_AVP_SPEC;
    }
    signaling_ip_avp.spec.len = strlen(signaling_ip_avp.spec.s);
    if (pv_parse_spec(&(signaling_ip_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LM_CRIT("invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(signaling_ip_avp.name), &(signaling_ip_avp.type))!=0) {
        LM_CRIT("invalid AVP specification for signaling_ip_avp: `%s'\n", signaling_ip_avp.spec.s);
        return -1;
    }

    // initialize the call_limit_avp structure
    if (call_limit_avp.spec.s==NULL || *(call_limit_avp.spec.s)==0) {
        LM_ERR("missing/empty call_limit_avp parameter. using default.\n");
        call_limit_avp.spec.s = CALL_LIMIT_AVP_SPEC;
    }
    call_limit_avp.spec.len = strlen(call_limit_avp.spec.s);
    if (pv_parse_spec(&(call_limit_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LM_CRIT("invalid AVP specification for call_limit_avp: `%s'\n", call_limit_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(call_limit_avp.name), &(call_limit_avp.type))!=0) {
        LM_CRIT("invalid AVP specification for call_limit_avp: `%s'\n", call_limit_avp.spec.s);
        return -1;
    }

    // initialize the call_token_avp structure
    if (call_token_avp.spec.s==NULL || *(call_token_avp.spec.s)==0) {
        LM_ERR("missing/empty call_token_avp parameter. using default.\n");
        call_token_avp.spec.s = CALL_TOKEN_AVP_SPEC;
    }
    call_token_avp.spec.len = strlen(call_token_avp.spec.s);
    if (pv_parse_spec(&(call_token_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LM_CRIT("invalid AVP specification for call_token_avp: `%s'\n", call_token_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(call_token_avp.name), &(call_token_avp.type))!=0) {
        LM_CRIT("invalid AVP specification for call_token_avp: `%s'\n", call_token_avp.spec.s);
        return -1;
    }

    // initialize the diverter_avp structure
    if (diverter_avp.spec.s==NULL || *(diverter_avp.spec.s)==0) {
        LM_ERR("missing/empty diverter_avp parameter. using default.\n");
        diverter_avp.spec.s = DIVERTER_AVP_SPEC;
    }
    diverter_avp.spec.len = strlen(diverter_avp.spec.s);
    if (pv_parse_spec(&(diverter_avp.spec), &avp_spec)==0 || avp_spec.type!=PVT_AVP) {
        LM_CRIT("invalid AVP specification for diverter_avp: `%s'\n", diverter_avp.spec.s);
        return -1;
    }
    if (pv_get_avp_name(0, &(avp_spec.pvp), &(diverter_avp.name), &(diverter_avp.type))!=0) {
        LM_CRIT("invalid AVP specification for diverter_avp: `%s'\n", diverter_avp.spec.s);
        return -1;
    }

    // bind to the dialog API
    if (load_dlg_api(&dlg_api)!=0) {
        LM_CRIT("cannot load the dialog module API\n");
        return -1;
    }

    // register dialog loading callback
    if (dlg_api.register_dlgcb(NULL, DLGCB_LOADED, __dialog_loaded, NULL, NULL) != 0) {
        LM_CRIT("cannot register callback for dialogs loaded from the database\n");
    }

    fix_flag_name(prepaid_account_str, prepaid_account_flag);

    prepaid_account_flag = get_flag_id_by_name(FLAG_TYPE_MSG, prepaid_account_str);

    return 0;
}
예제 #21
0
static int mod_init(void)
{
	pv_spec_t avp_spec;
	int i;

	init_db_url( db_url , 0 /*cannot be null*/);
	siptrace_table.len = strlen(siptrace_table.s);
	date_column.len = strlen(date_column.s);
	callid_column.len = strlen(callid_column.s);
	traced_user_column.len = strlen(traced_user_column.s);
	msg_column.len = strlen(msg_column.s);
	method_column.len = strlen(method_column.s);
	status_column.len = strlen(status_column.s);
	fromproto_column.len = strlen(fromproto_column.s);
	fromip_column.len = strlen(fromip_column.s);
	fromport_column.len = strlen(fromport_column.s);
	toproto_column.len = strlen(toproto_column.s);
	toip_column.len = strlen(toip_column.s);
	toport_column.len = strlen(toport_column.s);
	fromtag_column.len = strlen(fromtag_column.s);
	direction_column.len = strlen(direction_column.s);
	if (traced_user_avp_str.s)
		traced_user_avp_str.len = strlen(traced_user_avp_str.s);
	if (trace_table_avp_str.s)
		trace_table_avp_str.len = strlen(trace_table_avp_str.s);
	if (dup_uri_str.s)
		dup_uri_str.len = strlen(dup_uri_str.s);

	if (trace_local_ip.s)
		parse_trace_local_ip();

	LM_INFO("initializing...\n");

	fix_flag_name(trace_flag_str, trace_flag);

	trace_flag = get_flag_id_by_name(FLAG_TYPE_MSG, trace_flag_str);

	if (flag_idx2mask(&trace_flag)<0)
		return -1;

	trace_to_database_flag = (int*)shm_malloc(sizeof(int));
        if(trace_to_database_flag==NULL) {
                LM_ERR("no more shm memory left\n");
                return -1;
        }

	*trace_to_database_flag = trace_to_database;

	if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) {
		/* Find a database module */
		if (db_bind_mod(&db_url, &db_funcs))
		{
			LM_ERR("unable to bind database module\n");
			return -1;
		}
		if (trace_to_database_flag && !DB_CAPABILITY(db_funcs, DB_CAP_INSERT))
		{
			LM_ERR("database modules does not provide all functions needed by module\n");
			return -1;
		}

		if ((db_con = db_funcs.init(&db_url)) == 0) {
			LM_CRIT("Cannot connect to DB\n");
			return -1;
		}

		if(db_check_table_version(&db_funcs, db_con,
				&siptrace_table, SIPTRACE_TABLE_VERSION) < 0) {
			LM_ERR("error during table version check.\n");
			return -1;
		}

		db_funcs.close(db_con);
		db_con = 0;
	}

	trace_on_flag = (int*)shm_malloc(sizeof(int));
	if(trace_on_flag==NULL)
	{
		LM_ERR("no more shm memory left\n");
		return -1;
	}

	*trace_on_flag = trace_on;



	/* register callbacks to TM */
	if (load_tm_api(&tmb)!=0)
	{
		LM_ERR("can't load tm api\n");
		return -1;
	}

	if(tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, trace_onreq_in, 0, 0) <=0)
	{
		LM_ERR("can't register trace_onreq_in\n");
		return -1;
	}

	/* register sl callback */
	register_slcb_f = (register_slcb_t)find_export("register_slcb", 0, 0);
	if(register_slcb_f==NULL)
	{
		LM_ERR("can't load sl api\n");
		return -1;
	}
	if(register_slcb_f(SLCB_REPLY_OUT,trace_sl_onreply_out, NULL)!=0)
	{
		LM_ERR("can't register trace_sl_onreply_out\n");
		return -1;
	}
	if(register_fwdcb(trace_msg_out_w)!=0)
	{
		LM_ERR("can't register trace_sl_ack_out\n");
		return -1;
	}
	if(enable_ack_trace&&register_slcb_f(SLCB_ACK_IN,trace_sl_ack_in,NULL)!=0)
	{
		LM_ERR("can't register trace_sl_ack_in\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) {
			LM_ERR("no more pkg memory left\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) {
			LM_ERR("bad dup uri\n");
			return -1;
		}
	}

	if(traced_user_avp_str.s && traced_user_avp_str.len > 0)
	{
		if (pv_parse_spec(&traced_user_avp_str, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
				traced_user_avp_str.len, traced_user_avp_str.s);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &traced_user_avp,
					&traced_user_avp_type)!=0)
		{
			LM_ERR("[%.*s] - invalid AVP definition\n",
				traced_user_avp_str.len, traced_user_avp_str.s);
			return -1;
		}
	} else {
		traced_user_avp = -1;
		traced_user_avp_type = 0;
	}
	if(trace_table_avp_str.s && trace_table_avp_str.len > 0)
	{
		if (pv_parse_spec(&trace_table_avp_str, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
				trace_table_avp_str.len, trace_table_avp_str.s);
			return -1;
		}

		if(pv_get_avp_name(0, &avp_spec.pvp, &trace_table_avp,
					&trace_table_avp_type)!=0)
		{
			LM_ERR("[%.*s] - invalid AVP definition\n"
				, trace_table_avp_str.len, trace_table_avp_str.s);
			return -1;
		}
	} else {
		trace_table_avp = -1;
		trace_table_avp_type = 0;
	}

	if (duplicate_with_hep) {
		load_hep = (load_hep_f)find_export("load_hep", 1, 0);
		if (!load_hep) {
			LM_ERR("Can't bind proto hep!\n");
			return -1;
		}

		if (load_hep(&hep_api)) {
			LM_ERR("can't bind proto hep\n");
			return -1;
		}
	}



	/* init the DB keys for future queries */
	db_keys[0] = &msg_column;
	db_keys[1] = &callid_column;
	db_keys[2] = &method_column;
	db_keys[3] = &status_column;
	db_keys[4] = &fromproto_column;
	db_keys[5] = &fromip_column;
	db_keys[6] = &fromport_column;
	db_keys[7] = &toproto_column;
	db_keys[8] = &toip_column;
	db_keys[9] = &toport_column;
	db_keys[10] = &date_column;
	db_keys[11] = &direction_column;
	db_keys[12] = &fromtag_column;
	db_keys[13] = &traced_user_column;

	/* init DB values info which is constant ( type, null ) */
	db_vals[0].type = DB_BLOB;
	db_vals[1].type = DB_STR;
	db_vals[2].type = DB_STR;
	db_vals[3].type = DB_STR;
	db_vals[4].type = DB_STR;
	db_vals[5].type = DB_STR;
	db_vals[6].type = DB_INT;
	db_vals[7].type = DB_STR;
	db_vals[8].type = DB_STR;
	db_vals[9].type = DB_INT;
	db_vals[10].type = DB_DATETIME;
	db_vals[11].type = DB_STRING;
	db_vals[12].type = DB_STR;
	db_vals[13].type = DB_STR;
	/* no field can be null */
	for (i=0;i<NR_KEYS;i++)
		db_vals[i].nul = 0;

	return 0;
}
예제 #22
0
파일: tm.c 프로젝트: Deni90/opensips
int pv_get_tm_branch_avp(struct sip_msg *msg, pv_param_t *param,
		pv_value_t *val)
{
	int avp_name;
	int_str avp_value;
	unsigned short name_type;
	int idx, idxf, res=0;
	struct usr_avp **old_list=NULL;
	struct usr_avp **avp_list=NULL;
	struct usr_avp *avp;
	int_str avp_value0;
	struct usr_avp *avp0;
	int n=0;
	char *p;

	if (!msg || !val)
		goto error;

	avp_list = get_bavp_list();
	if (!avp_list) {
		pv_get_null(msg, param, val);
		goto success;
	}

	if (!param) {
		LM_ERR("bad parameters\n");
		goto error;
	}

	if (pv_get_avp_name(msg, param, &avp_name, &name_type)) {
		LM_ALERT("BUG in getting bavp name\n");
		goto error;
	}

	/* get the index */
	if(pv_get_spec_index(msg, param, &idx, &idxf)!=0) {
		LM_ERR("invalid index\n");
		goto error;
	}

	/* setting the avp head */
	old_list = set_avp_list(avp_list);
	if (!old_list) {
		LM_CRIT("no bavp head list found\n");
		goto error;
	}

	if ((avp=search_first_avp(name_type, avp_name, &avp_value, 0))==0) {
		pv_get_null(msg, param, val);
		goto success;
	}
	val->flags = PV_VAL_STR;
	if ( (idxf==0 || idxf==PV_IDX_INT) && idx==0) {
		if(avp->flags & AVP_VAL_STR) {
			val->rs = avp_value.s;
		} else {
			val->rs.s = sint2str(avp_value.n, &val->rs.len);
			val->ri = avp_value.n;
			val->flags |= PV_VAL_INT|PV_TYPE_INT;
		}
		goto success;
	}
	if(idxf==PV_IDX_ALL) {
		p = pv_local_buf;
		do {
			if(avp->flags & AVP_VAL_STR) {
				val->rs = avp_value.s;
			} else {
				val->rs.s = sint2str(avp_value.n, &val->rs.len);
			}

			if(p-pv_local_buf+val->rs.len+1>PV_LOCAL_BUF_SIZE) {
				LM_ERR("local buffer length exceeded!\n");
				pv_get_null(msg, param, val);
				goto success;
			}
			memcpy(p, val->rs.s, val->rs.len);
			p += val->rs.len;
			if(p-pv_local_buf+PV_FIELD_DELIM_LEN+1>PV_LOCAL_BUF_SIZE) {
				LM_ERR("local buffer length exceeded\n");
				pv_get_null(msg, param, val);
				goto success;
			}
			memcpy(p, PV_FIELD_DELIM, PV_FIELD_DELIM_LEN);
			p += PV_FIELD_DELIM_LEN;
		} while ((avp=search_first_avp(name_type, avp_name,
						&avp_value, avp))!=0);
		*p = 0;
		val->rs.s = pv_local_buf;
		val->rs.len = p - pv_local_buf;
		goto success;
	}

	/* we have a numeric index */
	if(idx<0) {
		n = 1;
		avp0 = avp;
		while ((avp0=search_first_avp(name_type, avp_name,
						&avp_value0, avp0))!=0) n++;
		idx = -idx;
		if(idx>n) {
			LM_DBG("index out of range\n");
			pv_get_null(msg, param, val);
			goto success;
		}
		idx = n - idx;
		if(idx==0) {
			if(avp->flags & AVP_VAL_STR) {
				val->rs = avp_value.s;
			} else {
				val->rs.s = sint2str(avp_value.n, &val->rs.len);
				val->ri = avp_value.n;
				val->flags |= PV_VAL_INT|PV_TYPE_INT;
			}
			goto success;
		}
	}
	n=0;
	while(n<idx &&
			(avp=search_first_avp(name_type, avp_name, &avp_value, avp))!=0)
		n++;

	if(avp!=0) {
		if(avp->flags & AVP_VAL_STR) {
			val->rs = avp_value.s;
		} else {
			val->rs.s = sint2str(avp_value.n, &val->rs.len);
			val->ri = avp_value.n;
			val->flags |= PV_VAL_INT|PV_TYPE_INT;
		}
	}

	goto success;

error:
	res = -1;
success:
	if (old_list)
		set_avp_list(old_list);
	return res;
}
예제 #23
0
파일: tm.c 프로젝트: Deni90/opensips
int pv_set_tm_branch_avp(struct sip_msg *msg, pv_param_t *param, int op,
		pv_value_t *val)
{
	int avp_name;
	int_str avp_val;
	int flags, res=0;
	unsigned short name_type;
	int idx, idxf;
	struct usr_avp **old_list=NULL;
	struct usr_avp **avp_list=NULL;

	if (!msg || !val)
		goto error;

	avp_list = get_bavp_list();
	if (!avp_list) {
		pv_get_null(msg, param, val);
		goto success;
	}

	if (!param) {
		LM_ERR("bad parameters\n");
		goto error;
	}

	if (pv_get_avp_name(msg, param, &avp_name, &name_type)) {
		LM_ALERT("BUG in getting bavp name\n");
		goto error;
	}

	/* get the index */
	if(pv_get_spec_index(msg, param, &idx, &idxf)!=0) {
		LM_ERR("invalid index\n");
		goto error;
	}

	/* setting the avp head */
	old_list = set_avp_list(avp_list);
	if (!old_list) {
		LM_CRIT("no bavp head list found\n");
		goto error;
	}

	if(val == NULL) {
		if(op == COLONEQ_T || idxf == PV_IDX_ALL)
			destroy_avps(name_type, avp_name, 1);
		else {
			if(idx < 0) {
				LM_ERR("index with negative value\n");
				goto error;
			}
			destroy_index_avp(name_type, avp_name, idx);
		}
		/* restoring head */
		goto success;
	}

	if(op == COLONEQ_T || idxf == PV_IDX_ALL)
		destroy_avps(name_type, avp_name, 1);

	flags = name_type;
	if(val->flags&PV_TYPE_INT) {
		avp_val.n = val->ri;
	} else {
		avp_val.s = val->rs;
		flags |= AVP_VAL_STR;
	}

	if(idxf == PV_IDX_INT || idxf == PV_IDX_PVAR) {
		if(replace_avp(flags, avp_name, avp_val, idx)< 0) {
			LM_ERR("failed to replace bavp\n");
			goto error;
		}
	} else {
		if (add_avp(flags, avp_name, avp_val)<0) {
			LM_ERR("error - cannot add bavp\n");
			goto error;
		}
	}
	goto success;

error:
	res = -1;
success:
	if (old_list)
		set_avp_list(old_list);
	return res;
}
예제 #24
0
static int
mmg_lookup_cmd(struct sip_msg *msg, char *_fields_pv, char *_ipaddr_pv, char *_dst_spec)
{
	pv_elem_t *fields_pv=(pv_elem_t*)_fields_pv, *ipaddr_pv=(pv_elem_t*)_ipaddr_pv;
	pv_spec_t *dst_spec=(pv_spec_t*)_dst_spec;
	GeoIPRecord *gir=0;
	str field_str, ipaddr_str;
	char rslt_buf[256], ipaddr_buf[256], field_buf[256];
	char *token=0, *saveptr=0;

	int dst_name=-1;
	int_str rslt=(int_str)0;
	unsigned short dstType=0;

	/* Sanity checks */
	if(!(ipaddr_pv && fields_pv && dst_spec)) {
		LM_ERR("Missing argument(s).\n");
		return -1;
	}
	if(dst_spec->type != PVT_AVP) {
		LM_ERR("Invalid destination spec -- expected AVP.\n");
		return -1;
	}
	if(pv_get_avp_name(msg, &(dst_spec->pvp), &dst_name, &dstType)!=0) {
		LM_ERR("Internal error getting AVP name.\n");
		return -1;
	}

	/* Expand input args: lookup field list and IP address.*/
	*ipaddr_buf=0;
	ipaddr_str.s=ipaddr_buf;
	ipaddr_str.len=sizeof ipaddr_buf;
	if(pv_printf(msg, ipaddr_pv, ipaddr_buf,  &ipaddr_str.len) || ipaddr_str.len==0) {
		LM_ERR("Internal error parsing IP address.\n");
		return -1;
	}

	*field_buf=0;
	field_str.s=field_buf;
	field_str.len=sizeof field_buf;
	if(pv_printf(msg, fields_pv, field_buf,  &field_str.len) || field_str.len==0) {
		LM_ERR("Internal error parsing lookup fields.\n");
		return -1;
	}

	/* Attempt lookup */
	if(!(gir=GeoIP_record_by_name (MMG_gi,ipaddr_buf))){
		LM_DBG("'%s'--> 'Unknown'.\n", *ipaddr_buf?ipaddr_buf:"Undefined");
		return -1;
	}

	/* Construct return data. Know fields are: */
	/* 	   lat		- latitude */
	/* 	   lon		- longitude */
	/* 	   cont		- continent  */
	/* 	   cc		- country code */
	/* 	   reg		- region */
	/* 	   city		- city */
	/* 	   pc		- postal code */
	/* 	   dma		- dma code */
	/* 	   ac		- area code  */
	/* 	   tz		- timezone  */

#define MMG_FAIL_EXIT if(gir) GeoIPRecord_delete(gir); return -1

	LM_DBG("ipaddr:'%.*s'; fields:'%.*s'.\n",
		   ipaddr_str.len, ipaddr_str.s, field_str.len, field_str.s);
	*rslt_buf=0;
	rslt.s.s=rslt_buf;
	token=strtok_r(field_buf,MMG_OP_DELIMS,&saveptr);
	while (token) {
		if(!strcmp(token,"lat")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%f",gir->latitude); }
		else if(!strcmp(token,"lon"))  { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%f",gir->longitude); }
		else if(!strcmp(token,"cont")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->continent_code); }
		else if(!strcmp(token,"cc"))   { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->country_code); }
		else if(!strcmp(token,"reg"))  { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->region); }
		else if(!strcmp(token,"city")) { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->city); }
		else if(!strcmp(token,"pc"))   { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%s",gir->postal_code); }
		else if(!strcmp(token,"dma"))  { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%d",gir->dma_code); }
		else if(!strcmp(token,"ac"))   { rslt.s.len=snprintf(rslt_buf,sizeof rslt_buf,"%d",gir->area_code); }
		else if(!strcmp(token,"rbc"))  {
			rslt.s.len=snprintf(
				rslt_buf,sizeof rslt_buf,"%s",GeoIP_region_name_by_code(gir->country_code, gir->region));
		}
		else if(!strcmp(token,"tz"))   {
			rslt.s.len=snprintf(
				rslt_buf,sizeof rslt_buf,"%s",GeoIP_time_zone_by_country_and_region(gir->country_code, gir->region));
		} else {
			LM_ERR("unknown field:'%s'\n",token);
			MMG_FAIL_EXIT;
		}
		if(rslt.s.len<0 || rslt.s.len>sizeof rslt_buf ||
		add_avp(dstType|AVP_VAL_STR,dst_name,rslt)==-1 ) {
			LM_ERR("Internal error processing field/IP '%s/%s'.\n",
				token,ipaddr_buf);
			MMG_FAIL_EXIT;
		}
		LM_DBG("field %s[%s] %.*s\n",ipaddr_buf,token,rslt.s.len,rslt.s.s);
		token=strtok_r(0,MMG_OP_DELIMS,&saveptr);
	}
	GeoIPRecord_delete(gir);
	return 1;
}
예제 #25
0
static int mod_init( void )
{
	pv_spec_t avp_spec;

	LM_INFO("initializing...\n");

	if (db_url.s)
		db_url.len = strlen(db_url.s);
	db_table_acc.len = strlen(db_table_acc.s);
	db_table_mc.len = strlen(db_table_mc.s);
	acc_method_col.len = strlen(acc_method_col.s);
	acc_fromtag_col.len = strlen(acc_fromtag_col.s);
	acc_totag_col.len = strlen(acc_totag_col.s);
	acc_callid_col.len = strlen(acc_callid_col.s);
	acc_sipcode_col.len = strlen(acc_sipcode_col.s);
	acc_sipreason_col.len = strlen(acc_sipreason_col.s);
	acc_time_col.len = strlen(acc_time_col.s);

	if (log_facility_str) {
		int tmp = str2facility(log_facility_str);
		if (tmp != -1)
			acc_log_facility = tmp;
		else {
			LM_ERR("invalid log facility configured");
			return -1;
		}
	}

	/* ----------- GENERIC INIT SECTION  ----------- */

	fix_flag_name(failed_transaction_string, failed_transaction_flag);

	failed_transaction_flag =
	    get_flag_id_by_name(FLAG_TYPE_MSG, failed_transaction_string);

	if (flag_idx2mask(&failed_transaction_flag)<0)
		return -1;
	fix_flag_name(cdr_string, cdr_flag);

	cdr_flag = get_flag_id_by_name(FLAG_TYPE_MSG, cdr_string);

	if (flag_idx2mask(&cdr_flag)<0)
		return -1;

	/* load the TM API */
	if (load_tm_api(&tmb)!=0) {
		LM_ERR("can't load TM API\n");
		return -1;
	}

	if (load_dlg_api(&dlg_api)!=0)
		LM_DBG("failed to find dialog API - is dialog module loaded?\n");

	if (cdr_flag && !dlg_api.get_dlg) {
		LM_WARN("error loading dialog module - cdrs cannot be generated\n");
		cdr_flag = 0;
	}
	/* if detect_direction is enabled, load rr also */
	if (detect_direction) {
		if (load_rr_api(&rrb)!=0) {
			LM_ERR("can't load RR API\n");
			return -1;
		}
		/* we need the append_fromtag on in RR */
		if (!rrb.append_fromtag) {
			LM_ERR("'append_fromtag' RR param is not enabled!"
				" - required by 'detect_direction'\n");
			return -1;
		}
	}

	/* listen for all incoming requests  */
	if ( tmb.register_tmcb( 0, 0, TMCB_REQUEST_IN, acc_onreq, 0, 0 ) <=0 ) {
		LM_ERR("cannot register TMCB_REQUEST_IN callback\n");
		return -1;
	}

	/* init the extra engine */
	init_acc_extra();

	/* configure multi-leg accounting */
	if (leg_info_str && (leg_info=parse_acc_leg(leg_info_str))==0 ) {
		LM_ERR("failed to parse multi_leg_info param\n");
		return -1;
	}
	if (leg_bye_info_str && (leg_bye_info=parse_acc_leg(leg_bye_info_str))==0 ) {
		LM_ERR("failed to parse multi_leg_bye_info param\n");
		return -1;
	}

	/* ----------- SYSLOG INIT SECTION ----------- */

	/* parse the extra string, if any */
	if (log_extra_str && (log_extra=parse_acc_extra(log_extra_str, 1))==0 ) {
		LM_ERR("failed to parse log_extra param\n");
		return -1;
	}
	if (log_extra_bye_str &&
			(log_extra_bye=parse_acc_extra(log_extra_bye_str, 0))==0 ) {
		LM_ERR("failed to parse log_extra_bye param\n");
		return -1;
	}

	fix_flag_name(log_string, log_flag);

	log_flag = get_flag_id_by_name(FLAG_TYPE_MSG, log_string);

	if (flag_idx2mask(&log_flag)<0)
		return -1;

	fix_flag_name(log_missed_string, log_missed_flag);

	log_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, log_missed_string);

	if (flag_idx2mask(&log_missed_flag)<0)
		return -1;

	acc_log_init();

	/* ------------ SQL INIT SECTION ----------- */

	if (db_url.s && db_url.len > 0) {
		/* parse the extra string, if any */
		if (db_extra_str && (db_extra=parse_acc_extra(db_extra_str, 1))==0 ) {
			LM_ERR("failed to parse db_extra param\n");
			return -1;
		}
		if (db_extra_bye_str &&
				(db_extra_bye=parse_acc_extra(db_extra_bye_str, 0))==0 ) {
			LM_ERR("failed to parse db_extra_bye param\n");
			return -1;
		}
		if (acc_db_init(&db_url)<0){
			LM_ERR("failed...did you load a database module?\n");
			return -1;
		}
		/* fix the flags */
		fix_flag_name(db_string, db_flag);

		db_flag = get_flag_id_by_name(FLAG_TYPE_MSG, db_string);

		if (flag_idx2mask(&db_flag)<0)
			return -1;

		fix_flag_name(db_missed_string, db_missed_flag);

		db_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, db_missed_string);

		if (flag_idx2mask(&db_missed_flag)<0)
			return -1;
		if (db_table_avp.s) {
			db_table_avp.len = strlen(db_table_avp.s);
			if (pv_parse_spec(&db_table_avp, &avp_spec) == 0 ||
					avp_spec.type != PVT_AVP) {
				LM_ERR("malformed or non AVP %s\n", db_table_avp.s);
				return -1;
			}
			if (pv_get_avp_name(0, &avp_spec.pvp, &db_table_name,
						&db_table_name_type)) {
				LM_ERR("invalid definition of AVP %s\n", db_table_avp.s);
				return -1;
			}
		}
	} else {
		db_flag = 0;
		db_missed_flag = 0;
	}

	/* ------------ AAA PROTOCOL INIT SECTION ----------- */

	if (aaa_proto_url && aaa_proto_url[0]) {
		/* parse the extra string, if any */
		if (aaa_extra_str && (aaa_extra = parse_acc_extra(aaa_extra_str, 1))==0) {
			LM_ERR("failed to parse aaa_extra param\n");
			return -1;
		}
		if (aaa_extra_bye_str &&
				(aaa_extra_bye = parse_acc_extra(aaa_extra_bye_str, 0))==0) {
			LM_ERR("failed to parse aaa_extra_bye param\n");
			return -1;
		}

		/* fix the flags */
		fix_flag_name(aaa_string, aaa_flag);

		aaa_flag = get_flag_id_by_name(FLAG_TYPE_MSG, aaa_string);

		if (flag_idx2mask(&aaa_flag)<0)
			return -1;

		fix_flag_name(aaa_missed_string, aaa_missed_flag);

		aaa_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, aaa_missed_string);

		if (flag_idx2mask(&aaa_missed_flag)<0)
			return -1;

		if (init_acc_aaa(aaa_proto_url, service_type)!=0 ) {
			LM_ERR("failed to init radius\n");
			return -1;
		}
	} else {
		aaa_proto_url = NULL;
		aaa_flag = 0;
		aaa_missed_flag = 0;
	}

	/* ------------ DIAMETER INIT SECTION ----------- */

#ifdef DIAM_ACC
	/* fix the flags */
	fix_flag_name(diameter_string, diameter_flag);

	diameter_flag = get_flag_id_by_name(FLAG_TYPE_MSG, diameter_string);

	if (flag_idx2mask(&diameter_flag)<0)
		return -1;

	fix_flag_name(diameter_missed_string, diameter_missed_flag);

	diameter_missed_flag=get_flag_id_by_name(FLAG_TYPE_MSG, diameter_missed_string);

	if (flag_idx2mask(&diameter_missed_flag)<0)
		return -1;

	/* parse the extra string, if any */
	if (dia_extra_str && (dia_extra=parse_acc_extra(dia_extra_str))==0 ) {
		LM_ERR("failed to parse dia_extra param\n");
		return -1;
	}

	if (acc_diam_init()!=0) {
		LM_ERR("failed to init diameter engine\n");
		return -1;
	}

#endif

	/* ------------ EVENTS INIT SECTION ----------- */

	if (evi_extra_str && (evi_extra = parse_acc_extra(evi_extra_str, 1))==0) {
		LM_ERR("failed to parse evi_extra param\n");
		return -1;
	}
	if (evi_extra_bye_str &&
			(evi_extra_bye = parse_acc_extra(evi_extra_bye_str, 0))==0) {
		LM_ERR("failed to parse evi_extra_bye param\n");
		return -1;
	}

	/* fix the flags */
	fix_flag_name(evi_string, evi_flag);

	evi_flag = get_flag_id_by_name(FLAG_TYPE_MSG, evi_string);

	if (flag_idx2mask(&evi_flag)<0)
		return -1;

	fix_flag_name(evi_missed_string, evi_missed_flag);

	evi_missed_flag = get_flag_id_by_name(FLAG_TYPE_MSG, evi_missed_string);

	if (flag_idx2mask(&evi_missed_flag)<0)
		return -1;

	if (init_acc_evi() < 0) {
		LM_ERR("cannot init acc events\n");
		return -1;
	}

	/* load callbacks */
	if (cdr_flag && dlg_api.get_dlg && dlg_api.register_dlgcb(NULL,
				DLGCB_LOADED,acc_loaded_callback, NULL, NULL) < 0)
			LM_ERR("cannot register callback for dialog loaded - accounting "
					"for ongoing calls will be lost after restart\n");


	return 0;
}
예제 #26
0
/**
 * init module function
 */
static int mod_init(void)
{
	pv_spec_t avp_spec;

	LM_DBG("initializing ...\n");

	if (dst_avp_param.s)
		dst_avp_param.len = strlen(dst_avp_param.s);
	if (grp_avp_param.s)
		grp_avp_param.len = strlen(grp_avp_param.s);
	if (cnt_avp_param.s)
		cnt_avp_param.len = strlen(cnt_avp_param.s);
	if (attrs_avp_param.s)
		attrs_avp_param.len = strlen(attrs_avp_param.s);
	if (hash_pvar_param.s)
		hash_pvar_param.len = strlen(hash_pvar_param.s);
	if (ds_setid_pvname.s)
		ds_setid_pvname.len = strlen(ds_setid_pvname.s);
	if (ds_ping_from.s) ds_ping_from.len = strlen(ds_ping_from.s);
	if (ds_ping_method.s) ds_ping_method.len = strlen(ds_ping_method.s);

	if(options_reply_codes_str.s)
	{
		options_reply_codes_str.len = strlen(options_reply_codes_str.s);
		if(parse_reply_codes( &options_reply_codes_str, &options_reply_codes,
		&options_codes_no )< 0)
		{
			LM_ERR("Bad format for options_reply_code parameter"
					" - Need a code list separated by commas\n");
			return -1;
		}
	}

	if(init_data()!= 0)
		return -1;

	if(ds_db_url.s)
	{
		ds_db_url.len     = strlen(ds_db_url.s);
		ds_table_name.len = strlen(ds_table_name.s);
		ds_set_id_col.len     = strlen(ds_set_id_col.s);
		ds_dest_uri_col.len   = strlen(ds_dest_uri_col.s);
		ds_dest_flags_col.len = strlen(ds_dest_flags_col.s);
		ds_dest_weight_col.len= strlen(ds_dest_weight_col.s);
		ds_dest_attrs_col.len = strlen(ds_dest_attrs_col.s);

		if(init_ds_db()!= 0)
		{
			LM_ERR("could not initiate a connect to the database\n");
			return -1;
		}
	} else {
		if(ds_load_list(dslistfile)!=0) {
			LM_ERR("no dispatching list loaded from file\n");
			return -1;
		} else {
			LM_DBG("loaded dispatching list\n");
		}
	}

	if (dst_avp_param.s && dst_avp_param.len > 0)
	{
		if (pv_parse_spec(&dst_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					dst_avp_param.len, dst_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &dst_avp_name,&dst_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", dst_avp_param.len,
					dst_avp_param.s);
			return -1;
		}
	} else {
		dst_avp_name.n = 0;
		dst_avp_type = 0;
	}

	if (grp_avp_param.s && grp_avp_param.len > 0)
	{
		if (pv_parse_spec(&grp_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					grp_avp_param.len, grp_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &grp_avp_name,&grp_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", grp_avp_param.len,
					grp_avp_param.s);
			return -1;
		}
	} else {
		grp_avp_name.n = 0;
		grp_avp_type = 0;
	}

	if (cnt_avp_param.s && cnt_avp_param.len > 0)
	{
		if (pv_parse_spec(&cnt_avp_param, &avp_spec)==0
				|| avp_spec.type!=PVT_AVP)
		{
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					cnt_avp_param.len, cnt_avp_param.s);
			return -1;
		}

		if(pv_get_avp_name(0, &(avp_spec.pvp), &cnt_avp_name,&cnt_avp_type)!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition\n", cnt_avp_param.len,
					cnt_avp_param.s);
			return -1;
		}
	} else {
		cnt_avp_name.n = 0;
		cnt_avp_type = 0;
	}

	if (attrs_avp_param.s && attrs_avp_param.len > 0) {
		if (pv_parse_spec(&attrs_avp_param, &avp_spec)==0
		|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					attrs_avp_param.len, attrs_avp_param.s);
			return -1;
		}

		if (pv_get_avp_name(0, &(avp_spec.pvp), &attrs_avp_name,
		&attrs_avp_type)!=0){
			LM_ERR("[%.*s]- invalid AVP definition\n", attrs_avp_param.len,
					attrs_avp_param.s);
			return -1;
		}
	} else {
		attrs_avp_name.n = 0;
		attrs_avp_type = 0;
	}

	if (hash_pvar_param.s && *hash_pvar_param.s) {
		if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0
				|| hash_param_model==NULL) {
			LM_ERR("malformed PV string: %s\n", hash_pvar_param.s);
			return -1;
		}		
	} else {
		hash_param_model = NULL;
	}

	if(ds_setid_pvname.s!=0)
	{
		if(pv_parse_spec(&ds_setid_pvname, &ds_setid_pv)==NULL
				|| !pv_is_w(&ds_setid_pv))
		{
			LM_ERR("[%s]- invalid setid_pvname\n", ds_setid_pvname.s);
			return -1;
		}
	}
	/* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */
	if (ds_ping_interval > 0)
	{
		load_tm_f load_tm;
		str host;
		int port,proto;

		if (probing_sock_s && probing_sock_s[0]!=0 ) {
			if (parse_phostport( probing_sock_s, strlen(probing_sock_s),
			&host.s, &host.len, &port, &proto)!=0 ) {
				LM_ERR("socket description <%s> is not valid\n",
					probing_sock_s);
				return -1;
			}
			probing_sock = grep_sock_info( &host, port, proto);
			if (probing_sock==NULL) {
				LM_ERR("socket <%s> is not local to opensips (we must listen "
					"on it\n", probing_sock_s);
				return -1;
			}
		}
		/* TM-Bindings */
		load_tm=(load_tm_f)find_export("load_tm", 0, 0);
		if (load_tm==NULL) {
			LM_ERR("failed to bind to the TM-Module - required for probing\n");
			return -1;
		}
		/* let the auto-loading function load all TM stuff */
		if (load_tm( &tmb ) == -1) {
			LM_ERR("could not load the TM-functions - disable DS ping\n");
			return -1;
		}
		/* Register the PING-Timer */
		if (register_timer(ds_check_timer, NULL, ds_ping_interval)<0) {
			LM_ERR("failed to register timer for probing!\n");
			return -1;
		}
	}

	return 0;
}
예제 #27
0
파일: dispatcher.c 프로젝트: Danfx/opensips
static int partition_init(ds_db_head_t *db_head, ds_partition_t *partition)
{

	/* Load stuff from DB. URL cannot be null!*/
	if (db_head->db_url.s == NULL){
		LM_ERR("[%.*s] DB URL is not defined!\n", db_head->partition_name.len,
				db_head->partition_name.s);
		return -1;
	}

	memset(partition, 0, sizeof(ds_partition_t));
	partition->name = db_head->partition_name;
	partition->table_name = db_head->table_name;
	partition->db_url = db_head->db_url;
	partition->db_handle = pkg_malloc(sizeof(struct db_con_t *));
	if (partition->db_handle == NULL) {
		LM_ERR("Failed to allocate private data\n");
		return -1;
	}
	*partition->db_handle = NULL;

	/* handle AVPs spec */
	pv_spec_t avp_spec;

	if (pv_parse_spec(&db_head->dst_avp, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			db_head->dst_avp.len, db_head->dst_avp.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->dst_avp_name,
				&partition->dst_avp_type)!=0) {
		LM_ERR("[%.*s]- invalid AVP definition\n", db_head->dst_avp.len,
			db_head->dst_avp.s);
		return -1;
	}

	if (pv_parse_spec(&db_head->grp_avp, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			db_head->grp_avp.len, db_head->grp_avp.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->grp_avp_name,
				&partition->grp_avp_type)!=0) {
		LM_ERR("[%.*s]- invalid AVP definition\n", db_head->grp_avp.len,
			db_head->grp_avp.s);
		return -1;
	}

	if (pv_parse_spec(&db_head->cnt_avp, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			db_head->cnt_avp.len, db_head->cnt_avp.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->cnt_avp_name,
				&partition->cnt_avp_type)!=0) {
		LM_ERR("[%.*s]- invalid AVP definition\n", db_head->cnt_avp.len,
			db_head->cnt_avp.s);
		return -1;
	}

	if (pv_parse_spec(&db_head->sock_avp, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			db_head->sock_avp.len, db_head->sock_avp.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &partition->sock_avp_name,
				&partition->sock_avp_type)!=0){
		LM_ERR("[%.*s]- invalid AVP definition\n", db_head->sock_avp.len,
			db_head->sock_avp.s);
		return -1;
	}

	if (db_head->attrs_avp.s && db_head->attrs_avp.len > 0) {
		if (pv_parse_spec(&db_head->attrs_avp, &avp_spec)==0
		|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					db_head->attrs_avp.len, db_head->attrs_avp.s);
			return -1;
		}

		if (pv_get_avp_name(0, &(avp_spec.pvp), &partition->attrs_avp_name,
		&partition->attrs_avp_type)!=0){
			LM_ERR("[%.*s]- invalid AVP definition\n", db_head->attrs_avp.len,
					db_head->attrs_avp.s);
			return -1;
		}
	} else {
		partition->attrs_avp_name = -1;
		partition->attrs_avp_type = 0;
	}

	return 0;
}
예제 #28
0
/**
 * init module function
 */
static int mod_init(void)
{
	pv_spec_t avp_spec;

	LM_DBG("initializing ...\n");

	/* Load stuff from DB */
	init_db_url( ds_db_url , 0 /*cannot be null*/);

	ds_table_name.len = strlen(ds_table_name.s);
	ds_set_id_col.len = strlen(ds_set_id_col.s);
	ds_dest_uri_col.len = strlen(ds_dest_uri_col.s);
	ds_dest_sock_col.len = strlen(ds_dest_sock_col.s);
	ds_dest_state_col.len = strlen(ds_dest_state_col.s);
	ds_dest_weight_col.len = strlen(ds_dest_weight_col.s);
	ds_dest_attrs_col.len = strlen(ds_dest_attrs_col.s);

	/* handle AVPs spec */
	dst_avp_param.len = strlen(dst_avp_param.s);
	if (pv_parse_spec(&dst_avp_param, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			dst_avp_param.len, dst_avp_param.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &dst_avp_name,&dst_avp_type)!=0) {
		LM_ERR("[%.*s]- invalid AVP definition\n", dst_avp_param.len,
			dst_avp_param.s);
		return -1;
	}

	grp_avp_param.len=strlen(grp_avp_param.s);
	if (pv_parse_spec(&grp_avp_param, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			grp_avp_param.len, grp_avp_param.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &grp_avp_name,&grp_avp_type)!=0) {
		LM_ERR("[%.*s]- invalid AVP definition\n", grp_avp_param.len,
			grp_avp_param.s);
		return -1;
	}

	cnt_avp_param.len=strlen(cnt_avp_param.s);
	if (pv_parse_spec(&cnt_avp_param, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			cnt_avp_param.len, cnt_avp_param.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &cnt_avp_name,&cnt_avp_type)!=0) {
		LM_ERR("[%.*s]- invalid AVP definition\n", cnt_avp_param.len,
			cnt_avp_param.s);
		return -1;
	}

	sock_avp_param.len=strlen(sock_avp_param.s);
	if (pv_parse_spec(&sock_avp_param, &avp_spec)==0
	|| avp_spec.type!=PVT_AVP) {
		LM_ERR("malformed or non AVP %.*s AVP definition\n",
			sock_avp_param.len, sock_avp_param.s);
		return -1;
	}
	if(pv_get_avp_name(0, &(avp_spec.pvp), &sock_avp_name,&sock_avp_type)!=0){
		LM_ERR("[%.*s]- invalid AVP definition\n", sock_avp_param.len,
			sock_avp_param.s);
		return -1;
	}

	if (attrs_avp_param.s && (attrs_avp_param.len=strlen(attrs_avp_param.s)) > 0) {
		if (pv_parse_spec(&attrs_avp_param, &avp_spec)==0
		|| avp_spec.type!=PVT_AVP) {
			LM_ERR("malformed or non AVP %.*s AVP definition\n",
					attrs_avp_param.len, attrs_avp_param.s);
			return -1;
		}

		if (pv_get_avp_name(0, &(avp_spec.pvp), &attrs_avp_name,
		&attrs_avp_type)!=0){
			LM_ERR("[%.*s]- invalid AVP definition\n", attrs_avp_param.len,
					attrs_avp_param.s);
			return -1;
		}
	} else {
		attrs_avp_name = -1;
		attrs_avp_type = 0;
	}

	if (hash_pvar_param.s && (hash_pvar_param.len=strlen(hash_pvar_param.s))>0 ) {
		if(pv_parse_format(&hash_pvar_param, &hash_param_model) < 0
				|| hash_param_model==NULL) {
			LM_ERR("malformed PV string: %s\n", hash_pvar_param.s);
			return -1;
		}		
	} else {
		hash_param_model = NULL;
	}

	if (ds_setid_pvname.s && (ds_setid_pvname.len=strlen(ds_setid_pvname.s))>0 ) {
		if(pv_parse_spec(&ds_setid_pvname, &ds_setid_pv)==NULL
				|| !pv_is_w(&ds_setid_pv))
		{
			LM_ERR("[%s]- invalid setid_pvname\n", ds_setid_pvname.s);
			return -1;
		}
	}

	pvar_algo_param.len = strlen(pvar_algo_param.s);
	if (pvar_algo_param.len)
		ds_pvar_parse_pattern(pvar_algo_param);

	if (init_ds_bls()!=0) {
		LM_ERR("failed to init DS blacklists\n");
		return E_CFG;
	}

	if (init_ds_data()!=0) {
		LM_ERR("failed to init DS data holder\n");
		return -1;
	}

	/* open DB connection to load provisioning data */
	if (init_ds_db()!= 0) {
		LM_ERR("failed to init database support\n");
		return -1;
	}

	/* do the actula data load */
	if (ds_reload_db()!=0) {
		LM_ERR("failed to load data from DB\n");
		return -1;
	}

	/* close DB connection */
	ds_disconnect_db();

	/* Only, if the Probing-Timer is enabled the TM-API needs to be loaded: */
	if (ds_ping_interval > 0)
	{
		load_tm_f load_tm;
		str host;
		int port,proto;

		if (ds_ping_from.s)
			ds_ping_from.len = strlen(ds_ping_from.s);
		if (ds_ping_method.s)
			ds_ping_method.len = strlen(ds_ping_method.s);
		/* parse the list of reply codes to be counted as success */
		if(options_reply_codes_str.s) {
			options_reply_codes_str.len = strlen(options_reply_codes_str.s);
			if(parse_reply_codes( &options_reply_codes_str, &options_reply_codes,
			&options_codes_no )< 0) {
				LM_ERR("Bad format for options_reply_code parameter"
						" - Need a code list separated by commas\n");
				return -1;
			}
		}
		/* parse and look for the socket to ping from */
		if (probing_sock_s && probing_sock_s[0]!=0 ) {
			if (parse_phostport( probing_sock_s, strlen(probing_sock_s),
			&host.s, &host.len, &port, &proto)!=0 ) {
				LM_ERR("socket description <%s> is not valid\n",
					probing_sock_s);
				return -1;
			}
			probing_sock = grep_sock_info( &host, port, proto);
			if (probing_sock==NULL) {
				LM_ERR("socket <%s> is not local to opensips (we must listen "
					"on it\n", probing_sock_s);
				return -1;
			}
		}
		/* TM-Bindings */
		load_tm=(load_tm_f)find_export("load_tm", 0, 0);
		if (load_tm==NULL) {
			LM_ERR("failed to bind to the TM-Module - required for probing\n");
			return -1;
		}
		/* let the auto-loading function load all TM stuff */
		if (load_tm( &tmb ) == -1) {
			LM_ERR("could not load the TM-functions - disable DS ping\n");
			return -1;
		}
		/* Register the PING-Timer */
		if (register_timer("ds-pinger",ds_check_timer,NULL,ds_ping_interval)<0){
			LM_ERR("failed to register timer for probing!\n");
			return -1;
		}
	}

	/* register timer to flush the state of destination back to DB */
	if (register_timer("ds-flusher",ds_flusher_routine,NULL, 30)<0){
		LM_ERR("failed to register timer for DB flushing!\n");
		return -1;
	}

	dispatch_evi_id = evi_publish_event(dispatcher_event);
	if (dispatch_evi_id == EVI_ERROR)
		LM_ERR("cannot register dispatcher event\n");
	return 0;
}
예제 #29
0
파일: b2b_sca.c 프로젝트: OpenSIPS/opensips
/** Module init function */
static int mod_init(void)
{
	unsigned int i;

	LM_DBG("start\n");

	init_db_url( db_url , 0 /*cannot be null*/);

	/* load tm api */
	if(load_tm_api(&tmb)==-1)
	{
		LM_ERR("can't load tm functions\n");
		return -1;
	}

	/* load pua api */
	if(load_pua_api(&pua_api) < 0)
	{
		LM_ERR("Can't bind pua\n");
		return -1;
	}
	/* add event in pua module */
	if(pua_api.add_event(CALLINFO_EVENT, "call-info", NULL, 0) < 0) {
		LM_ERR("failed to add 'call-info' event to pua module\n");
		return -1;
	}

	/* load b2b_logic api */
	if(load_b2b_logic_api(&b2bl_api)< 0)
	{
		LM_ERR("Failed to load b2b_logic api\n");
		return -1;
	}

	if(b2b_sca_hsize<1 || b2b_sca_hsize>20)
	{
		LM_ERR("Wrong hash size. Needs to be greater than 1"
			" and smaller than 20. Be aware that you should set the log 2"
			" value of the real size\n");
		return -1;
	}
	b2b_sca_hsize = 1<<b2b_sca_hsize;

	if(presence_server.s)
		presence_server.len = strlen(presence_server.s);
	LM_DBG("fix db columns\n");
	sca_table_name.len = strlen(sca_table_name.s);
	shared_line_column.len = strlen(shared_line_column.s);
	watchers_column.len = strlen(watchers_column.s);
	for (i=0; i<MAX_APPEARANCE_INDEX; i++) {
		app_shared_entity_column[i].len = strlen(app_shared_entity_column[i].s);
		app_call_state_column[i].len = strlen(app_call_state_column[i].s);
		app_call_info_uri_column[i].len = strlen(app_call_info_uri_column[i].s);
		app_call_info_appearance_uri_column[i].len =
				strlen(app_call_info_appearance_uri_column[i].s);
		app_b2bl_key_column[i].len = strlen(app_b2bl_key_column[i].s);
	}

	LM_DBG("fix AVP spec\n");
	/* fix AVP spec */
	if(watchers_avp_spec.s)
	{
		watchers_avp_spec.len = strlen(watchers_avp_spec.s);
		if(pv_parse_spec(&watchers_avp_spec, &watchers_spec)==NULL ||
			watchers_spec.type != PVT_AVP)
		{
			LM_ERR("failed to parse watchers spec [%.*s]\n",
				watchers_avp_spec.len, watchers_avp_spec.s);
			return E_CFG;
		}
		if(pv_get_avp_name(NULL, &(watchers_spec.pvp), &(watchers_avp_name),
			&(watchers_avp_type) )!=0)
		{
			LM_ERR("[%.*s]- invalid AVP definition for watchers_avp_spec\n",
				watchers_avp_spec.len, watchers_avp_spec.s);
		}
	} else {
		watchers_avp_name = -1;
		watchers_avp_type = 0;
	}

	if(shared_line_spec_param.s)
	{
		shared_line_spec_param.len = strlen(shared_line_spec_param.s);
		if(pv_parse_spec(&shared_line_spec_param, &shared_line_spec)==NULL)
		{
			LM_ERR("failed to parse shared_line spec\n");
			return E_CFG;
		}
		switch(shared_line_spec.type) {
			case PVT_NONE:
			case PVT_EMPTY:
			case PVT_NULL:
			case PVT_MARKER:
			case PVT_COLOR:
				LM_ERR("invalid shared_line spec\n");
				return -3;
			default: ;
		}
	}

	if(appearance_name_addr_spec_param.s)
	{
		appearance_name_addr_spec_param.len = strlen(appearance_name_addr_spec_param.s);
		if(pv_parse_spec(&appearance_name_addr_spec_param, &appearance_name_addr_spec)==NULL)
		{
			LM_ERR("failed to parse appearance_name_addr spec\n");
			return E_CFG;
		}
		switch(appearance_name_addr_spec.type) {
			case PVT_NONE:
			case PVT_EMPTY:
			case PVT_NULL:
			case PVT_MARKER:
			case PVT_COLOR:
				LM_ERR("invalid appearance_name_addr spec\n");
				return -3;
			default: ;
		}
	}

	if(init_b2b_sca_htable() < 0) {
		LM_ERR("Failed to initialize b2b_sca hash table\n");
		return -1;
	}

	if (sca_db_mode==DB_MODE_NONE) {
		db_url.s = NULL; db_url.len = 0;
	} else {
		if (sca_db_mode!=DB_MODE_REALTIME) {
			LM_ERR("unsupported db_mode %d\n", sca_db_mode);
			return -1;
		}
		if ( !db_url.s || db_url.len==0 ) {
			LM_ERR("db_url not configured for db_mode %d\n", sca_db_mode);
			return -1;
		}
		if (init_sca_db(&db_url, b2b_sca_hsize)!=0) {
			LM_ERR("failed to initialize the DB support\n");
			return -1;
		}
	}
	return 0;
}
예제 #30
0
/*
 * Verify parameters for OSP module
 * return 0 success, -1 failure
 */
static int ospVerifyParameters(void)
{
    int i;
    pv_spec_t avp_spec;
    str avp_str;
    int result = 0;

    if ((_osp_work_mode < 0) || (_osp_work_mode > 1)) {
        _osp_work_mode = OSP_DEF_MODE;
        LM_WARN("work mode is out of range, reset to %d\n", OSP_DEF_MODE);
    }

    if ((_osp_service_type < 0) || (_osp_service_type > 1)) {
        _osp_service_type = OSP_DEF_SERVICE;
        LM_WARN("service type is out of range, reset to %d\n", OSP_DEF_SERVICE);
    }

    /* If use_security_features is 0, ignroe the certificate files */
    if (_osp_use_security != 0) {
        /* Default location for the cert files is in the compile time variable CFG_DIR */
        if (_osp_private_key == NULL) {
            sprintf(_osp_PRIVATE_KEY, "%spkey.pem", CFG_DIR);
            _osp_private_key = _osp_PRIVATE_KEY;
        }

        if (_osp_local_certificate == NULL) {
            sprintf(_osp_LOCAL_CERTIFICATE, "%slocalcert.pem", CFG_DIR);
            _osp_local_certificate = _osp_LOCAL_CERTIFICATE;
        }

        if (_osp_ca_certificate == NULL) {
            sprintf(_osp_CA_CERTIFICATE, "%scacert_0.pem", CFG_DIR);
            _osp_ca_certificate = _osp_CA_CERTIFICATE;
        }
    }

    if (_osp_device_ip != NULL) {
        ospConvertToInAddress(_osp_device_ip, _osp_in_device, sizeof(_osp_in_device));
        ospConvertToOutAddress(_osp_device_ip, _osp_out_device, sizeof(_osp_out_device));
    } else {
        _osp_in_device[0] = '\0';
        _osp_out_device[0] = '\0';
    }

    if (_osp_max_dests > OSP_MAX_DESTS || _osp_max_dests < 1) {
        _osp_max_dests = OSP_DEF_DESTS;
        LM_WARN("max_destinations is out of range, reset to %d\n", OSP_DEF_DESTS);
    }

    if (_osp_report_nid < 0 || _osp_report_nid > 3) {
        _osp_report_nid = OSP_DEF_REPORTNID;
        LM_WARN("report_networkid is out of range, reset to %d\n", OSP_DEF_REPORTNID);
    }

    if (_osp_token_format < 0 || _osp_token_format > 2) {
        _osp_token_format = OSP_DEF_TOKEN;
        LM_WARN("token_format is out of range, reset to %d\n", OSP_DEF_TOKEN);
    }

    _osp_sp_number = 0;
    for (i = 0; i < OSP_DEF_SPS; i++) {
        if (_osp_sp_uris[i] != NULL) {
            if (_osp_sp_number != i) {
                _osp_sp_uris[_osp_sp_number] = _osp_sp_uris[i];
                _osp_sp_weights[_osp_sp_number] = _osp_sp_weights[i];
                _osp_sp_uris[i] = NULL;
                _osp_sp_weights[i] = OSP_DEF_WEIGHT;
            }
            osp_index[_osp_sp_number] = i + 1;
            _osp_sp_number++;
        }
    }

    if (_osp_sp_number == 0) {
        LM_ERR("at least one service point uri must be configured\n");
        result = -1;
    }

    if ((_osp_dnid_location < 0) || (_osp_dnid_location > 3)) {
        _osp_dnid_location = OSP_DEF_DNIDLOC;
        LM_WARN("networkid_location is out of range, reset to %d\n", OSP_DEF_DNIDLOC);
    }

    if (!(_osp_dnid_param && *_osp_dnid_param)) {
        _osp_dnid_param = OSP_DEF_DNIDPARAM;
    }

    if ((_osp_work_mode == 1) && _osp_srcdev_avp && *_osp_srcdev_avp) {
        avp_str.s = _osp_srcdev_avp;
        avp_str.len = strlen(_osp_srcdev_avp);
        if ((pv_parse_spec(&avp_str, &avp_spec) == NULL) ||
            avp_spec.type != PVT_AVP ||
            pv_get_avp_name(0, &(avp_spec.pvp), &_osp_srcdev_avpid, &_osp_srcdev_avptype) != 0)
        {
            LM_WARN("'%s' invalid AVP definition\n", _osp_srcdev_avp);
            _osp_srcdev_avpid = OSP_DEF_AVP;
            _osp_srcdev_avptype = 0;
        }
    } else {
        _osp_srcdev_avpid = OSP_DEF_AVP;
        _osp_srcdev_avptype = 0;
    }

    if (_osp_snid_avp && *_osp_snid_avp) {
        avp_str.s = _osp_snid_avp;
        avp_str.len = strlen(_osp_snid_avp);
        if (pv_parse_spec(&avp_str, &avp_spec) == NULL ||
            avp_spec.type != PVT_AVP ||
            pv_get_avp_name(0, &(avp_spec.pvp), &_osp_snid_avpid, &_osp_snid_avptype) != 0)
        {
            LM_WARN("'%s' invalid AVP definition\n", _osp_snid_avp);
            _osp_snid_avpid = OSP_DEF_AVP;
            _osp_snid_avptype = 0;
        }
    } else {
        _osp_snid_avpid = OSP_DEF_AVP;
        _osp_snid_avptype = 0;
    }

    if (_osp_cinfo_avp && *_osp_cinfo_avp) {
        avp_str.s = _osp_cinfo_avp;
        avp_str.len = strlen(_osp_cinfo_avp);
        if (pv_parse_spec(&avp_str, &avp_spec) == NULL ||
            avp_spec.type != PVT_AVP ||
            pv_get_avp_name(0, &(avp_spec.pvp), &_osp_cinfo_avpid, &_osp_cinfo_avptype) != 0)
        {
            LM_WARN("'%s' invalid AVP definition\n", _osp_cinfo_avp);
            _osp_cinfo_avpid = OSP_DEF_AVP;
            _osp_cinfo_avptype = 0;
        }
    } else {
        _osp_cinfo_avpid = OSP_DEF_AVP;
        _osp_cinfo_avptype = 0;
    }

    ospDumpParameters();

    return result;
}