]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proxy: define proxies_list iteration functions
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 15 Jul 2026 14:30:45 +0000 (16:30 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 Jul 2026 14:03:19 +0000 (16:03 +0200)
Define wrappers function for <proxies_list> iteration. These functions
are used when a standard for loop over the whole list is not desirable.

The objective of this patch is to ease the conversion of <proxies_list>
from a singly linked list to a standard doubly linked list type. This
will help to keep the final conversion patch smaller.

Also, iteration over struct list is sligthly more complicated as it
requires more operation, for example for list end detection. Thus, the
wrappers will become handy to avoid tedious code repetion.

addons/promex/service-prometheus.c
include/haproxy/proxy.h
src/ech.c
src/hlua_fcn.c
src/proxy.c
src/ssl_ckch.c
src/stats-proxy.c
src/stats.c

index a0ebdff6300bc48b7b565f82c43860d338ecbff1..f387bb6728e1b79c9fed61acabd12be475364298 100644 (file)
@@ -539,9 +539,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
                if (promex_filter_metric(appctx, prefix, name))
                        continue;
 
-               if (!px)
-                       px = proxies_list;
-
+               px = main_proxies_cond_first(px);
                while (px) {
                        struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                        enum promex_mt_type type;
@@ -618,7 +616,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
                                            &val, labels, &out, max))
                                goto full;
                  next_px:
-                       px = px->next;
+                       px = main_proxies_next(px);
                }
                ctx->flags |= PROMEX_FL_METRIC_HDR;
        }
@@ -643,9 +641,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
                        if (promex_filter_metric(appctx, prefix, name))
                                continue;
 
-                       if (!px)
-                               px = proxies_list;
-
+                       px = main_proxies_cond_first(px);
                        while (px) {
                                struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                                struct promex_metric metric;
@@ -680,7 +676,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
                                        goto full;
 
                        next_px2:
-                               px = px->next;
+                               px = main_proxies_next(px);
                        }
                        ctx->flags |= PROMEX_FL_METRIC_HDR;
                }
@@ -739,9 +735,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                if (promex_filter_metric(appctx, prefix, name))
                        continue;
 
-               if (!px)
-                       px = proxies_list;
-
+               px = main_proxies_cond_first(px);
                while (px) {
                        struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                        int lb_idx = 0;
@@ -806,7 +800,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                        li = NULL;
 
                  next_px:
-                       px = px->next;
+                       px = main_proxies_next(px);
                }
                ctx->flags |= PROMEX_FL_METRIC_HDR;
        }
@@ -831,9 +825,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                        if (promex_filter_metric(appctx, prefix, name))
                                continue;
 
-                       if (!px)
-                               px = proxies_list;
-
+                       px = main_proxies_cond_first(px);
                        while (px) {
                                struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                                struct promex_metric metric;
@@ -879,7 +871,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                                li = NULL;
 
                        next_px2:
-                               px = px->next;
+                               px = main_proxies_next(px);
                        }
                        ctx->flags |= PROMEX_FL_METRIC_HDR;
                }
@@ -1097,7 +1089,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                                            &val, labels, &out, max))
                                goto full;
                  next_px:
-                       px = watcher_next(&ctx->px_watch, px->next);
+                       px = watcher_next(&ctx->px_watch, main_proxies_next(px));
                }
                watcher_detach(&ctx->px_watch);
                ctx->flags |= PROMEX_FL_METRIC_HDR;
@@ -1105,8 +1097,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                /* Prepare a new iteration for the next stat column.
                 * Update ctx.p[0] via watcher.
                 */
-               watcher_attach(&ctx->px_watch, proxies_list);
-               px = proxies_list;
+               px = main_proxies_first();
+               watcher_attach(&ctx->px_watch, px);
        }
 
        /* Skip extra counters */
@@ -1163,7 +1155,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                                        goto full;
 
                        next_px2:
-                               px = watcher_next(&ctx->px_watch, px->next);
+                               px = watcher_next(&ctx->px_watch, main_proxies_next(px));
                        }
                        watcher_detach(&ctx->px_watch);
                        ctx->flags |= PROMEX_FL_METRIC_HDR;
@@ -1171,8 +1163,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                        /* Prepare a new iteration for the next stat column.
                         * Update ctx.p[0] via watcher.
                         */
-                       watcher_attach(&ctx->px_watch, proxies_list);
-                       px = proxies_list;
+                       px = main_proxies_first();
+                       watcher_attach(&ctx->px_watch, px);
                }
 
                ctx->field_num += mod->stats_count;
@@ -1411,7 +1403,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
 
                  next_px:
                        watcher_detach(&ctx->srv_watch);
-                       px = watcher_next(&ctx->px_watch, px->next);
+                       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);
@@ -1424,8 +1416,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                /* Prepare a new iteration for the next stat column.
                 * Update ctx.p[0]/p[1] via px_watch/srv_watch.
                 */
-               watcher_attach(&ctx->px_watch, proxies_list);
-               px = proxies_list;
+               px = main_proxies_first();
+               watcher_attach(&ctx->px_watch, px);
                if (likely(px)) {
                        watcher_attach(&ctx->srv_watch, px->srv);
                        sv = ctx->p[1];
@@ -1499,7 +1491,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
 
                          next_px2:
                                watcher_detach(&ctx->srv_watch);
-                               px = watcher_next(&ctx->px_watch, px->next);
+                               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);
@@ -1512,8 +1504,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                        /* Prepare a new iteration for the next stat column.
                         * Update ctx.p[0]/p[1] via px_watch/srv_watch.
                         */
-                       watcher_attach(&ctx->px_watch, proxies_list);
-                       px = proxies_list;
+                       px = main_proxies_first();
+                       watcher_attach(&ctx->px_watch, px);
                        if (likely(px)) {
                                watcher_attach(&ctx->srv_watch, px->srv);
                                sv = ctx->p[1];
@@ -1711,6 +1703,7 @@ static int promex_dump_all_modules_metrics(struct appctx *appctx, struct htx *ht
 static int promex_dump_metrics(struct appctx *appctx, struct htx *htx)
 {
        struct promex_ctx *ctx = appctx->svcctx;
+       struct proxy *px;
        int ret;
 
        switch (appctx->st1) {
@@ -1773,7 +1766,8 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx)
 
                        if (ctx->flags & PROMEX_FL_SCOPE_BACK) {
                                /* Update ctx.p[0] via watcher. */
-                               watcher_attach(&ctx->px_watch, proxies_list);
+                               px = main_proxies_first();
+                               watcher_attach(&ctx->px_watch, px);
                        }
                        __fallthrough;
 
@@ -1795,10 +1789,11 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx)
 
                        if (ctx->flags & PROMEX_FL_SCOPE_SERVER) {
                                /* Update ctx.p[0] via watcher. */
-                               watcher_attach(&ctx->px_watch, proxies_list);
-                               if (likely(proxies_list)) {
+                               px = main_proxies_first();
+                               watcher_attach(&ctx->px_watch, px);
+                               if (likely(px)) {
                                        /* Update ctx.p[1] via watcher. */
-                                       watcher_attach(&ctx->srv_watch, proxies_list->srv);
+                                       watcher_attach(&ctx->srv_watch, px->srv);
                                }
                        }
                        __fallthrough;
index 3d543024c5abd2deef57a91822d118e5e3f14721..2884e8110d15e47fc6eca59eecc1bc90e62eeee0 100644 (file)
@@ -324,6 +324,28 @@ static inline void main_proxies_register(struct proxy *px)
        proxies_list = px;
 }
 
+/* Returns first entry in main proxies list or NULL if empty. */
+static inline struct proxy *main_proxies_first(void)
+{
+       return proxies_list;
+}
+
+/* Returns first entry in main proxies list unless <px> is already set. This is
+ * useful when iterating over proxies with possible task yielding interruption.
+ */
+static inline struct proxy *main_proxies_cond_first(struct proxy *px)
+{
+       if (!px)
+               px = proxies_list;
+       return px;
+}
+
+/* Return next entry after <px> in main proxies list or NULL if reaching end of list. */
+static inline struct proxy *main_proxies_next(const struct proxy *px)
+{
+       return px->next;
+}
+
 #endif /* _HAPROXY_PROXY_H */
 
 /*
index d7e74dbcc6c57d88701151b82be67c7a08f8020e..d5de79268bff1dd848914de8482e40d08938b8b1 100644 (file)
--- a/src/ech.c
+++ b/src/ech.c
@@ -154,7 +154,7 @@ static int cli_parse_show_ech(char **args, char *payload,
        } else {
                ctx->specific_name = NULL;
                ctx->specific_ctx = NULL;
-               ctx->pp = proxies_list;
+               ctx->pp = main_proxies_first();
                ctx->b = NULL;
                ctx->state = SHOW_ECH_ALL;
        }
@@ -246,7 +246,7 @@ static int cli_io_handler_ech_details(struct appctx *appctx)
                bind_conf = ctx->b;
                p = ctx->pp;
 
-               for (; p; p = p->next) {
+               for (; p; p = main_proxies_next(p)) {
 
                        if (!(p->cap & PR_CAP_FE) || LIST_ISEMPTY(&p->conf.bind))
                                continue;
index f204c0a048c4900baa880b3d14fceb6ce1475fb9..92f154263a419ce65ca046296c00b095ecc9c8c4 100644 (file)
@@ -2379,10 +2379,10 @@ int hlua_listable_proxies_pairs_iterator(lua_State *L)
        lua_pushstring(L, ctx->next->id);
        hlua_fcn_new_proxy(L, ctx->next);
 
-       ctx->next = watcher_next(&ctx->px_watch, ctx->next->next);
+       ctx->next = watcher_next(&ctx->px_watch, main_proxies_next(ctx->next));
        for (;
             ctx->next && !hlua_listable_proxies_match(ctx->next, ctx->capabilities);
-            ctx->next = watcher_next(&ctx->px_watch, ctx->next->next))
+            ctx->next = watcher_next(&ctx->px_watch, main_proxies_next(ctx->next)))
                ;
 
        return 2;
@@ -2426,9 +2426,9 @@ int hlua_listable_proxies_pairs(lua_State *L)
        ctx->next = NULL;
        watcher_init(&ctx->px_watch, &ctx->next, offsetof(struct proxy, watcher_list));
 
-       for (watcher_attach(&ctx->px_watch, proxies_list);
+       for (watcher_attach(&ctx->px_watch, main_proxies_first());
             ctx->next && !hlua_listable_proxies_match(ctx->next, ctx->capabilities);
-            ctx->next = watcher_next(&ctx->px_watch, ctx->next->next))
+            ctx->next = watcher_next(&ctx->px_watch, main_proxies_next(ctx->next)))
                ;
 
        lua_pushcclosure(L, hlua_listable_proxies_pairs_iterator, 1);
index f3d705fd9ef49aa2791ce0e953c2da3507c508ea..23adbbf0e74c47f382b7f7a753c54b69c6727322 100644 (file)
@@ -4592,10 +4592,10 @@ static int cli_io_handler_servers_state(struct appctx *appctx)
                ctx->state = SHOW_SRV_LIST;
 
                if (!ctx->px)
-                       watcher_attach(&ctx->px_watch, proxies_list);
+                       watcher_attach(&ctx->px_watch, main_proxies_first());
        }
 
-       for (; ctx->px; watcher_next(&ctx->px_watch, ctx->px->next)) {
+       for (; ctx->px; watcher_next(&ctx->px_watch, main_proxies_next(ctx->px))) {
                curproxy = ctx->px;
                /* servers are only in backends */
                if ((curproxy->cap & PR_CAP_BE) && !(curproxy->cap & PR_CAP_INT)) {
@@ -4629,11 +4629,11 @@ static int cli_io_handler_show_backend(struct appctx *appctx)
 
                watcher_init(&ctx->px_watch, &ctx->px, offsetof(struct proxy, watcher_list));
                /* This will automatically update ctx->px pointer. */
-               watcher_attach(&ctx->px_watch, proxies_list);
+               watcher_attach(&ctx->px_watch, main_proxies_first());
        }
 
-       for (; ctx->px; watcher_next(&ctx->px_watch, ctx->px->next)) {
-               curproxy = ctx->px;
+       for (; ctx->px; watcher_next(&ctx->px_watch, main_proxies_next(ctx->px))) {
+               curproxy = appctx->svcctx;
 
                /* looking for non-internal backends only */
                if ((curproxy->cap & (PR_CAP_BE|PR_CAP_INT)) != PR_CAP_BE)
@@ -5111,7 +5111,7 @@ static int cli_parse_delete_backend(char **args, char *payload, struct appctx *a
 
        while (!MT_LIST_ISEMPTY(&px->watcher_list)) {
                px_watch = MT_LIST_NEXT(&px->watcher_list, struct watcher *, el);
-               watcher_next(px_watch, px->next);
+               watcher_next(px_watch, main_proxies_next(px));
        }
 
        ceb32_item_delete(&used_proxy_id, conf.uuid_node, uuid, px);
@@ -5327,7 +5327,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                if (applet_putchk(appctx, &trash) == -1)
                        goto cant_send;
 
-               watcher_attach(&ctx->px_watch, proxies_list);
+               watcher_attach(&ctx->px_watch, main_proxies_first());
                ctx->bol = 0;
                ctx->ptr = -1;
        }
@@ -5459,7 +5459,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                ctx->ptr = -1;
                ctx->flag ^= 1;
                if (!(ctx->flag & 1))
-                       watcher_next(&ctx->px_watch, ctx->px->next);
+                       watcher_next(&ctx->px_watch, main_proxies_next(ctx->px));
        }
 
        /* dump complete */
index c3de2cbd8e663d4974c4983196a96270a3d11191..59fb01456a1586e64d4eb907eb423975513d8635 100644 (file)
@@ -1720,15 +1720,15 @@ static int cli_io_handler_show_sni(struct appctx *appctx)
                return 1;
 
        /* ctx->bind is NULL only once we finished dumping a frontend or when starting
-        * so let's dump the header in these cases*/
+        * so let's dump the header in these cases.
+        */
        if (ctx->bind == NULL && (ctx->options & SHOW_SNI_OPT_1FRONTEND ||
-           (!(ctx->options & SHOW_SNI_OPT_1FRONTEND) && ctx->px == proxies_list)))
+           (!(ctx->options & SHOW_SNI_OPT_1FRONTEND) && ctx->px == main_proxies_first())))
                chunk_appendf(trash, "# Frontend/Bind\tSNI\tNegative Filter\tType\tFilename\tNotAfter\tNotBefore\n");
        if (applet_putchk(appctx, trash) == -1)
                goto yield;
 
-       for (px = ctx->px; px; px = px->next) {
-
+       for (px = ctx->px; px; px = main_proxies_next(px)) {
                /* only check the frontends which are not internal proxies */
                if (!(px->cap & PR_CAP_FE) || (px->cap & PR_CAP_INT))
                        continue;
@@ -1851,7 +1851,7 @@ static int cli_parse_show_sni(char **args, char *payload, struct appctx *appctx,
        struct show_sni_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
        int cur_arg = 3;
 
-       ctx->px = proxies_list;
+       ctx->px = main_proxies_first();
 
        /* look for the right <frontend> to display */
 
index 9238810ef03b2adeeff82672b0d2336efd0ecfac..5b43aac574062012c55604d93dbebc6dbd39dd43 100644 (file)
@@ -1635,7 +1635,7 @@ int stats_dump_proxies(struct stconn *sc, struct buffer *buf, struct htx *htx)
        /* dump proxies */
        /* obj1 is updated and returned through watcher_next() */
        for (px = ctx->obj1; px;
-            px = watcher_next(&ctx->px_watch, px->next)) {
+            px = watcher_next(&ctx->px_watch, main_proxies_next(px))) {
 
                if (stats_is_full(appctx, buf, htx))
                        goto full;
index 6843f49b457543892366acd4139a4856295ebdf7..442632ad48e12eedadc1af5ceb516b8c40283789 100644 (file)
@@ -596,7 +596,7 @@ int stats_dump_stat_to_buffer(struct stconn *sc, struct buffer *buf, struct htx
                ctx->state = STAT_STATE_LIST;
                /* Update ctx->obj1 via watcher to point on the first proxy. */
                if (domain == STATS_DOMAIN_PROXY)
-                       watcher_attach(&ctx->px_watch, proxies_list);
+                       watcher_attach(&ctx->px_watch, main_proxies_first());
 
                __fallthrough;