From: aland Date: Mon, 14 May 2007 11:17:32 +0000 (+0000) Subject: Add new load balancing method "client-port-balance" X-Git-Tag: release_2_0_0_pre1~20 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;h=6655f51fc26ce9d28e925316405eb4970df4202d;p=freeradius.git Add new load balancing method "client-port-balance" This method should be removed when we have state tracking of EAP proxies in a module --- diff --git a/raddb/proxy.conf b/raddb/proxy.conf index 1006821..a29cad4 100644 --- a/raddb/proxy.conf +++ b/raddb/proxy.conf @@ -317,14 +317,55 @@ home_server localhost { # server_pool my_auth_failover { # - # The type of this pool is either "fail-over" or "load-balance". - # - # With "fail-over", the request is sent to the first live - # home server in the list. - # - # With "load-balance", the request is load-balanced (randomly) - # between the live home servers. This is equivalent to the - # old per-realm configuration "round_robin". + # The type of this pool controls how home servers are chosen. + # + # fail-over - the request is sent to the first live + # home server in the list. i.e. If the first home server + # is marked "dead", the second one is chosen, etc. + # + # load-balance - the least busy home server is chosen, + # where "least busy" is counted by taking the number of + # requests sent to that home server, and subtracting the + # number of responses received from that home server. + # + # If there are two or more servers with the same low + # load, then one of those servers is chosen at random. + # This configuration is most similar to the old + # "round-robin" method, though it is not exactly the same. + # + # Note that load balancing does not work well with EAP, + # as EAP requires packets for an EAP conversation to be + # sent to the same home server. The load balancing method + # does not keep state in between packets, meaning that + # EAP packets for the same conversation may be sent to + # different home servers. This will prevent EAP from + # working. + # + # For non-EAP authentication methods, and for accounting + # packets, we recommend using "load-balance". It will + # ensure the highest availability for your network. + # + # client-balance - the home server is chosen by hashing the + # source IP address of the packet. If that home server + # is down, the next one in the list is used, just as + # with "fail-over". + # + # There is no way of predicting which source IP will map + # to which home server. + # + # This configuration is most useful to do simple load + # balancing for EAP sessions, as the EAP session will + # always be sent to the same home server. + # + # client-port-balance - the home server is chosen by hashing + # the source IP address and source port of the packet. + # If that home server is down, the next one in the list + # is used, just as with "fail-over". + # + # This method provides slightly better load balancing + # for EAP sessions than "client-balance". However, it + # also means that authentication and accounting packets + # for the same session MAY go to different home servers. # type = fail-over diff --git a/src/include/realms.h b/src/include/realms.h index 3c42c7f..7831017 100644 --- a/src/include/realms.h +++ b/src/include/realms.h @@ -69,7 +69,8 @@ typedef enum home_pool_type_t { HOME_POOL_INVALID = 0, HOME_POOL_LOAD_BALANCE, HOME_POOL_FAIL_OVER, - HOME_POOL_CLIENT_BALANCE + HOME_POOL_CLIENT_BALANCE, + HOME_POOL_CLIENT_PORT_BALANCE } home_pool_type_t; diff --git a/src/main/realms.c b/src/main/realms.c index d301dca..a2dd7b8 100644 --- a/src/main/realms.c +++ b/src/main/realms.c @@ -480,6 +480,7 @@ static int server_pool_add(const char *filename, CONF_SECTION *cs) { "round_robin", HOME_POOL_LOAD_BALANCE }, { "fail_over", HOME_POOL_FAIL_OVER }, { "client-balance", HOME_POOL_CLIENT_BALANCE }, + { "client-port-balance", HOME_POOL_CLIENT_PORT_BALANCE }, { NULL, 0 } }; @@ -1064,6 +1065,25 @@ home_server *home_server_ldb(const char *realmname, start = hash % pool->num_home_servers; break; + case HOME_POOL_CLIENT_PORT_BALANCE: + switch (request->packet->src_ipaddr.af) { + case AF_INET: + hash = lrad_hash(&request->packet->src_ipaddr.ipaddr.ip4addr, + sizeof(request->packet->src_ipaddr.ipaddr.ip4addr)); + break; + case AF_INET6: + hash = lrad_hash(&request->packet->src_ipaddr.ipaddr.ip6addr, + sizeof(request->packet->src_ipaddr.ipaddr.ip6addr)); + break; + default: + hash = 0; + break; + } + lrad_hash_update(&request->packet->src_port, + sizeof(request->packet->src_port), hash); + start = hash % pool->num_home_servers; + break; + case HOME_POOL_LOAD_BALANCE: found = pool->servers[0];