/** * 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; }
/** * 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); }
/** * 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; }