Mercurial > hg > freeDiameter
changeset 563:dc9764591567
Automatic load-balancing between peers that have the same routing score. Use rt_ereg to obtain stable routes.
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Thu, 16 Sep 2010 16:41:44 +0900 |
parents | e837ef4bdf35 |
children | 603f70bf1453 |
files | freeDiameter/routing_dispatch.c libfreeDiameter/rt_data.c |
diffstat | 2 files changed, 33 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/freeDiameter/routing_dispatch.c Thu Sep 16 14:35:48 2010 +0900 +++ b/freeDiameter/routing_dispatch.c Thu Sep 16 16:41:44 2010 +0900 @@ -843,7 +843,7 @@ if (rtd == NULL) { CHECK_FCT( fd_rtd_init(&rtd) ); - /* Add all peers in OPEN state */ + /* Add all peers currently in OPEN state */ CHECK_FCT( pthread_rwlock_rdlock(&fd_g_activ_peers_rw) ); for (li = fd_g_activ_peers.next; li != &fd_g_activ_peers; li = li->next) { struct fd_peer * p = (struct fd_peer *)li->o;
--- a/libfreeDiameter/rt_data.c Thu Sep 16 14:35:48 2010 +0900 +++ b/libfreeDiameter/rt_data.c Thu Sep 16 16:41:44 2010 +0900 @@ -249,10 +249,12 @@ return; } -/* Reorder the list of peers */ +/* Reorder the list of peers. If several peer have the same highest score, they are randomized. */ int fd_rtd_candidate_reorder(struct fd_list * candidates) { struct fd_list unordered = FD_LIST_INITIALIZER(unordered), *li; + struct fd_list highest = FD_LIST_INITIALIZER(highest); + int hs = -1; TRACE_ENTRY("%p", candidates); CHECK_PARAMS( candidates ); @@ -266,17 +268,39 @@ fd_list_unlink(&c->chain); - /* Find the position in ordered candidates list */ - for (li = candidates->next; li != candidates; li = li->next) { - struct rtd_candidate * cnext = (struct rtd_candidate *) li; - if (cnext->score >= c->score) - break; + /* If this candidate has a higher score than the previous ones */ + if (c->score > hs) { + /* Then we move the previous high score items at end of the list */ + fd_list_move_end(candidates, &highest); + + /* And the new high score is this reset */ + hs = c->score; } - /* Add the element there */ - fd_list_insert_before(li, &c->chain); + /* If this candidate equals the higher score, add it into highest list at a random place */ + if (c->score == hs) { + if (rand() & 1) { + fd_list_insert_after(&highest, &c->chain); + } else { + fd_list_insert_before(&highest, &c->chain); + } + /* Otherwise, insert at normal place in the list */ + } else { + /* Find the position in ordered candidates list */ + for (li = candidates->next; li != candidates; li = li->next) { + struct rtd_candidate * cnext = (struct rtd_candidate *) li; + if (cnext->score >= c->score) + break; + } + + /* Add the element there */ + fd_list_insert_before(li, &c->chain); + } } + /* Now simply move back all the "highest" candidates at the end of the list */ + fd_list_move_end(candidates, &highest); + return 0; }