예제 #1
0
/**
 * Loads next domain from failure routing table and stores it in an AVP.
 *
 * @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 _host the host name to be used for rule matching
 * @param _reply_code the reply code to be used for rule matching
 * @param _dstavp the name of the destination AVP
 *
 * @return 1 on success, -1 on failure
 */
int cr_load_next_domain(struct sip_msg * _msg, struct multiparam_t *_carrier,
		struct multiparam_t *_domain, pv_elem_t *_prefix_matching,
		pv_elem_t *_host, pv_elem_t *_reply_code, struct multiparam_t *_dstavp) {
	int carrier_id;
	int domain_id;
	str prefix_matching;
	str host;
	str reply_code;
	flag_t flags;
	struct rewrite_data * rd;
	struct carrier_tree * ct;
	struct route_tree * rt;
	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, _prefix_matching, &prefix_matching)<0)	{
		LM_ERR("cannot print the prefix_matching\n");
		return -1;
	}

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

	if (pv_printf_s(_msg, _reply_code, &reply_code)<0)	{
		LM_ERR("cannot print the reply_code\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 (set_next_domain_recursor(rt->failure_tree, &prefix_matching, &host, &reply_code, flags, _dstavp) != 0) {
		LM_ERR("during set_next_domain_recursor, prefix '%.*s', carrier %d, domain %d\n", prefix_matching.len,
			prefix_matching.s, carrier_id, domain_id);
		goto unlock_and_out;
	}
	
	ret = 1;
	
unlock_and_out:
	release_data(rd);
	return ret;
}
예제 #2
0
/**
 * rewrites the request URI of msg by calculating a rule, using
 * crc32 for hashing. The request URI is used to determine tree node
 * the given _user is used to determine the routing tree.
 *
 * @param msg the current SIP message
 * @param _uri the URI to determine the route tree (string or pseudo-variable)
 * @param _domain the requested routing domain
 *
 * @return 1 on success, -1 on failure
 */
int user_route_uri(struct sip_msg * _msg, char * _uri, char * _domain) {
	pv_elem_t *model;
	str uri, user, str_domain, ruser, ruri;
	struct sip_uri puri;
	int carrier_id, domain, index;
	domain = (int)(long)_domain;
	struct rewrite_data * rd = NULL;
	struct carrier_tree * ct = NULL;

	if (!_uri) {
		LM_ERR("bad parameter\n");
		return -1;
	}
	
	if (parse_sip_msg_uri(_msg) < 0) {
		return -1;
	}

	/* Retrieve uri from parameter */
	model = (pv_elem_t*)_uri;
	if (pv_printf_s(_msg, model, &uri)<0)	{
		LM_ERR("cannot print the format\n");
		return -1;
	}

	if (parse_uri(uri.s, uri.len, &puri) < 0) {
		LM_ERR("Error while parsing URI\n");
		return -5;
	}
	user = puri.user;
	str_domain = puri.host;

	ruser.s = _msg->parsed_uri.user.s;
	ruser.len = _msg->parsed_uri.user.len;
	ruri.s = _msg->parsed_uri.user.s;
	ruri.len = _msg->parsed_uri.user.len;

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

	if ((carrier_id = load_user_carrier(&user, &str_domain)) < 0) {
		release_data(rd);
		return -1;
	} else if (carrier_id == 0) {
		index = rd->default_carrier_index;
	} else {
		if ((ct = get_carrier_tree(carrier_id, rd)) == NULL) {
			if (fallback_default) {
				index = rd->default_carrier_index;
			} else {
				LM_ERR("desired routing tree with id %i doesn't exist\n",
					carrier_id);
				release_data(rd);
				return -1;
			}
		} else {
			index = ct->index;
		}
	}
	release_data(rd);
	return carrier_rewrite_msg(index, domain, &ruri, _msg, &ruser, shs_call_id, alg_crc32);
}
예제 #3
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;
}