]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proxy: define server list iteration functions
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 Jul 2026 14:34:49 +0000 (16:34 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 24 Jul 2026 07:33:00 +0000 (09:33 +0200)
Define wrappers function to iterate over a proxy servers list. These
functions are used when a standard for loop over the whole list is not
desirable.

This patch will ease the conversion of the proxy servers list into a
doubly linked struct list type, as the final conversion patch changes
will be smaller.

14 files changed:
addons/promex/service-prometheus.c
include/haproxy/proxy.h
src/cfgparse-peers.c
src/hlua_fcn.c
src/http_ana.c
src/lb_chash.c
src/lb_fas.c
src/lb_fwlc.c
src/lb_fwrr.c
src/lb_map.c
src/proxy.c
src/resolvers.c
src/server.c
src/stats-proxy.c

index f387bb6728e1b79c9fed61acabd12be475364298..e28dc7d554e410073f3d93ef4f31b4625f21cfa0 100644 (file)
@@ -1398,7 +1398,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                                    &val, labels, &out, max))
                                        goto full;
                          next_sv:
-                               sv = watcher_next(&ctx->srv_watch, sv->next);
+                               sv = watcher_next(&ctx->srv_watch, proxy_next_server(sv));
                        }
 
                  next_px:
@@ -1406,7 +1406,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                        px = watcher_next(&ctx->px_watch, main_proxies_next(px));
                        if (px) {
                                /* Update ctx.p[1] via watcher. */
-                               watcher_attach(&ctx->srv_watch, px->srv);
+                               watcher_attach(&ctx->srv_watch, proxy_first_server(px));
                                sv = ctx->p[1];
                        }
                }
@@ -1419,7 +1419,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                px = main_proxies_first();
                watcher_attach(&ctx->px_watch, px);
                if (likely(px)) {
-                       watcher_attach(&ctx->srv_watch, px->srv);
+                       watcher_attach(&ctx->srv_watch, proxy_first_server(px));
                        sv = ctx->p[1];
                }
        }
@@ -1486,7 +1486,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                                goto full;
 
                                  next_sv2:
-                                       sv = watcher_next(&ctx->srv_watch, sv->next);
+                                       sv = watcher_next(&ctx->srv_watch, proxy_next_server(sv));
                                }
 
                          next_px2:
@@ -1494,7 +1494,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                px = watcher_next(&ctx->px_watch, main_proxies_next(px));
                                if (px) {
                                        /* Update ctx.p[1] via watcher. */
-                                       watcher_attach(&ctx->srv_watch, px->srv);
+                                       watcher_attach(&ctx->srv_watch, proxy_first_server(px));
                                        sv = ctx->p[1];
                                }
                        }
@@ -1507,7 +1507,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                        px = main_proxies_first();
                        watcher_attach(&ctx->px_watch, px);
                        if (likely(px)) {
-                               watcher_attach(&ctx->srv_watch, px->srv);
+                               watcher_attach(&ctx->srv_watch, proxy_first_server(px));
                                sv = ctx->p[1];
                        }
                }
@@ -1793,7 +1793,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx)
                                watcher_attach(&ctx->px_watch, px);
                                if (likely(px)) {
                                        /* Update ctx.p[1] via watcher. */
-                                       watcher_attach(&ctx->srv_watch, px->srv);
+                                       watcher_attach(&ctx->srv_watch, proxy_first_server(px));
                                }
                        }
                        __fallthrough;
index ff1526801653adbbb3c7af15310f363be82d19a8..8470d61cc88a7ad1676d5eff477ba7edcbc17f96 100644 (file)
@@ -346,6 +346,16 @@ static inline struct proxy *main_proxies_next(const struct proxy *px)
        return LIST_ELEM(px->el.n, struct proxy *, el);
 }
 
+static inline struct server *proxy_first_server(const struct proxy *px)
+{
+       return px->srv;
+}
+
+static inline struct server *proxy_next_server(const struct server *srv)
+{
+       return srv->next;
+}
+
 #endif /* _HAPROXY_PROXY_H */
 
 /*
index bf1f9a54372c8968ee230df68e7a1ef9b4618434..8d5b4ca2b85a3a44b1bf1f97ae925d8964cba36e 100644 (file)
@@ -314,7 +314,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
        }
        else if (strcmp(args[0], "peer") == 0 ||
                 strcmp(args[0], "server") == 0) { /* peer or server definition */
-               struct server *prev_srv;
+               struct server *srv, *prev_srv;
                int local_peer, peer;
                int parse_addr = 0;
 
@@ -365,10 +365,10 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                 * or if we are parsing a "server" line and the current peer is not the local one.
                 */
                parse_addr = (peer || !local_peer) ? SRV_PARSE_PARSE_ADDR : 0;
-               prev_srv = curpeers->peers_fe->srv;
+               prev_srv = proxy_first_server(curpeers->peers_fe);
                err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL,
                                         SRV_PARSE_IN_PEER_SECTION|parse_addr|SRV_PARSE_INITIAL_RESOLVE);
-               if (curpeers->peers_fe->srv == prev_srv) {
+               if (prev_srv == proxy_first_server(curpeers->peers_fe)) {
                        /* parse_server didn't add a server:
                         * Remove the newly allocated peer.
                         */
@@ -404,31 +404,33 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                        goto out;
                }
 
+               srv = proxy_first_server(curpeers->peers_fe);
+
                if (!parse_addr && bind_addr) {
                        /* local peer declared using "server": has name but no
                         * address: we use the known "bind" line addr settings
                         * as implicit server's addr and port.
                         */
-                       curpeers->peers_fe->srv->addr = *bind_addr;
-                       curpeers->peers_fe->srv->svc_port = get_host_port(bind_addr);
+                       srv->addr = *bind_addr;
+                       srv->svc_port = get_host_port(bind_addr);
                }
 
-               if (nb_shards && curpeers->peers_fe->srv->shard > nb_shards) {
+               if (nb_shards && srv->shard > nb_shards) {
                        ha_warning("parsing [%s:%d] : '%s %s' : %d peer shard greater value than %d shards value is ignored.\n",
-                                  file, linenum, args[0], args[1], curpeers->peers_fe->srv->shard, nb_shards);
-                       curpeers->peers_fe->srv->shard = 0;
+                                  file, linenum, args[0], args[1], srv->shard, nb_shards);
+                       srv->shard = 0;
                        err_code |= ERR_WARN;
                }
 
-               if (curpeers->peers_fe->srv->init_addr_methods || curpeers->peers_fe->srv->resolvers_id ||
-                   curpeers->peers_fe->srv->do_check || curpeers->peers_fe->srv->do_agent) {
+               if (srv->init_addr_methods || srv->resolvers_id ||
+                   srv->do_check || srv->do_agent) {
                        ha_warning("parsing [%s:%d] : '%s %s' : init_addr, resolvers, check and agent are ignored for peers.\n", file, linenum, args[0], args[1]);
                        err_code |= ERR_WARN;
                }
 
                HA_SPIN_INIT(&newpeer->lock);
 
-               newpeer->srv = curpeers->peers_fe->srv;
+               newpeer->srv = srv;
                if (!newpeer->local)
                        goto out;
 
index 92f154263a419ce65ca046296c00b095ecc9c8c4..6424fe2bb9b58e5fa79cf3f3fc56aa2d0bf9c214 100644 (file)
@@ -1890,7 +1890,7 @@ int hlua_listable_servers_pairs_iterator(lua_State *L)
 
        if (ctx->px) {
                /* First iteration, initialize list on the first server */
-               cur = ctx->px->srv;
+               cur = proxy_first_server(ctx->px);
                watcher_attach(&ctx->srv_watch, cur);
                ctx->px = NULL;
        }
@@ -1906,7 +1906,7 @@ int hlua_listable_servers_pairs_iterator(lua_State *L)
        }
 
        /* compute next server */
-       ctx->next = watcher_next(&ctx->srv_watch, cur->next);
+       ctx->next = watcher_next(&ctx->srv_watch, proxy_next_server(cur));
 
        lua_pushstring(L, cur->id);
        hlua_fcn_new_server(L, cur);
index 75369fe183d589fbe73e20f55bb3e1b0d64ead7f..b4a57cb082267730cf29f44742ed46059ad97ee0 100644 (file)
@@ -3424,7 +3424,7 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re
                         */
                        if ((att_end - att_beg == s->be->cookie_len) && (s->be->cookie_name != NULL) &&
                            (memcmp(att_beg, s->be->cookie_name, att_end - att_beg) == 0)) {
-                               struct server *srv = s->be->srv;
+                               struct server *srv = proxy_first_server(s->be);
                                char *delim;
 
                                /* if we're in cookie prefix mode, we'll search the delimiter so that we
@@ -3520,7 +3520,7 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re
                                if ((delim == val_beg) || (s->flags & (SF_IGNORE_PRST | SF_ASSIGNED)))
                                        srv = NULL;
 
-                               while (srv) {
+                               for (; srv; srv = proxy_next_server(srv)) {
                                        if (srv->cookie && (srv->cklen == delim - val_beg) &&
                                            !memcmp(val_beg, srv->cookie, delim - val_beg)) {
                                                if ((srv->cur_state != SRV_ST_STOPPED) ||
@@ -3541,7 +3541,6 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re
                                                        txn->flags |= TX_CK_DOWN;
                                                }
                                        }
-                                       srv = srv->next;
                                }
 
                                if (!srv && !(txn->flags & (TX_CK_DOWN|TX_CK_EXPIRED|TX_CK_OLD))) {
index ce60bee8ba5af9cb09ca09cd1fc638713934a7ab..d19f06de44a4a886146495575a7a849c6f027bb6 100644 (file)
@@ -21,6 +21,7 @@
 #include <haproxy/backend.h>
 #include <haproxy/errors.h>
 #include <haproxy/guid.h>
+#include <haproxy/proxy.h>
 #include <haproxy/queue.h>
 #include <haproxy/server.h>
 #include <haproxy/tools.h>
@@ -240,7 +241,7 @@ static void chash_set_server_status_down(struct server *srv)
                         */
                        struct server *srv2 = p->lbprm.fbck;
                        do {
-                               srv2 = srv2->next;
+                               srv2 = proxy_next_server(srv2);
                        } while (srv2 &&
                                 !((srv2->flags & SRV_F_BACKUP) &&
                                   srv_willbe_usable(srv2)));
@@ -301,7 +302,7 @@ static void chash_set_server_status_up(struct server *srv)
                                 */
                                struct server *srv2 = srv;
                                do {
-                                       srv2 = srv2->next;
+                                       srv2 = proxy_next_server(srv2);
                                } while (srv2 && (srv2 != p->lbprm.fbck));
                                if (srv2)
                                        p->lbprm.fbck = srv;
index f789d19db64e50a32d9d2b5f7d7d70970439d6b1..3f601d8a57e040857f92920dade0b96aef03ce5c 100644 (file)
@@ -19,6 +19,7 @@
 #include <import/eb32tree.h>
 #include <haproxy/api.h>
 #include <haproxy/backend.h>
+#include <haproxy/proxy.h>
 #include <haproxy/queue.h>
 #include <haproxy/server-t.h>
 
@@ -106,7 +107,7 @@ static void fas_set_server_status_down(struct server *srv)
                         */
                        struct server *srv2 = p->lbprm.fbck;
                        do {
-                               srv2 = srv2->next;
+                               srv2 = proxy_next_server(srv2);
                        } while (srv2 &&
                                 !((srv2->flags & SRV_F_BACKUP) &&
                                   srv_willbe_usable(srv2)));
@@ -169,7 +170,7 @@ static void fas_set_server_status_up(struct server *srv)
                                 */
                                struct server *srv2 = srv;
                                do {
-                                       srv2 = srv2->next;
+                                       srv2 = proxy_next_server(srv2);
                                } while (srv2 && (srv2 != p->lbprm.fbck));
                                if (srv2)
                                        p->lbprm.fbck = srv;
index 6c1cd13e0891c81a761195d03872c0d4c3ea0ec7..c635d5edc866d3d1c3bc1ccc15057071847e155c 100644 (file)
@@ -13,6 +13,7 @@
 #include <import/eb32tree.h>
 #include <haproxy/api.h>
 #include <haproxy/backend.h>
+#include <haproxy/proxy.h>
 #include <haproxy/queue.h>
 #include <haproxy/server-t.h>
 #include <haproxy/task.h>
@@ -560,7 +561,7 @@ static void fwlc_set_server_status_down(struct server *srv)
                         */
                        struct server *srv2 = p->lbprm.fbck;
                        do {
-                               srv2 = srv2->next;
+                               srv2 = proxy_next_server(srv2);
                        } while (srv2 &&
                                 !((srv2->flags & SRV_F_BACKUP) &&
                                   srv_willbe_usable(srv2)));
@@ -623,7 +624,7 @@ static void fwlc_set_server_status_up(struct server *srv)
                                 */
                                struct server *srv2 = srv;
                                do {
-                                       srv2 = srv2->next;
+                                       srv2 = proxy_next_server(srv2);
                                } while (srv2 && (srv2 != p->lbprm.fbck));
                                if (srv2)
                                        p->lbprm.fbck = srv;
index 8d2386529b64fb473de4364039a2a780641de1b0..28fca679d64ddab1a7683c985bf52f737211529e 100644 (file)
@@ -16,6 +16,7 @@
 #include <haproxy/queue.h>
 #include <haproxy/server-t.h>
 #include <haproxy/global.h>
+#include <haproxy/proxy.h>
 
 
 static inline void fwrr_remove_from_tree(struct server *s, int tgid);
@@ -68,7 +69,7 @@ static void fwrr_set_server_status_down(struct server *srv)
                         */
                        struct server *srv2 = p->lbprm.fbck;
                        do {
-                               srv2 = srv2->next;
+                               srv2 = proxy_next_server(srv2);
                        } while (srv2 &&
                                 !((srv2->flags & SRV_F_BACKUP) &&
                                   srv_willbe_usable(srv2)));
@@ -134,7 +135,7 @@ static void fwrr_set_server_status_up(struct server *srv)
                                 */
                                struct server *srv2 = srv;
                                do {
-                                       srv2 = srv2->next;
+                                       srv2 = proxy_next_server(srv2);
                                } while (srv2 && (srv2 != p->lbprm.fbck));
                                if (srv2)
                                        p->lbprm.fbck = srv;
@@ -343,7 +344,7 @@ static int fwrr_init_server_groups(struct proxy *p)
                                        srv, i + 1);
                }
                j = 0;
-               for (srv = p->srv; srv && j < i; srv = srv->next) {
+               for (srv = proxy_first_server(p); srv && j < i; srv = proxy_next_server(srv)) {
                        j++;
                        if (!srv_currently_usable(srv))
                                continue;
index 91d09caf5745e5741cb4911b1c14f8d3a89ebb53..e71400349644c35f882877874fc15c86f92aa8e4 100644 (file)
@@ -14,6 +14,7 @@
 #include <haproxy/api.h>
 #include <haproxy/backend.h>
 #include <haproxy/lb_map.h>
+#include <haproxy/proxy.h>
 #include <haproxy/queue.h>
 #include <haproxy/server-t.h>
 
@@ -152,13 +153,13 @@ static int init_server_map(struct proxy *p)
         * find a non-zero weight server.
         */
        pgcd = 1;
-       srv = p->srv;
+       srv = proxy_first_server(p);
        while (srv && !srv->uweight)
-               srv = srv->next;
+               srv = proxy_next_server(srv);
 
        if (srv) {
                pgcd = srv->uweight; /* note: cannot be zero */
-               while (pgcd > 1 && (srv = srv->next)) {
+               while (pgcd > 1 && (srv = proxy_next_server(srv))) {
                        int w = srv->uweight;
                        while (w) {
                                int t = pgcd % w;
index a1906f25259b04e5a67e2d4516004395fd135512..4789a86f6017d1ed735f95d1f551a3595a0bc8fb 100644 (file)
@@ -4509,9 +4509,9 @@ static int dump_servers_state(struct appctx *appctx)
        char *srvrecord;
 
        if (!ctx->sv)
-               watcher_attach(&ctx->srv_watch, px->srv);
+               watcher_attach(&ctx->srv_watch, proxy_first_server(px));
 
-       for (; ctx->sv; watcher_next(&ctx->srv_watch, ctx->sv->next)) {
+       for (; ctx->sv; watcher_next(&ctx->srv_watch, proxy_next_server(ctx->sv))) {
                srv = ctx->sv;
 
                dump_server_addr(&srv->addr, srv_addr);
index 2144561dce041a8e78628dd647c370ec8a6abea5..1d99dd9536cef006e99ae37b5fe633d86bef0c9f 100644 (file)
@@ -3780,7 +3780,7 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
                                goto out;
                        }
 
-                       if (dns_stream_init(newnameserver, curr_resolvers->px->srv) < 0) {
+                       if (dns_stream_init(newnameserver, proxy_first_server(curr_resolvers->px)) < 0) {
                                ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
                                err_code |= ERR_ALERT|ERR_ABORT;
                                free(newnameserver);
index 94a8e9772fb6f882ac75a5a88b088b87086070ff..1171c7364cc868f566cf72326ead24abcca7418a 100644 (file)
@@ -6699,7 +6699,7 @@ leave:
 static int cli_parse_delete_server(char **args, char *payload, struct appctx *appctx, void *private)
 {
        struct proxy *be;
-       struct server *srv;
+       struct server *srv, *next;
        struct ist be_name, sv_name;
        struct watcher *srv_watch;
        const char *msg;
@@ -6750,10 +6750,11 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
        if (srv->proxy->lbprm.ops && srv->proxy->lbprm.ops->server_deinit)
                srv->proxy->lbprm.ops->server_deinit(srv);
 
+       next = proxy_next_server(srv);
+       BUG_ON(next && next->flags & SRV_F_DELETED);
        while (!MT_LIST_ISEMPTY(&srv->watcher_list)) {
                srv_watch = MT_LIST_NEXT(&srv->watcher_list, struct watcher *, el);
-               BUG_ON(srv->next && srv->next->flags & SRV_F_DELETED);
-               watcher_next(srv_watch, srv->next);
+               watcher_next(srv_watch, next);
        }
 
        /* detach the server from the proxy linked list
index dbcfdb9df90dbbe335a1942ddf074030a4fd4dbf..e9337769f250b412851449437195dd1f00fd7cbe 100644 (file)
@@ -1529,7 +1529,7 @@ more:
                }
 
                /* for servers ctx.obj2 is set via watcher_attach() */
-               watcher_attach(&ctx->srv_watch, px->srv);
+               watcher_attach(&ctx->srv_watch, proxy_first_server(px));
                ctx->px_st = STAT_PX_ST_SV;
 
                __fallthrough;
@@ -1537,7 +1537,7 @@ more:
        case STAT_PX_ST_SV:
                /* obj2 is updated and returned through watcher_next() */
                for (sv = ctx->obj2; sv;
-                    sv = watcher_next(&ctx->srv_watch, sv->next)) {
+                    sv = watcher_next(&ctx->srv_watch, proxy_next_server(sv))) {
 
                        if (stats_is_full(appctx, buf, htx))
                                goto full;