From: Alan T. DeKok Date: Tue, 22 Jul 2025 11:40:02 +0000 (+0200) Subject: hoist "id" into the array X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9987442d0e9df1e773ce57f50213821d5d0c681e;p=thirdparty%2Ffreeradius-server.git hoist "id" into the array so that we have better locality of reference for the O(N^2) loop for consistent keyed balance. For other situations, it increases the memory usage slightly, but doesn't have a large effect on other use-cases --- diff --git a/src/include/realms.h b/src/include/realms.h index 2d8106263f..32eff9b7da 100644 --- a/src/include/realms.h +++ b/src/include/realms.h @@ -158,7 +158,6 @@ typedef struct home_server { #ifdef HAVE_TRUST_ROUTER_TR_DH_H time_t expiration; #endif - uint32_t id; } home_server_t; @@ -172,6 +171,10 @@ typedef enum home_pool_type_t { HOME_POOL_CONSISTENT_KEYED_BALANCE } home_pool_type_t; +typedef struct { + home_server_t *home; + uint32_t id; +} home_server_id_t; typedef struct home_pool_t { char const *name; @@ -190,7 +193,7 @@ typedef struct home_pool_t { home_server_t **affinity_group; int num_home_servers; - home_server_t *servers[1]; + home_server_id_t servers[1]; } home_pool_t; diff --git a/src/main/process.c b/src/main/process.c index df02f2ff39..12e681c496 100644 --- a/src/main/process.c +++ b/src/main/process.c @@ -757,7 +757,7 @@ void request_done(REQUEST *request, int original) request->home_pool->last_serviced = now.tv_sec; for (i = 0; i < request->home_pool->num_home_servers; i++) { - home_server_t *home = request->home_pool->servers[i]; + home_server_t *home = request->home_pool->servers[i].home; if (home->state == HOME_STATE_CONNECTION_FAIL) { mark_home_server_dead(home, &now, false); diff --git a/src/main/realms.c b/src/main/realms.c index f016c67197..c4eb86eee9 100644 --- a/src/main/realms.c +++ b/src/main/realms.c @@ -1374,7 +1374,7 @@ void realm_pool_free(home_pool_t *pool) * configuration files. */ for (i = 0; i < pool->num_home_servers; i++) { - if (pool->servers[i]->cs) { + if (pool->servers[i].home->cs) { rad_assert(0 == 1); return; } @@ -1470,13 +1470,13 @@ int realm_pool_add(home_pool_t *pool, CONF_SECTION *cs) static int server_cmp_by_id(void const *one, void const *two) { - home_server_t const *a = *(home_server_t const * const *) one; - home_server_t const *b = *(home_server_t const * const *) two; + home_server_id_t const *a = (home_server_id_t const *) one; + home_server_id_t const *b = (home_server_id_t const *) two; if (a->id < b->id) return -1; if (a->id > b->id) return +1; - if (a < b) return -1; + if (a->home < b->home) return -1; return +1; } @@ -1698,7 +1698,8 @@ static int server_pool_add(realm_config_t *rc, } if (do_print) cf_log_info(cs, "\thome_server = %s", home->name); - pool->servers[num_home_servers++] = home; + pool->servers[num_home_servers++].home = home; + } /* loop over home_server's */ if (pool->fallback) { @@ -1725,7 +1726,7 @@ static int server_pool_add(realm_config_t *rc, for (i = 0; i < pool->num_home_servers; i++) { uint32_t hash; - home = pool->servers[i]; + home = pool->servers[i].home; switch (home->ipaddr.af) { case AF_INET: @@ -1754,7 +1755,7 @@ static int server_pool_add(realm_config_t *rc, } hash = fr_hash_update(&home->proto, sizeof(home->proto), hash); - home->id = fr_hash_update(&home->port, sizeof(home->port), hash); + pool->servers[i].id = fr_hash_update(&home->port, sizeof(home->port), hash); } qsort(&pool->servers[0], pool->num_home_servers, sizeof(pool->servers[0]), @@ -1866,9 +1867,9 @@ static int old_server_add(realm_config_t *rc, CONF_SECTION *cs, insert_point = -1; if (pool) { for (i = pool->num_home_servers - 1; i >= 0; i--) { - if (pool->servers[i]) break; + if (pool->servers[i].home) break; - if (!pool->servers[i]) { + if (!pool->servers[i].home) { insert_point = i; } } @@ -1993,7 +1994,7 @@ static int old_server_add(realm_config_t *rc, CONF_SECTION *cs, */ if (insert_point >= 0) { rad_assert(pool != NULL); - pool->servers[insert_point] = home; + pool->servers[insert_point].home = home; return 1; } @@ -2027,7 +2028,7 @@ static int old_server_add(realm_config_t *rc, CONF_SECTION *cs, pool->cs = cs; - pool->servers[0] = home; + pool->servers[0].home = home; if (!rbtree_insert(home_pools_byname, pool)) { rad_assert("Internal sanity check failed" == NULL); @@ -2953,10 +2954,10 @@ static home_server_t *home_server_by_consistent_key(home_pool_t *pool, uint32_t int i; for (i = 0; i < pool->num_home_servers; i++) { - if (pool->servers[i]->id > hash) return pool->servers[i]; + if (pool->servers[i].id > hash) return pool->servers[i].home; } - return pool->servers[0]; + return pool->servers[0].home; } home_server_t *home_server_ldb(char const *realmname, @@ -3092,7 +3093,7 @@ home_server_t *home_server_ldb(char const *realmname, * Otherwise, use it. */ for (count = 0; count < pool->num_home_servers; count++) { - home_server_t *home = pool->servers[(start + count) % pool->num_home_servers]; + home_server_t *home = pool->servers[(start + count) % pool->num_home_servers].home; if (!home) continue; @@ -3211,7 +3212,7 @@ all_dead: if (!realm_config->fallback && realm_config->wake_all_if_all_dead) { for (count = 0; count < pool->num_home_servers; count++) { - home_server_t *home = pool->servers[count]; + home_server_t *home = pool->servers[count].home; if (!home) continue; diff --git a/src/modules/rlm_realm/rlm_realm.c b/src/modules/rlm_realm/rlm_realm.c index 3f7e3fb30d..c8ea3ae7c4 100644 --- a/src/modules/rlm_realm/rlm_realm.c +++ b/src/modules/rlm_realm/rlm_realm.c @@ -316,9 +316,9 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm * send it there again. */ for (i = 0; i < realm->acct_pool->num_home_servers; i++) { - if (realm->acct_pool->servers[i]->ipaddr.af == AF_UNSPEC) continue; + if (realm->acct_pool->servers[i].home->ipaddr.af == AF_UNSPEC) continue; - if (fr_ipaddr_cmp(&realm->acct_pool->servers[i]->ipaddr, &my_ipaddr) == 0) { + if (fr_ipaddr_cmp(&realm->acct_pool->servers[i].home->ipaddr, &my_ipaddr) == 0) { RDEBUG2("Suppressing proxy due to FreeRADIUS-Proxied-To"); return RLM_MODULE_OK; } @@ -341,11 +341,11 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm * send it there again. */ for (i = 0; i < realm->acct_pool->num_home_servers; i++) { - if (realm->acct_pool->servers[i]->ipaddr.af == AF_UNSPEC) continue; + if (realm->acct_pool->servers[i].home->ipaddr.af == AF_UNSPEC) continue; - if ((fr_ipaddr_cmp(&realm->acct_pool->servers[i]->ipaddr, + if ((fr_ipaddr_cmp(&realm->acct_pool->servers[i].home->ipaddr, &request->packet->src_ipaddr) == 0) && - (realm->acct_pool->servers[i]->port == request->packet->src_port)) { + (realm->acct_pool->servers[i].home->port == request->packet->src_port)) { RDEBUG2("Suppressing proxy because packet was already sent to a server in that realm"); return RLM_MODULE_OK; }