]> git.kaiwu.me - haproxy.git/commitdiff
CLEANUP: sink: initialize and finalize the implicit forward proxy
authorWilly Tarreau <w@1wt.eu>
Wed, 26 Aug 2026 13:47:54 +0000 (15:47 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 26 Aug 2026 13:56:09 +0000 (15:56 +0200)
sink_new_from_logger() builds a forward proxy by hand from a POST_CHECK
hook, that is after check_config_validity() has walked over
sink_proxies_list. As a result, contrary to the proxy of a "ring"
section, that one was neither passed to proxy_init_per_thr() nor to
proxy_finalize(), and kept running with px->per_tgrp left NULL, no
load-balancing setup at all (lbprm.algo, lbprm.ops and the lbprm lock
were never initialized), and its server left in SRV_ST_STOPPED with a
zero effective weight.

It still works surprisingly well but for how long... Let's just make
sure the freshly created server is completely initialized like any
other one so as to avoid susprises in the future like the max-reuse
one.

This shouldn't be backported as it might reveal other issues in older
code.

src/sink.c

index 8d660ce71fddbf66db358b4420a8e23e0fe9326c..e08a8abfb26ef2589288d3ff778631f2b5221cde 100644 (file)
@@ -1240,6 +1240,7 @@ struct sink *sink_new_from_logger(struct logger *logger)
        struct sink *sink = NULL;
        struct server *srv = NULL;
        char *err_msg = NULL;
+       int err_code = ERR_NONE;
 
        /* prepare description for the sink */
        chunk_reset(&trash);
@@ -1293,6 +1294,16 @@ struct sink *sink_new_from_logger(struct logger *logger)
        if (srv_preinit(srv) & ERR_CODE)
                goto error;
 
+       /* Same thing for the forward proxy: check_config_validity() has
+        * already walked over sink_proxies_list, so this one is never
+        * initialized nor finalized. Keep the same order as there, as the
+        * load-balancing setup performed by proxy_finalize() relies on the
+        * per-thread-group areas allocated by proxy_init_per_thr().
+        */
+       proxy_init_per_thr(sink->forward_px);
+       if (proxy_finalize(sink->forward_px, &err_code) || (err_code & ERR_CODE))
+               goto error;
+
        if (sink_finalize(sink) & ERR_CODE)
                goto error;