Module: kamailio Branch: master Commit: adba3caa2d12d1f8b89d720fbb9a6a9cdc8b2573 URL: https://github.com/kamailio/kamailio/commit/adba3caa2d12d1f8b89d720fbb9a6a9c...
Author: Morten Tryfoss morten@tryfoss.no Committer: Daniel-Constantin Mierla miconda@gmail.com Date: 2022-01-11T12:46:33+01:00
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.
---
Modified: src/modules/dispatcher/dispatch.c
---
Diff: https://github.com/kamailio/kamailio/commit/adba3caa2d12d1f8b89d720fbb9a6a9c... Patch: https://github.com/kamailio/kamailio/commit/adba3caa2d12d1f8b89d720fbb9a6a9c...
---
diff --git a/src/modules/dispatcher/dispatch.c b/src/modules/dispatcher/dispatch.c index 26836433f1..fad6334fa4 100644 --- a/src/modules/dispatcher/dispatch.c +++ b/src/modules/dispatcher/dispatch.c @@ -2201,7 +2201,7 @@ int ds_manage_route_algo13(ds_set_t *idx, ds_select_state_t *rstate) { }
for(y=0; y<idx->nr ;y++) { - int latency_proirity_handicap = 0; + int latency_priority_handicap = 0; ds_dest_t * ds_dest = &idx->dlist[z]; int gw_priority = ds_dest->priority; 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) { gw_latency = ds_dest->latency_stats.estimate - ds_dest->latency_stats.average; if(!gw_inactive) { if(gw_latency > gw_priority && gw_priority > 0) - latency_proirity_handicap = gw_latency / gw_priority; - ds_dest->attrs.rpriority = gw_priority - latency_proirity_handicap; + latency_priority_handicap = gw_latency / gw_priority; + ds_dest->attrs.rpriority = gw_priority - latency_priority_handicap; if(ds_dest->attrs.rpriority < 1 && gw_priority > 0) ds_dest->attrs.rpriority = 1; - if(ds_dest->attrs.rpriority > active_priority) { - hash = z; - active_priority = ds_dest->attrs.rpriority; - } ds_sorted[y].idx = z; ds_sorted[y].priority = ds_dest->attrs.rpriority; LM_DBG("[active]idx[%d]uri[%.*s]priority[%d-%d=%d]latency[%dms]flag[%d]\n", z, ds_dest->uri.len, ds_dest->uri.s, - gw_priority, latency_proirity_handicap, + gw_priority, latency_priority_handicap, ds_dest->attrs.rpriority, gw_latency, ds_dest->flags); } else { ds_sorted[y].idx = -1; @@ -2237,10 +2233,15 @@ int ds_manage_route_algo13(ds_set_t *idx, ds_select_state_t *rstate) { else z = (z + 1) % idx->nr; } - idx->last = (hash + 1) % idx->nr; - LM_DBG("priority[%d]gateway_selected[%d]next_index[%d]\n", active_priority, hash, idx->last); ds_sorted_by_priority(ds_sorted, idx->nr); + // the list order might have changed after sorting - update hash + if(idx->nr > 0) { + hash = ds_sorted[0].idx; + active_priority = ds_sorted[0].priority; + } ds_manage_routes_fill_reodered_xavp(ds_sorted, idx, rstate); + idx->last = (hash + 1) % idx->nr; + LM_DBG("priority[%d]gateway_selected[%d]next_index[%d]\n", active_priority, hash, idx->last); pkg_free(ds_sorted); return hash; }