Exemplo n.º 1
0
static int w_ds_select_domain_limited(struct sip_msg* msg, char* set, char* alg, char* max_results)
{
	int a, s, m;
	if(msg==NULL)
		return -1;

	if(fixup_get_ivalue(msg, (gparam_p)set, &s)!=0)
	{
		LM_ERR("no dst set value\n");
		return -1;
	}
	if(fixup_get_ivalue(msg, (gparam_p)alg, &a)!=0)
	{
		LM_ERR("no alg value\n");
		return -1;
	}
	if(fixup_get_ivalue(msg, (gparam_p)max_results, &m)!=0)
	{
		LM_ERR("no max results value\n");
		return -1;
	}

	return ds_select_dst(msg, s, a, 1/*set host port*/, m);
}
Exemplo n.º 2
0
static int w_ds_select(struct sip_msg* msg, char* part_set, char* alg,
											char* max_results_flags, int mode)
{
	int ret = -1;
	int _ret;
	int run_prev_ds_select = 0;
	ds_select_ctl_t prev_ds_select_ctl, ds_select_ctl;
	char selected_dst_sock_buf[PTR_STRING_SIZE]; /* a hexa string */
	ds_selected_dst selected_dst;
	struct socket_info *sock = NULL;

	if(msg==NULL)
		return -1;

	ds_select_ctl.mode = mode;
	ds_select_ctl.max_results = 1000;
	ds_select_ctl.reset_AVP = 1;
	ds_select_ctl.set_destination = 1;
	ds_select_ctl.ds_flags = 0;

	memset(&selected_dst, 0, sizeof(ds_selected_dst));
	selected_dst.socket.s = selected_dst_sock_buf;

	/* Retrieve dispatcher set */
	ds_param_t *part_set_param = (ds_param_t*)part_set;

	if (fixup_get_partition(msg, &part_set_param->partition,
			&ds_select_ctl.partition) != 0 ||ds_select_ctl.partition == NULL) {
		LM_ERR("unknown partition\n");
		return -1;
	}

	int_list_t *set_list = part_set_param->sets;
	int_list_t *set_list_exp_start = NULL, *set_list_exp_end = NULL;

	/* Retrieve dispatcher algorithm */
	int_list_t *alg_list = (int_list_t *)alg;
	int_list_t *alg_list_exp_start = NULL, *alg_list_exp_end = NULL;

	/* In case this parameter is not specified */
	max_list_param_p max_param = (max_list_param_p)max_results_flags;
	str max_list_str;

	int_list_t *max_list=NULL, *max_list_free;
	if (max_param && max_param->type == MAX_LIST_TYPE_STR) {
		max_list = (int_list_t*)max_param->lst.list;
	} else if (max_param && max_param->type == MAX_LIST_TYPE_PV) {
		if (pv_printf_s(msg, max_param->lst.elem, &max_list_str) != 0) {
			LM_ERR("cannot get max list from pv\n");
			return -1;
		}

		if (set_list_from_string(max_list_str, &max_list) != 0
				|| max_list == NULL)
			return -1;
	}

	/* Avoid compiler warning */
	memset(&prev_ds_select_ctl, 0, sizeof(ds_select_ctl_t));

	ds_select_ctl.set_destination = 0;

	/* Parse the params in reverse order.
	 * We need to runt the first entry last to properly populate ds_select_dst
	 *  AVPs.
	 * On the first ds_select_dst run we need to reset AVPs.
	 * On the last ds_select_dst run we need to set destination.  */
	do {
		CHECK_AND_EXPAND_LIST(set_list);
		ds_select_ctl.set = set_list->v.ival;

		CHECK_AND_EXPAND_LIST(alg_list);
		ds_select_ctl.alg = alg_list->v.ival;

		if (max_results_flags) {
			ds_select_ctl.max_results = max_list->v.ival;
			ds_select_ctl.ds_flags    = max_list->flags;
		}

		if (run_prev_ds_select) {
			LM_DBG("ds_select: %d %d %d %d %d\n",
				prev_ds_select_ctl.set, prev_ds_select_ctl.alg,
				prev_ds_select_ctl.max_results,
				prev_ds_select_ctl.reset_AVP,
				prev_ds_select_ctl.set_destination);
			_ret = ds_select_dst(msg, &prev_ds_select_ctl, &selected_dst,
				prev_ds_select_ctl.ds_flags);
			if (_ret>=0) ret = _ret;
			/* stop resetting AVPs. */
			ds_select_ctl.reset_AVP = 0;
		} else {
			/* Enable running ds_select_dst on next loop. */
			run_prev_ds_select = 1;
		}
		prev_ds_select_ctl = ds_select_ctl;

		set_list = set_list->next;
		alg_list = alg_list->next;
		if (max_results_flags) {
			max_list_free = max_list;
			max_list = max_list->next;

			if (max_param->type == MAX_LIST_TYPE_PV)
				pkg_free(max_list_free);
		}

		TRY_FREE_EXPANDED_LIST(set_list);
		TRY_FREE_EXPANDED_LIST(alg_list);

	} while (set_list && alg_list &&
			(max_results_flags ? max_list : set_list));

	if (max_results_flags &&  max_list != NULL) {
		LM_ERR("extra max slot(s) and/or flag(s)\n");
		ret = -2;
		goto error;
	}

	if (set_list != NULL) {
		LM_ERR("extra set(s)\n");
		ret = -2;
		goto error;
	}

	if (alg_list != NULL) {
		LM_ERR("extra algorithm(s)\n");
		ret = -2;
		goto error;
	}

	/* last ds_select_dst run: setting destination. */
	ds_select_ctl.set_destination = 1;
	LM_DBG("ds_select: %d %d %d %d %d\n",
		ds_select_ctl.set, ds_select_ctl.alg, ds_select_ctl.max_results,
		ds_select_ctl.reset_AVP, ds_select_ctl.set_destination);
	_ret = ds_select_dst(msg, &ds_select_ctl, &selected_dst,
		ds_select_ctl.ds_flags);
	if (_ret>=0) {
		ret = _ret;
	}
	else {
		if (selected_dst.uri.s != NULL) {
			if (selected_dst.socket.len != 0) {
				if (sscanf( selected_dst.socket.s, "%p", (void**)&sock ) != 1){
					LM_ERR("unable to read forced destination socket\n");
					ret = -4;
					goto error;
				}
			}
			if (ds_update_dst(msg, &selected_dst.uri, sock, ds_select_ctl.mode)
			!= 0) {
				LM_ERR("cannot set dst addr\n");
				ret = -3;
				goto error;
			}
		}
		else {
			ret = -1;
			goto error;
		}
	}

error:
	if (selected_dst.uri.s != NULL) pkg_free(selected_dst.uri.s);
	return ret;
}
Exemplo n.º 3
0
static int w_ds_select(struct sip_msg* msg, char* set, char* alg, char* max_results, int mode)
{
	unsigned int algo_flags, set_flags, max_flags;
	str s_algo = {NULL, 0};
	str s_set = {NULL, 0};
	str s_max = {NULL, 0};
	str _param;
	char *p;
	int ret;
	int run_prev_ds_select = 0;
	ds_select_ctl_t prev_ds_select_ctl, ds_select_ctl;

	if(msg==NULL)
		return -1;

	ds_select_ctl.mode = mode;
	ds_select_ctl.max_results = 1000;
	ds_select_ctl.reset_AVP = 1;
	ds_select_ctl.set_destination = 1;

	/* Retrieve dispatcher set */
	GET_VALUE("destination set", set, ds_select_ctl.set, s_set, set_flags);

	/* Retrieve dispatcher algorithm */
	GET_VALUE("algorithm", alg, ds_select_ctl.alg, s_algo, algo_flags);

	/* Retrieve dispatcher max results */
	if (max_results) {
		GET_VALUE("max results", max_results, ds_select_ctl.max_results, s_max, max_flags);
		if( !( (set_flags  & GPARAM_INT_VALUE_FLAG)
			&& (algo_flags & GPARAM_INT_VALUE_FLAG)
			&& (max_flags  & GPARAM_INT_VALUE_FLAG) ) ) {
			goto handle_str_params;
		}
	} else {
		if( !( (set_flags  & GPARAM_INT_VALUE_FLAG)
			&& (algo_flags & GPARAM_INT_VALUE_FLAG) ) ) {
			goto handle_str_params;
		}
	}

	return ds_select_dst(msg, &ds_select_ctl);

handle_str_params:
	if (max_results) {
		if(  ( (set_flags  & GPARAM_INT_VALUE_FLAG)
			|| (algo_flags & GPARAM_INT_VALUE_FLAG)
			|| (max_flags  & GPARAM_INT_VALUE_FLAG) ) ) {
			LM_ERR("Mixed param types: set_flags=[%u] algo_flags=[%u] max_flags=[%u]\n",
				set_flags, algo_flags, max_flags);
			return -1;
		}
		if( !( (set_flags  & GPARAM_STR_VALUE_FLAG)
			&& (algo_flags & GPARAM_STR_VALUE_FLAG)
			&& (max_flags  & GPARAM_STR_VALUE_FLAG) ) ) {
			LM_ERR("Not all params are strings: set_flags=[%u] algo_flags=[%u] max_flags=[%u]\n",
				set_flags, algo_flags, max_flags);
			return -1;
		}
	} else {
		if(  ( (set_flags  & GPARAM_INT_VALUE_FLAG)
			|| (algo_flags & GPARAM_INT_VALUE_FLAG) ) ) {
			LM_ERR("Mixed param types: set_flags=[%u] algo_flags=[%u]\n",
				set_flags, algo_flags);
			return -1;
		}
		if( !( (set_flags  & GPARAM_STR_VALUE_FLAG)
			&& (algo_flags & GPARAM_STR_VALUE_FLAG) ) ) {
			LM_ERR("Not all params are strings: set_flags=[%u] algo_flags=[%u]\n",
				set_flags, algo_flags);
			return -1;
		}
	}

	CHECK_INVALID_PARAM(s_set);
	CHECK_INVALID_PARAM(s_algo);
	if (max_results) CHECK_INVALID_PARAM(s_max);

	/* Avoid compiler warning */
	memset(&prev_ds_select_ctl, 0, sizeof(ds_select_ctl_t));

	ds_select_ctl.set_destination = 0;

	/* Parse the params in reverse order.
	 * We need to runt the first entry last to properly populate ds_select_dst AVPs.
	 * On the first ds_select_dst run we need to reset AVPs.
	 * On the last ds_select_dst run we need to set destination.  */
	do {
		PARSE_PARAM("set", s_set,  ds_select_ctl.set);
		PARSE_PARAM("alg", s_algo, ds_select_ctl.alg);
		if (max_results) PARSE_PARAM("max", s_max, ds_select_ctl.max_results);

		if (run_prev_ds_select) {
			LM_DBG("ds_select: %d %d %d %d %d\n",
				prev_ds_select_ctl.set, prev_ds_select_ctl.alg, prev_ds_select_ctl.max_results,
				prev_ds_select_ctl.reset_AVP, prev_ds_select_ctl.set_destination);
			ret = ds_select_dst(msg, &prev_ds_select_ctl);
			if (ret<0) return ret;
			/* stop resetting AVPs. */
			ds_select_ctl.reset_AVP = 0;
		} else {
			/* Enable running ds_select_dst on next loop. */
			run_prev_ds_select = 1;
		}
		prev_ds_select_ctl = ds_select_ctl;
	} while (s_set.len>0 || s_algo.len>0);

	if (max_results && s_max.len>0) {
		LM_ERR("extra max slot(s) [%.*s]\n", s_max.len,s_max.s);
		goto error;
	}

	/* las ds_select_dst run: setting destination. */
	ds_select_ctl.set_destination = 1;
	LM_DBG("ds_select: %d %d %d %d %d\n",
		ds_select_ctl.set, ds_select_ctl.alg, ds_select_ctl.max_results,
		ds_select_ctl.reset_AVP, ds_select_ctl.set_destination);
	return ds_select_dst(msg, &ds_select_ctl);

error:
	return -1;
}