* Main balancing routine. This does not try to keep the same proxy for * the call if some proxies were disabled or enabled; proxy death considered * too rare. Otherwise we should implement "mature" HA clustering, which is * too expensive here. */
| 3361 | * too expensive here. |
| 3362 | */ |
| 3363 | static struct rtpe_node * |
| 3364 | select_rtpe_node(str callid, struct rtpe_set *set, struct rtpe_ignore_node *ignore_list) |
| 3365 | { |
| 3366 | unsigned sum, weight_sum; |
| 3367 | struct rtpe_node* node; |
| 3368 | int was_forced, sumcut, found, constant_weight_sum; |
| 3369 | |
| 3370 | /* check last list version */ |
| 3371 | if (my_version != *list_version && update_rtpengines(0) < 0) { |
| 3372 | LM_ERR("cannot update rtpengines list\n"); |
| 3373 | return 0; |
| 3374 | } |
| 3375 | |
| 3376 | if(!set){ |
| 3377 | LM_ERR("script error -no valid set selected\n"); |
| 3378 | return NULL; |
| 3379 | } |
| 3380 | |
| 3381 | /* Most popular case: 1 proxy, nothing to calculate */ |
| 3382 | if (set->rtpe_node_count == 1) { |
| 3383 | node = set->rn_first; |
| 3384 | if (node->rn_disabled || rtpe_is_ignore_node(ignore_list, node)) |
| 3385 | return NULL; |
| 3386 | return node; |
| 3387 | } |
| 3388 | |
| 3389 | /* XXX Use quick-and-dirty hashing algo */ |
| 3390 | for(sum = 0; callid.len > 0; callid.len--) |
| 3391 | sum += callid.s[callid.len - 1]; |
| 3392 | sum &= 0xff; |
| 3393 | |
| 3394 | was_forced = 0; |
| 3395 | weight_sum = 0; |
| 3396 | constant_weight_sum = 0; |
| 3397 | found = 0; |
| 3398 | for (node=set->rn_first; node!=NULL; node=node->rn_next) { |
| 3399 | constant_weight_sum += node->rn_weight; |
| 3400 | if (!node->rn_disabled && !rtpe_is_ignore_node(ignore_list, node)) { |
| 3401 | weight_sum += node->rn_weight; |
| 3402 | found = 1; |
| 3403 | } |
| 3404 | } |
| 3405 | if (found == 0) { |
| 3406 | return NULL; |
| 3407 | } |
| 3408 | sumcut = weight_sum ? sum % constant_weight_sum : -1; |
| 3409 | /* |
| 3410 | * sumcut here lays from 0 to constant_weight_sum-1. |
| 3411 | * Scan proxy list and decrease until appropriate proxy is found. |
| 3412 | */ |
| 3413 | was_forced = 0; |
| 3414 | for (node=set->rn_first; node!=NULL;) { |
| 3415 | if (sumcut < (int)node->rn_weight) { |
| 3416 | if (!node->rn_disabled && !rtpe_is_ignore_node(ignore_list, node)) |
| 3417 | return node; |
| 3418 | if (was_forced == 0) { |
| 3419 | /* appropriate proxy is disabled : redistribute on enabled ones */ |
| 3420 | sumcut = weight_sum ? sum % weight_sum : -1; |
no test coverage detected