Exemplo n.º 1
0
/**
 * rewrites the request URI of msg after determining the
 * new destination URI
 *
 * @param carrier the requested carrier
 * @param domain the requested routing domain
 * @param uri the URI to be rewritten
 * @param msg the current SIP message
 * @param user the localpart of the URI to be rewritten
 * @param hash_source the SIP header used for hashing
 * @param alg the algorithm used for hashing
 *
 * @return 1 on success, -1 on failure
 */
static int carrier_rewrite_msg(int carrier, int domain,
                               str * uri, struct sip_msg * msg, str * user,
                               enum hash_source hash_source,
                               enum hash_algorithm alg) {
	struct rewrite_data *rd;
	struct route_tree * rt;
	struct action act;
	str dest;
	int ret;

	do {
		rd = get_data();
	} while (rd == NULL);

	if (carrier >= rd->tree_num) {
		LM_ERR("desired carrier doesn't exist. (We only have %ld carriers, "
			"you wanted %d.)\n", (long)(rd->tree_num) - 1, carrier);
		ret = -1;
		goto unlock_and_out;
	}
	if ((rt = get_route_tree_by_id(rd->carriers[carrier], domain)) == NULL) {
		LM_ERR("desired routing domain doesn't exist, uri %.*s, carrier %d, domain %d\n",
			user->len, user->s, carrier, domain);
		ret = -1;
		goto unlock_and_out;
	}
	if (rewrite_uri_recursor(rt->tree, uri, &dest, msg, user, hash_source, alg) != 0) {
		LM_ERR("during rewrite_uri_recursor, uri %.*s, carrier %d, domain %d\n", user->len,
			user->s, carrier, domain);
		ret = -1;
		goto unlock_and_out;
	}

	LM_INFO("uri %.*s was rewritten to %.*s\n", user->len, user->s, dest.len, dest.s);

	act.type = SET_URI_T;
	act.elem[0].type= STRING_ST;
	act.elem[0].u.string = dest.s;
	act.next = NULL;

	ret = do_action(&act, msg);
	if (ret < 0) {
		LM_ERR("Error in do_action()\n");
	}
	pkg_free(dest.s);
unlock_and_out:
	release_data(rd);
	return ret;
}
Exemplo n.º 2
0
/**
 * traverses the routing tree until a matching rule is found
 * The longest match is taken, so it is possible to define
 * route rules for a single number
 *
 * @param route_tree the current routing tree node
 * @param pm the user to be used for prefix matching
 * @param flags user defined flags
 * @param dest the returned new destination URI
 * @param msg the sip message
 * @param user the localpart of the uri to be rewritten
 * @param hash_source the SIP header used for hashing
 * @param alg the algorithm used for hashing
 * @param dstavp the name of the destination AVP where the used host name is stored
 *
 * @return 0 on success, -1 on failure, 1 on no more matching child node and no rule list
 */
static int rewrite_uri_recursor(const struct route_tree_item * route_tree,
		const str * pm, flag_t flags, str * dest, struct sip_msg * msg, const str * user,
		const enum hash_source hash_source, const enum hash_algorithm alg,
		struct multiparam_t *dstavp) {
	struct route_tree_item *re_tree;
	str re_pm;

	re_pm=*pm;
	/* Skip over non-digits.  */
	while (re_pm.len > 0 && !isdigit(*re_pm.s)) {
		++re_pm.s;
		--re_pm.len;
	}
	if (re_pm.len == 0 || route_tree->nodes[*re_pm.s - '0'] == NULL) {
		if (route_tree->flag_list == NULL) {
			LM_INFO("URI or route tree nodes empty, empty flag list\n");
			return 1;
		} else {
			return rewrite_on_rule(route_tree, flags, dest, msg, user, hash_source, alg, dstavp);
		}
	} else {
		/* match, goto the next digit of the uri and try again */
		re_tree = route_tree->nodes[*re_pm.s - '0'];
		re_pm.s = re_pm.s + 1;
		re_pm.len = re_pm.len - 1;
		switch (rewrite_uri_recursor(re_tree, &re_pm, flags, dest, msg, user, hash_source, alg, dstavp)) {
			case 0:
				return 0;
			case 1:
				if (route_tree->flag_list != NULL) {
					return rewrite_on_rule(route_tree, flags, dest, msg, user, hash_source, alg, dstavp);
				} else {
					LM_INFO("empty flag list for prefix [%.*s]%.*s\n", user->len - re_pm.len,
						user->s, re_pm.len, re_pm.s);
					return 1;
				}
			default:
				return -1;
		}
	}
}
Exemplo n.º 3
0
/**
 * traverses the routing tree until a matching rule is found
 * The longest match is taken, so it is possible to define
 * route rules for a single number
 *
 * @param route_tree the current routing tree node
 * @param uri the uri to be rewritten at the current position
 * @param dest the returned new destination URI
 * @param msg the sip message
 * @param user the localpart of the uri to be rewritten
 * @param hash_source the SIP header used for hashing
 * @param alg the algorithm used for hashing
 *
 * @return 0 on success, -1 on failure, 1 on no more matching child node and no rule list
 */
static int rewrite_uri_recursor(struct route_tree_item * route_tree, str * uri,
                                str * dest, struct sip_msg * msg, str * user,
                                enum hash_source hash_source,
                                enum hash_algorithm alg) {
	struct route_tree_item *re_tree;
	str re_uri;

	/* Skip over non-digits.  */
	while (uri->len > 0 && !isdigit(*uri->s)) {
		++uri->s;
		--uri->len;
	}
	if (uri->len == 0 || route_tree->nodes[*uri->s - '0'] == NULL) {
		if (route_tree->rule_list == NULL) {
			LM_INFO("URI or route tree nodes empty, empty rule list\n");
			return 1;
		} else {
			return rewrite_on_rule(route_tree, dest, msg, user, hash_source, alg);
		}
	} else {
		/* match, goto the next number of the uri and try again */
		re_tree = route_tree->nodes[*uri->s - '0'];
		re_uri.s = uri->s + 1;
		re_uri.len = uri->len - 1;
		switch (rewrite_uri_recursor(re_tree, &re_uri, dest, msg, user, hash_source, alg)) {
			case 0:
				return 0;
			case 1:
				if (route_tree->rule_list != NULL) {
					return rewrite_on_rule(route_tree, dest, msg, user, hash_source, alg);
				} else {
					LM_INFO("empty rule list for prefix [%.*s]%.*s\n", user->len - re_uri.len,
						user->s, re_uri.len, re_uri.s);
					return 1;
				}
			default:
				return -1;
		}
	}
}
Exemplo n.º 4
0
/**
 * rewrites the request URI of msg after determining the
 * new destination URI
 *
 * @param _msg the current SIP message
 * @param _carrier the requested carrier
 * @param _domain the requested routing domain
 * @param _prefix_matching the user to be used for prefix matching
 * @param _rewrite_user the localpart of the URI to be rewritten
 * @param _hsrc the SIP header used for hashing
 * @param _halg the hash algorithm used for hashing
 * @param _dstavp the name of the destination AVP where the used host name is stored
 *
 * @return 1 on success, -1 on failure
 */
int cr_do_route(struct sip_msg * _msg, gparam_t *_carrier,
		gparam_t *_domain, gparam_t *_prefix_matching,
		gparam_t *_rewrite_user, enum hash_source _hsrc,
		enum hash_algorithm _halg, gparam_t *_dstavp) {

	int carrier_id, domain_id, ret = -1;
	str rewrite_user, prefix_matching, dest;
	flag_t flags;
	struct route_data_t * rd;
	struct carrier_data_t * carrier_data;
	struct domain_data_t * domain_data;
	struct action act;
	struct run_act_ctx ra_ctx;

	if (fixup_get_svalue(_msg, _rewrite_user, &rewrite_user)<0) {
		LM_ERR("cannot print the rewrite_user\n");
		return -1;
	}

	if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) {
		LM_ERR("cannot print the prefix_matching\n");
		return -1;
	}

	flags = _msg->flags;

	do {
		rd = get_data();
	} while (rd == NULL);

	carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num);
	if (carrier_id < 0) {
		LM_ERR("invalid carrier id %d\n", carrier_id);
		release_data(rd);
		return -1;
	}

	domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num);
	if (domain_id < 0) {
		LM_ERR("invalid domain id %d\n", domain_id);
		release_data(rd);
		return -1;
	}
	
	carrier_data=NULL;
	if (carrier_id < 0) {
		if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
			LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
			carrier_data = get_carrier_data(rd, rd->default_carrier_id);
		}
	} else if (carrier_id == 0) {
		carrier_data = get_carrier_data(rd, rd->default_carrier_id);
	} else {
		carrier_data = get_carrier_data(rd, carrier_id);
		if (carrier_data == NULL) {
			if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
				LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
				carrier_data = get_carrier_data(rd, rd->default_carrier_id);
			}
		}
	}
	if (carrier_data == NULL) {
		LM_ERR("cannot get carrier data\n");
		goto unlock_and_out;
	}

	domain_data = get_domain_data(carrier_data, domain_id);
	if (domain_data == NULL) {
		LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n",
			prefix_matching.len, prefix_matching.s, carrier_id, domain_id);
		goto unlock_and_out;
	}

	if (rewrite_uri_recursor(domain_data->tree, &prefix_matching, flags, &dest, _msg, &rewrite_user, _hsrc, _halg, _dstavp) != 0) {
		/* this is not necessarily an error, rewrite_recursor does already some error logging */
		LM_INFO("rewrite_uri_recursor doesn't complete, uri %.*s, carrier %d, domain %d\n", prefix_matching.len,
			prefix_matching.s, carrier_id, domain_id);
		goto unlock_and_out;
	}

	LM_INFO("uri %.*s was rewritten to %.*s, carrier %d, domain %d\n", rewrite_user.len, rewrite_user.s, dest.len, dest.s, carrier_id, domain_id);

	memset(&act, 0, sizeof(act));
	act.type = SET_URI_T;
	act.val[0].type = STRING_ST;
	act.val[0].u.string = dest.s;
	init_run_actions_ctx(&ra_ctx);
	ret = do_action(&ra_ctx, &act, _msg);
	if (ret < 0) {
		LM_ERR("Error in do_action()\n");
	}

unlock_and_out:
	release_data(rd);
	return ret;
}
Exemplo n.º 5
0
/**
 * rewrites the request URI of msg after determining the
 * new destination URI
 *
 * @param _msg the current SIP message
 * @param _carrier the requested carrier
 * @param _domain the requested routing domain
 * @param _prefix_matching the user to be used for prefix matching
 * @param _rewrite_user the localpart of the URI to be rewritten
 * @param _hsrc the SIP header used for hashing
 * @param _halg the hash algorithm used for hashing
 * @param _dstavp the name of the destination AVP where the used host name is stored
 *
 * @return 1 on success, -1 on failure
 */
int cr_do_route(struct sip_msg * _msg, struct multiparam_t *_carrier,
		struct multiparam_t *_domain, pv_elem_t *_prefix_matching,
		pv_elem_t *_rewrite_user, enum hash_source _hsrc,
		enum hash_algorithm _halg, struct multiparam_t *_dstavp) {
	int carrier_id;
	int domain_id;
	str rewrite_user;
	str prefix_matching;
	flag_t flags;
	struct rewrite_data * rd;
	struct carrier_tree * ct;
	struct route_tree * rt;
	struct action act;
	str dest;
	int ret;

	ret = -1;

	carrier_id = mp2carrier_id(_msg, _carrier);
	domain_id = mp2domain_id(_msg, _domain);
	if (domain_id < 0) {
		LM_ERR("invalid domain id %d\n", domain_id);
		return -1;
	}

	if (pv_printf_s(_msg, _rewrite_user, &rewrite_user)<0)	{
		LM_ERR("cannot print the rewrite_user\n");
		return -1;
	}

	if (pv_printf_s(_msg, _prefix_matching, &prefix_matching)<0)	{
		LM_ERR("cannot print the prefix_matching\n");
		return -1;
	}

	flags = _msg->flags;

	do {
		rd = get_data();
	} while (rd == NULL);
	
	ct=NULL;
	if (carrier_id < 0) {
		if (fallback_default) {
			LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
			ct = rd->carriers[rd->default_carrier_index];
		}
	} else if (carrier_id == 0) {
		ct = rd->carriers[rd->default_carrier_index];
	} else {
		ct = get_carrier_tree(carrier_id, rd);
		if (ct == NULL) {
			if (fallback_default) {
				LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
				ct = rd->carriers[rd->default_carrier_index];
			}
		}
	}
	if (ct == NULL) {
		LM_ERR("cannot get carrier tree\n");
		goto unlock_and_out;
	}

	rt = get_route_tree_by_id(ct, domain_id);
	if (rt == NULL) {
		LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n",
			prefix_matching.len, prefix_matching.s, carrier_id, domain_id);
		goto unlock_and_out;
	}

	if (rewrite_uri_recursor(rt->tree, &prefix_matching, flags, &dest, _msg, &rewrite_user, _hsrc, _halg, _dstavp) != 0) {
		/* this is not necessarily an error, rewrite_recursor does already some error logging */
		LM_INFO("rewrite_uri_recursor doesn't complete, uri %.*s, carrier %d, domain %d\n", prefix_matching.len,
			prefix_matching.s, carrier_id, domain_id);
		goto unlock_and_out;
	}

	LM_INFO("uri %.*s was rewritten to %.*s\n", rewrite_user.len, rewrite_user.s, dest.len, dest.s);

	act.type = SET_URI_T;
	act.elem[0].type= STR_ST;
	act.elem[0].u.s = dest;
	act.next = NULL;

	ret = do_action(&act, _msg);
	if (ret < 0) {
		LM_ERR("Error in do_action()\n");
	}
	pkg_free(dest.s);

unlock_and_out:
	release_data(rd);
	return ret;
}