From f09551a9a806d404e77bff4710c2410a1d9887ee Mon Sep 17 00:00:00 2001 From: lucian balanceanu Date: Thu, 16 Apr 2015 11:16:06 +0300 Subject: [PATCH] cr: add param to avoid failed dests - adding config param avoid_failed_destinations to toggle on/off the avoidance of already failed destinations in cr_route --- modules/carrierroute/carrierroute.c | 30 ++++---- modules/carrierroute/carrierroute.h | 1 + modules/carrierroute/cr_func.c | 72 ++++++++++--------- .../carrierroute/doc/carrierroute_admin.xml | 26 ++++++- 4 files changed, 81 insertions(+), 48 deletions(-) diff --git a/modules/carrierroute/carrierroute.c b/modules/carrierroute/carrierroute.c index 01ce7346870..a9cc847ee9b 100644 --- a/modules/carrierroute/carrierroute.c +++ b/modules/carrierroute/carrierroute.c @@ -78,7 +78,7 @@ const str CR_EMPTY_PREFIX = str_init("null"); int mode = 0; int cr_match_mode = 10; - +int cr_avoid_failed_dests = 1; /************* Declaration of Interface Functions **************************/ static int mod_init(void); @@ -108,17 +108,18 @@ static param_export_t params[]= { carrierfailureroute_DB_COLS carrier_name_DB_COLS domain_name_DB_COLS - {"subscriber_table", PARAM_STR, &subscriber_table }, - {"subscriber_user_col", PARAM_STR, &subscriber_username_col }, - {"subscriber_domain_col", PARAM_STR, &subscriber_domain_col }, - {"subscriber_carrier_col", PARAM_STR, &cr_preferred_carrier_col }, - {"config_source", PARAM_STRING, &config_source }, - {"default_tree", PARAM_STR, &default_tree }, - {"config_file", PARAM_STRING, &config_file }, - {"use_domain", INT_PARAM, &default_carrierroute_cfg.use_domain }, - {"fallback_default", INT_PARAM, &default_carrierroute_cfg.fallback_default }, - {"fetch_rows", INT_PARAM, &default_carrierroute_cfg.fetch_rows }, - {"match_mode", INT_PARAM, &cr_match_mode }, + {"subscriber_table", PARAM_STR, &subscriber_table }, + {"subscriber_user_col", PARAM_STR, &subscriber_username_col }, + {"subscriber_domain_col", PARAM_STR, &subscriber_domain_col }, + {"subscriber_carrier_col", PARAM_STR, &cr_preferred_carrier_col }, + {"config_source", PARAM_STRING, &config_source }, + {"default_tree", PARAM_STR, &default_tree }, + {"config_file", PARAM_STRING, &config_file }, + {"use_domain", INT_PARAM, &default_carrierroute_cfg.use_domain }, + {"fallback_default", INT_PARAM, &default_carrierroute_cfg.fallback_default }, + {"fetch_rows", INT_PARAM, &default_carrierroute_cfg.fetch_rows }, + {"match_mode", INT_PARAM, &cr_match_mode }, + {"avoid_failed_destinations", INT_PARAM, &cr_avoid_failed_dests }, {0,0,0} }; @@ -180,6 +181,11 @@ static int mod_init(void) { return -1; } + if (cr_avoid_failed_dests != 0 && cr_avoid_failed_dests != 1) { + LM_ERR("avoid_failed_dests must be 0 or 1"); + return -1; + } + if (strcmp(config_source, "db") == 0) { mode = CARRIERROUTE_MODE_DB; diff --git a/modules/carrierroute/carrierroute.h b/modules/carrierroute/carrierroute.h index bbcda9500a6..83e6da1275d 100644 --- a/modules/carrierroute/carrierroute.h +++ b/modules/carrierroute/carrierroute.h @@ -53,6 +53,7 @@ extern const str CR_EMPTY_PREFIX; extern int mode; extern int cr_match_mode; +extern int cr_avoid_failed_dests; extern int_str cr_uris_avp; diff --git a/modules/carrierroute/cr_func.c b/modules/carrierroute/cr_func.c index 70afe62df81..6d026c48fd1 100644 --- a/modules/carrierroute/cr_func.c +++ b/modules/carrierroute/cr_func.c @@ -494,29 +494,30 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest rr->next!= NULL && rr->dice_to <= prob ; rr = rr->next) {} //LM_DBG("CR: candidate hashed destination is: <%.*s>\n", rr->host.len, rr->host.s); - - if (is_route_type(FAILURE_ROUTE) && (mode == CARRIERROUTE_MODE_DB) ){ - build_used_uris_list(used_dests, &no_dests); - - if (cr_uri_already_used(rr->host, used_dests, no_dests) ) { - //LM_DBG("CR: selecting new destination !!! \n"); - for (rr = rf->rule_list; - rr!= NULL && cr_uri_already_used(rr->host, used_dests, no_dests); rr = rr->next) {} - /* are there any destinations that were not already used? */ - if (rr == NULL) { - LM_NOTICE("All gateways from this group were already used\n"); - return -1; + if (cr_avoid_failed_dests) { + if (is_route_type(FAILURE_ROUTE) && (mode == CARRIERROUTE_MODE_DB) ){ + build_used_uris_list(used_dests, &no_dests); + + if (cr_uri_already_used(rr->host, used_dests, no_dests) ) { + //LM_DBG("CR: selecting new destination !!! \n"); + for (rr = rf->rule_list; + rr!= NULL && cr_uri_already_used(rr->host, used_dests, no_dests); rr = rr->next) {} + /* are there any destinations that were not already used? */ + if (rr == NULL) { + LM_NOTICE("All gateways from this group were already used\n"); + return -1; + } + + /* this is a hack: we do not take probabilities into consideration if first destination + * was previously tried */ + + do { + int rule_no = rand() % rf->rule_num; + //LM_DBG("CR: trying rule_no=%d \n", rule_no); + for (rr = rf->rule_list; (rule_no > 0) && (rr->next!=NULL) ; rule_no-- , rr = rr->next) {} + } while (cr_uri_already_used(rr->host, used_dests, no_dests)); + LM_DBG("CR: candidate selected destination is: <%.*s>\n", rr->host.len, rr->host.s); } - - /* this is a hack: we do not take probabilities into consideration if first destination - * was previously tried */ - - do { - int rule_no = rand() % rf->rule_num; - //LM_DBG("CR: trying rule_no=%d \n", rule_no); - for (rr = rf->rule_list; (rule_no > 0) && (rr->next!=NULL) ; rule_no-- , rr = rr->next) {} - } while (cr_uri_already_used(rr->host, used_dests, no_dests)); - LM_DBG("CR: candidate selected destination is: <%.*s>\n", rr->host.len, rr->host.s); } } /*This should be regarded as an ELSE branch for the if above @@ -534,21 +535,22 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest } } - //LM_DBG("CR: destination is: <%.*s>\n", rr->host.len, rr->host.s); - cr_new_uri.s = rr->host; - /* insert used destination into avp, in case corresponding request fails and - * another destination has to be used; this new destination must not be one - * that failed before - */ - - if (mode == CARRIERROUTE_MODE_DB){ - if ( add_avp( AVP_VAL_STR | AVP_NAME_STR, cr_uris_avp, cr_new_uri) < 0){ - LM_ERR("set AVP failed\n"); - return -1; + if (cr_avoid_failed_dests) { + //LM_DBG("CR: destination is: <%.*s>\n", rr->host.len, rr->host.s); + cr_new_uri.s = rr->host; + /* insert used destination into avp, in case corresponding request fails and + * another destination has to be used; this new destination must not be one + * that failed before + */ + + if (mode == CARRIERROUTE_MODE_DB){ + if ( add_avp( AVP_VAL_STR | AVP_NAME_STR, cr_uris_avp, cr_new_uri) < 0){ + LM_ERR("set AVP failed\n"); + return -1; + } + //print_cr_uri_avp(); } - //print_cr_uri_avp(); } - break; } case alg_crc32_nofallback: diff --git a/modules/carrierroute/doc/carrierroute_admin.xml b/modules/carrierroute/doc/carrierroute_admin.xml index 2780114dd6c..dca543b2708 100644 --- a/modules/carrierroute/doc/carrierroute_admin.xml +++ b/modules/carrierroute/doc/carrierroute_admin.xml @@ -337,6 +337,29 @@ modparam("carrierroute", "match_mode", 10) + +
+ <varname>avoid_failed_destinations</varname> (integer) + + Integer parameter to toggle on/off the possibility that in the failurerouting cases + destinations that previously failed are avoided. Possible values are 0 (off), 1 (on). + Also see cr_route section. + + + + Default value is 1. + + + + Set <varname>avoid_failed_destinations</varname> parameter + +... +modparam("carrierroute", "avoid_failed_destinations", 0) +... + + +
+
@@ -414,7 +437,8 @@ cr_tree_rewrite_uri(tree, domain) number of channels. - The function pays special attention to the failurerouting cases, so that + Depending on the value of the avoid_failed_destinations module parameter, + the function pays special attention to the failurerouting cases, so that any destination that has failed to provide a successful response will not be reused in a subsequent call of cr_route. This situation can appear when different route domains contain a set of common gateways.