Skip to content

drouting: fix random GW selection when all weights are zero#3867

Open
wlp2s0 wants to merge 1 commit intoOpenSIPS:masterfrom
wlp2s0:fix/drouting-weight-zero-random-selection
Open

drouting: fix random GW selection when all weights are zero#3867
wlp2s0 wants to merge 1 commit intoOpenSIPS:masterfrom
wlp2s0:fix/drouting-weight-zero-random-selection

Conversation

@wlp2s0
Copy link
Copy Markdown

@wlp2s0 wlp2s0 commented Apr 8, 2026

Summary

Fix the weight_based_sort() function in the drouting module so that gateways with weight 0 are selected randomly with uniform distribution, instead of always picking the first one.

Details

When all remaining gateways in a routing group have weight == 0, the total weight_sum becomes 0. In this case the code fell through to an else branch that was supposed to randomly pick one of the equally-weighted gateways. However the random selection line was commented out and replaced with i = first;, which deterministically selected the first gateway every time.

This means that in any drouting rule where all gateways have weight 0 (or where the remaining unselected gateways all have weight 0), traffic was never distributed — it always went to the same gateway.

Solution

Restore and correct the random selection in the else branch of weight_based_sort():

i = first + (unsigned int)((size - first) * ((double)rand() / ((double)RAND_MAX + 1.0)));

Key points:

  • The + first offset ensures we only pick among the remaining (not yet sorted) gateways.
  • The + 1.0 on RAND_MAX prevents an out-of-bounds index when rand() == RAND_MAX (the result stays strictly in [first, size-1]).

Compatibility

No configuration or API changes. The fix only affects the runtime behavior of weight-based gateway selection when weight_sum == 0, restoring the intended uniform random distribution. Existing configurations with non-zero weights are completely unaffected.

Closing issues

Closes #3863

When weight_sum is 0 (all remaining gateways have weight 0), the code
was always selecting the first gateway (i = first) instead of randomly
picking one among the equally-weighted candidates.

Restore uniform random selection by computing:
  i = first + (unsigned int)((size - first) * ((double)rand() / ((double)RAND_MAX + 1.0)));

The +1.0 on RAND_MAX prevents the index from going out of bounds (i.e.
when rand() == RAND_MAX the result stays strictly below size-first).

Closes: OpenSIPS#3863
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

drouting: intentional behavior or dead code? random GW selection commented out in weight_based_sort() when weight_sum==0

1 participant