Browse code

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 authored on 16/04/2015 08:16:06
Showing 4 changed files
... ...
@@ -78,7 +78,7 @@ const str CR_EMPTY_PREFIX = str_init("null");
78 78
 
79 79
 int mode = 0;
80 80
 int cr_match_mode = 10;
81
-
81
+int cr_avoid_failed_dests = 1;
82 82
 
83 83
 /************* Declaration of Interface Functions **************************/
84 84
 static int mod_init(void);
... ...
@@ -108,17 +108,18 @@ static param_export_t params[]= {
108 108
 	carrierfailureroute_DB_COLS
109 109
 	carrier_name_DB_COLS
110 110
 	domain_name_DB_COLS
111
-	{"subscriber_table",       PARAM_STR, &subscriber_table },
112
-	{"subscriber_user_col",    PARAM_STR, &subscriber_username_col },
113
-	{"subscriber_domain_col",  PARAM_STR, &subscriber_domain_col },
114
-	{"subscriber_carrier_col", PARAM_STR, &cr_preferred_carrier_col },
115
-	{"config_source",          PARAM_STRING, &config_source },
116
-	{"default_tree",           PARAM_STR, &default_tree },
117
-	{"config_file",            PARAM_STRING, &config_file },
118
-	{"use_domain",             INT_PARAM, &default_carrierroute_cfg.use_domain },
119
-	{"fallback_default",       INT_PARAM, &default_carrierroute_cfg.fallback_default },
120
-	{"fetch_rows",             INT_PARAM, &default_carrierroute_cfg.fetch_rows },
121
-	{"match_mode",             INT_PARAM, &cr_match_mode },
111
+	{"subscriber_table",          PARAM_STR, &subscriber_table },
112
+	{"subscriber_user_col",       PARAM_STR, &subscriber_username_col },
113
+	{"subscriber_domain_col",     PARAM_STR, &subscriber_domain_col },
114
+	{"subscriber_carrier_col",    PARAM_STR, &cr_preferred_carrier_col },
115
+	{"config_source",             PARAM_STRING, &config_source },
116
+	{"default_tree",              PARAM_STR, &default_tree },
117
+	{"config_file",               PARAM_STRING, &config_file },
118
+	{"use_domain",                INT_PARAM, &default_carrierroute_cfg.use_domain },
119
+	{"fallback_default",          INT_PARAM, &default_carrierroute_cfg.fallback_default },
120
+	{"fetch_rows",                INT_PARAM, &default_carrierroute_cfg.fetch_rows },
121
+	{"match_mode",                INT_PARAM, &cr_match_mode },
122
+	{"avoid_failed_destinations", INT_PARAM, &cr_avoid_failed_dests },
122 123
 	{0,0,0}
123 124
 };
124 125
 
... ...
@@ -180,6 +181,11 @@ static int mod_init(void) {
180 180
 		return -1;
181 181
 	}
182 182
 
183
+	if (cr_avoid_failed_dests != 0 && cr_avoid_failed_dests != 1) {
184
+		LM_ERR("avoid_failed_dests must be 0 or 1");
185
+		return -1;
186
+	}
187
+
183 188
 	if (strcmp(config_source, "db") == 0) {
184 189
 		mode = CARRIERROUTE_MODE_DB;
185 190
 
... ...
@@ -53,6 +53,7 @@ extern const str CR_EMPTY_PREFIX;
53 53
 
54 54
 extern int mode;
55 55
 extern int cr_match_mode;
56
+extern int cr_avoid_failed_dests;
56 57
 
57 58
 extern int_str cr_uris_avp;
58 59
 
... ...
@@ -494,29 +494,30 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
494 494
 				rr->next!= NULL && rr->dice_to <= prob ; rr = rr->next) {}
495 495
 
496 496
 			//LM_DBG("CR: candidate hashed destination is: <%.*s>\n", rr->host.len, rr->host.s);
497
-
498
-			if (is_route_type(FAILURE_ROUTE) && (mode == CARRIERROUTE_MODE_DB) ){
499
-				build_used_uris_list(used_dests, &no_dests);
500
-
501
-				if (cr_uri_already_used(rr->host, used_dests, no_dests) ) {
502
-					//LM_DBG("CR: selecting new destination !!! \n");
503
-					for (rr = rf->rule_list;
504
-								rr!= NULL && cr_uri_already_used(rr->host, used_dests, no_dests); rr = rr->next) {}
505
-					/* are there any destinations that were not already used? */
506
-					if (rr == NULL) {
507
-						LM_NOTICE("All gateways from this group were already used\n");
508
-						return -1;
497
+			if (cr_avoid_failed_dests) {
498
+				if (is_route_type(FAILURE_ROUTE) && (mode == CARRIERROUTE_MODE_DB) ){
499
+					build_used_uris_list(used_dests, &no_dests);
500
+
501
+					if (cr_uri_already_used(rr->host, used_dests, no_dests) ) {
502
+						//LM_DBG("CR: selecting new destination !!! \n");
503
+						for (rr = rf->rule_list;
504
+									rr!= NULL && cr_uri_already_used(rr->host, used_dests, no_dests); rr = rr->next) {}
505
+						/* are there any destinations that were not already used? */
506
+						if (rr == NULL) {
507
+							LM_NOTICE("All gateways from this group were already used\n");
508
+							return -1;
509
+						}
510
+
511
+						/* this is a hack: we do not take probabilities into consideration if first destination
512
+						 * was previously tried */
513
+
514
+						do {
515
+							int rule_no = rand() % rf->rule_num;
516
+							//LM_DBG("CR: trying rule_no=%d \n", rule_no);
517
+							for (rr = rf->rule_list; (rule_no > 0) && (rr->next!=NULL) ; rule_no-- , rr = rr->next) {}
518
+						} while (cr_uri_already_used(rr->host, used_dests, no_dests));
519
+						LM_DBG("CR: candidate selected destination is: <%.*s>\n", rr->host.len, rr->host.s);
509 520
 					}
510
-
511
-					/* this is a hack: we do not take probabilities into consideration if first destination
512
-					 * was previously tried */
513
-
514
-					do {
515
-						int rule_no = rand() % rf->rule_num;
516
-						//LM_DBG("CR: trying rule_no=%d \n", rule_no);
517
-						for (rr = rf->rule_list; (rule_no > 0) && (rr->next!=NULL) ; rule_no-- , rr = rr->next) {}
518
-					} while (cr_uri_already_used(rr->host, used_dests, no_dests));
519
-					LM_DBG("CR: candidate selected destination is: <%.*s>\n", rr->host.len, rr->host.s);
520 521
 				}
521 522
 			}
522 523
 			/*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
534 534
 				}
535 535
 			}
536 536
 
537
-			//LM_DBG("CR: destination is: <%.*s>\n", rr->host.len, rr->host.s);
538
-			cr_new_uri.s = rr->host;
539
-			/* insert used destination into avp, in case corresponding request fails and
540
-			 * another destination has to be used; this new destination must not be one
541
-			 * that failed before
542
-			 */
543
-
544
-			if (mode == CARRIERROUTE_MODE_DB){
545
-				if ( add_avp( AVP_VAL_STR | AVP_NAME_STR, cr_uris_avp, cr_new_uri) < 0){
546
-					LM_ERR("set AVP failed\n");
547
-					return -1;
537
+			if (cr_avoid_failed_dests) {
538
+				//LM_DBG("CR: destination is: <%.*s>\n", rr->host.len, rr->host.s);
539
+				cr_new_uri.s = rr->host;
540
+				/* insert used destination into avp, in case corresponding request fails and
541
+				 * another destination has to be used; this new destination must not be one
542
+				 * that failed before
543
+				 */
544
+
545
+				if (mode == CARRIERROUTE_MODE_DB){
546
+					if ( add_avp( AVP_VAL_STR | AVP_NAME_STR, cr_uris_avp, cr_new_uri) < 0){
547
+						LM_ERR("set AVP failed\n");
548
+						return -1;
549
+					}
550
+					//print_cr_uri_avp();
548 551
 				}
549
-				//print_cr_uri_avp();
550 552
 			}
551
-
552 553
 			break;
553 554
 		}
554 555
 		case alg_crc32_nofallback:
... ...
@@ -337,6 +337,29 @@ modparam("carrierroute", "match_mode", 10)
337 337
 </programlisting>
338 338
 		</example>
339 339
 	</section>
340
+
341
+	<section>
342
+		<title><varname>avoid_failed_destinations</varname> (integer)</title>
343
+		<para>
344
+		Integer parameter to toggle on/off the possibility that in the failurerouting cases 
345
+		destinations that previously failed are avoided. Possible values are 0 (off), 1 (on).
346
+		Also see cr_route section.
347
+		</para>
348
+		<para>
349
+		<emphasis>
350
+			Default value is <quote>1</quote>.
351
+		</emphasis>
352
+		</para>
353
+		<example>
354
+		<title>Set <varname>avoid_failed_destinations</varname> parameter</title>
355
+		<programlisting format="linespecific">
356
+...
357
+modparam("carrierroute", "avoid_failed_destinations", 0)
358
+...
359
+</programlisting>
360
+		</example>
361
+	</section>
362
+
340 363
 </section>
341 364
 
342 365
     <section>
... ...
@@ -414,7 +437,8 @@ cr_tree_rewrite_uri(tree, domain)
414 414
         number of channels.
415 415
 		</para>
416 416
 		<para>
417
-		The function pays special attention to the failurerouting cases, so that
417
+		Depending on the value of the avoid_failed_destinations module parameter,
418
+		the function pays special attention to the failurerouting cases, so that
418 419
 		any destination that has failed to provide a successful response will not
419 420
 		be reused in a subsequent call of cr_route. This situation can appear when
420 421
 		different route domains contain a set of common gateways.