Browse Source

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
lucian balanceanu 10 years ago
parent
commit
f09551a9a8

+ 18 - 12
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;
 

+ 1 - 0
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;
 

+ 37 - 35
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:

+ 25 - 1
modules/carrierroute/doc/carrierroute_admin.xml

@@ -337,6 +337,29 @@ modparam("carrierroute", "match_mode", 10)
 </programlisting>
 		</example>
 	</section>
+
+	<section>
+		<title><varname>avoid_failed_destinations</varname> (integer)</title>
+		<para>
+		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.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>1</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>avoid_failed_destinations</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("carrierroute", "avoid_failed_destinations", 0)
+...
+</programlisting>
+		</example>
+	</section>
+
 </section>
 
     <section>
@@ -414,7 +437,8 @@ cr_tree_rewrite_uri(tree, domain)
         number of channels.
 		</para>
 		<para>
-		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.