From: Willy Tarreau Date: Tue, 10 Feb 2026 05:49:24 +0000 (+0100) Subject: CLEANUP: lb-chash: free lb_nodes from chash's deinit(), not global X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62239539bff7424e2548ac72d94fbf617dc4bee8;p=thirdparty%2Fhaproxy.git CLEANUP: lb-chash: free lb_nodes from chash's deinit(), not global There's an ambuity on the ownership of lb_nodes in chash, it's allocated by chash but freed by the server code in srv_free_params() from srv_drop() upon deinit. Let's move this free() call to a chash-specific function which will own the responsibility for doing this instead. Note that the .server_deinit() callback is properly called both on proxy being taken down and on server deletion. --- diff --git a/src/lb_chash.c b/src/lb_chash.c index 59300d13a..9e9025458 100644 --- a/src/lb_chash.c +++ b/src/lb_chash.c @@ -552,6 +552,12 @@ struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid) return srv; } +/* Releases the allocated lb_nodes for this server */ +void chash_server_deinit(struct server *srv) +{ + ha_free(&srv->lb_nodes); +} + /* This function is responsible for building the active and backup trees for * consistent hashing. The servers receive an array of initialized nodes * with their assigned keys. It also sets p->lbprm.wdiv to the eweight to @@ -567,6 +573,7 @@ int chash_init_server_tree(struct proxy *p) p->lbprm.set_server_status_up = chash_set_server_status_up; p->lbprm.set_server_status_down = chash_set_server_status_down; p->lbprm.update_server_eweight = chash_update_server_weight; + p->lbprm.server_deinit = chash_server_deinit; p->lbprm.server_take_conn = NULL; p->lbprm.server_drop_conn = NULL; diff --git a/src/server.c b/src/server.c index a475c881b..2452f0382 100644 --- a/src/server.c +++ b/src/server.c @@ -3184,7 +3184,6 @@ void srv_free_params(struct server *srv) free(srv->cc_algo); free(srv->tcp_md5sig); free(srv->addr_key); - free(srv->lb_nodes); counters_be_shared_drop(&srv->counters.shared); if (srv->log_target) { deinit_log_target(srv->log_target);