/** * 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; } } }
/** * 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; } } }
/** * 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 node 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 descavp the name of the AVP where the description 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(struct dtrie_node_t * node, 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, gparam_t *descavp) { str re_pm = *pm; void **ret; /* Skip over non-digits. */ while (re_pm.len > 0 && (!isdigit(*re_pm.s) && cr_match_mode == 10)) { ++re_pm.s; --re_pm.len; } ret = dtrie_longest_match(node, re_pm.s, re_pm.len, NULL, cr_match_mode); if (ret == NULL) { LM_INFO("URI or prefix tree nodes empty, empty rule list\n"); return 1; } else return rewrite_on_rule(*ret, flags, dest, msg, user, hash_source, alg, descavp); }