dispatcher module doing wrong when skipping inactive nodes on weighted
load distribution usage ( alg 9 )

here:
https://github.com/kamailio/kamailio/blob/master/modules/dispatcher/dispatch.c#L1919
loop iterates over possible destinations to get first active after
previously computed destination if it inactive.

this works for all balancing algorythms except of 9 (weighted balancing),
because on failover it ignores idx->wlist array and chooses next
destination ignoring weights.
thus we will get all traffic for inactive destination on the destination
which next by destinations index.

suggested patch changes behavior to continue to iterate over idx->wlist
on inactive destinations skipping for alg 9.

please, examine and apply.

-- 
Regards
Michael Furmur

diff --git a/modules/dispatcher/dispatch.c b/modules/dispatcher/dispatch.c
index 3638a9c..c834224 100644
--- a/modules/dispatcher/dispatch.c
+++ b/modules/dispatcher/dispatch.c
@@ -1744,6 +1744,17 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
 	return ds_select_dst_limit(msg, set, alg, 0, mode);
 }
 
+static inline int is_use_default(ds_set_t *idx)
+{
+	if(ds_use_default!=0 && idx->nr)
+	{
+		int i = idx->nr-1;
+		if(!ds_skip_dst(idx->dlist[i].flags))
+			return i;
+	}
+	return -1;
+}
+
 /**
  * Set destination address from group 'set' selected with alogorithm 'alg'
  * - the rest of addresses in group are added as next destination in avps,
@@ -1753,7 +1764,7 @@ int ds_select_dst(struct sip_msg *msg, int set, int alg, int mode)
  */
 int ds_select_dst_limit(sip_msg_t *msg, int set, int alg, unsigned int limit, int mode)
 {
-	int i, cnt;
+	int i, cnt, wlast;
 	unsigned int hash;
 	int_str avp_val;
 	ds_set_t *idx = NULL;
@@ -1914,25 +1925,34 @@ int ds_select_dst_limit(sip_msg_t *msg, int set, int alg, unsigned int limit, in
 	else
 		hash = hash%idx->nr;
 	i=hash;
+	wlast = idx->wlast;
 
 	/* if selected address is inactive, find next active */
 	while (ds_skip_dst(idx->dlist[i].flags))
 	{
-		if(ds_use_default!=0 && idx->nr!=1)
-			i = (i+1)%(idx->nr-1);
-		else
-			i = (i+1)%idx->nr;
-		if(i==hash)
+		if(alg == 9) /* weight based distribution */
 		{
-			/* back to start -- looks like no active dst */
-			if(ds_use_default!=0)
+			idx->wlast = (idx->wlast+1) % 100;
+			i = idx->wlist[idx->wlast];
+			if(idx->wlast == wlast)
 			{
-				i = idx->nr-1;
-				if(ds_skip_dst(idx->dlist[i].flags))
+				if((i = is_use_default(idx)) != -1)
+					break;
+				else
+					return -1;
+			}
+		} else {
+			if(ds_use_default!=0 && idx->nr!=1)
+				i = (i+1)%(idx->nr-1);
+			else
+				i = (i+1)%idx->nr;
+			if(i == hash)
+			{
+				/* back to start -- looks like no active dst */
+				if((i = is_use_default(idx)) != -1)
+					break;
+				else
 					return -1;
-				break;
-			} else {
-				return -1;
 			}
 		}
 	}

_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to