Browse code

dispatcher: Fix handling of inactive destination for alg 13

Alg 13 did try to distribute calls to inactive destinations.
If the highest priority destination is inactive, hash is not updated
and the xavp is not set. This is resulting in failover mechanism
not working at all for the given call.

When the hash variable is not updated, it makes alg 13 behave like
round robin if the scenario above occurs. If you got two destinations
and the highest priority is out of service, 50% of the calls will fail.

Now I tried a more simple approach updating hash with the first
entry of the sorted list.

Morten Tryfoss authored on 08/12/2021 12:07:53
Showing 1 changed files
... ...
@@ -2201,7 +2201,7 @@ int ds_manage_route_algo13(ds_set_t *idx, ds_select_state_t *rstate) {
2201 2201
 	}
2202 2202
 
2203 2203
 	for(y=0; y<idx->nr ;y++) {
2204
-		int latency_proirity_handicap = 0;
2204
+		int latency_priority_handicap = 0;
2205 2205
 		ds_dest_t * ds_dest = &idx->dlist[z];
2206 2206
 		int gw_priority = ds_dest->priority;
2207 2207
 		int gw_latency = ds_dest->latency_stats.estimate;
... ...
@@ -2211,19 +2211,15 @@ int ds_manage_route_algo13(ds_set_t *idx, ds_select_state_t *rstate) {
2211 2211
 			gw_latency = ds_dest->latency_stats.estimate - ds_dest->latency_stats.average;
2212 2212
 		if(!gw_inactive) {
2213 2213
 			if(gw_latency > gw_priority && gw_priority > 0)
2214
-				latency_proirity_handicap = gw_latency / gw_priority;
2215
-			ds_dest->attrs.rpriority = gw_priority - latency_proirity_handicap;
2214
+				latency_priority_handicap = gw_latency / gw_priority;
2215
+			ds_dest->attrs.rpriority = gw_priority - latency_priority_handicap;
2216 2216
 			if(ds_dest->attrs.rpriority < 1 && gw_priority > 0)
2217 2217
 				ds_dest->attrs.rpriority = 1;
2218
-			if(ds_dest->attrs.rpriority > active_priority) {
2219
-				hash = z;
2220
-				active_priority = ds_dest->attrs.rpriority;
2221
-			}
2222 2218
 			ds_sorted[y].idx = z;
2223 2219
 			ds_sorted[y].priority = ds_dest->attrs.rpriority;
2224 2220
 			LM_DBG("[active]idx[%d]uri[%.*s]priority[%d-%d=%d]latency[%dms]flag[%d]\n",
2225 2221
 				z, ds_dest->uri.len, ds_dest->uri.s,
2226
-				gw_priority, latency_proirity_handicap,
2222
+				gw_priority, latency_priority_handicap,
2227 2223
 				ds_dest->attrs.rpriority, gw_latency, ds_dest->flags);
2228 2224
 		} else {
2229 2225
 			ds_sorted[y].idx = -1;
... ...
@@ -2237,10 +2233,15 @@ int ds_manage_route_algo13(ds_set_t *idx, ds_select_state_t *rstate) {
2237 2233
 		else
2238 2234
 			z = (z + 1) % idx->nr;
2239 2235
 	}
2240
-	idx->last = (hash + 1) % idx->nr;
2241
-	LM_DBG("priority[%d]gateway_selected[%d]next_index[%d]\n", active_priority, hash, idx->last);
2242 2236
 	ds_sorted_by_priority(ds_sorted, idx->nr);
2237
+	// the list order might have changed after sorting - update hash
2238
+	if(idx->nr > 0) {
2239
+		hash = ds_sorted[0].idx;
2240
+		active_priority = ds_sorted[0].priority;
2241
+	}
2243 2242
 	ds_manage_routes_fill_reodered_xavp(ds_sorted, idx, rstate);
2243
+	idx->last = (hash + 1) % idx->nr;
2244
+	LM_DBG("priority[%d]gateway_selected[%d]next_index[%d]\n", active_priority, hash, idx->last);
2244 2245
 	pkg_free(ds_sorted);
2245 2246
 	return hash;
2246 2247
 }