From: Aurelien DARRAGON Date: Tue, 6 Oct 2026 19:26:35 +0000 (+0200) Subject: MINOR: event_hdl/proxy: publish EVENT_HDL_SUB_PROXY_{ADD,DEL,PUB,UNPUB} events X-Git-Tag: v3.5-dev9~39 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=e9d897a08b5dfaae6012eb087dcbb3601dbc1165;p=haproxy.git MINOR: event_hdl/proxy: publish EVENT_HDL_SUB_PROXY_{ADD,DEL,PUB,UNPUB} events Proxy events are published in the per-proxy subscription list as well as global one. EVENT_HDL_SUB_PROXY_ADD is published when proxy is created (ie: "add backend"), EVENT_HDL_SUB_PROXY_DEL when backend is removed, EVENT_HDL_SUB_PROXY_PUB when backend is published and EVENT_HDL_SUB_PROXY_UNPUB when backend is unpublished. All events provide event_hdl_cb_data_proxy struct, which contains info about the proxy that triggered the event. --- diff --git a/include/haproxy/proxy-t.h b/include/haproxy/proxy-t.h index 51c0f3ead..f9db0482b 100644 --- a/include/haproxy/proxy-t.h +++ b/include/haproxy/proxy-t.h @@ -549,6 +549,35 @@ struct proxy { int totpend; /* total number of pending connections on this instance (for stats) */ }; +/* data provided to EVENT_HDL_SUB_PROXY handlers through event_hdl facility */ +struct event_hdl_cb_data_proxy { + /* provided by: + * EVENT_HDL_SUB_PROXY_ADD + * EVENT_HDL_SUB_PROXY_DEL + */ + struct { + /* safe data can be safely used from both + * sync and async handlers + * data consistency is guaranteed + */ + char cap; /* supported capabilities (PR_CAP_*) */ + int uuid; /* uuid of the proxy */ + char name[64]; /* id of proxy */ + char guid[GUID_MAX_LEN + 1];/* GUID global tree node */ + } safe; + struct { + /* unsafe data may only be used from sync handlers: + * in async mode, data consistency cannot be guaranteed + * and unsafe data may already be stale, thus using + * it is highly discouraged because it + * could lead to undefined behavior (UAF, null dereference...) + */ + + /* not use yet */ + } unsafe; +}; + + struct switching_rule { struct list list; /* list linked to from the proxy */ struct acl_cond *cond; /* acl condition to meet */ diff --git a/src/proxy.c b/src/proxy.c index c70fc9cea..9c4fb5d0c 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -566,6 +566,30 @@ enum pr_mode str_to_proxy_mode(const char *mode) return PR_MODES; } +/* proxy event publishing helper: publish in both global and + * proxy dedicated subscription list. + */ +#define _proxy_event_hdl_publish(e, d, px) \ + ({ \ + /* publish in proxy dedicated sub list */ \ + event_hdl_publish(&px->e_subs, e, EVENT_HDL_CB_DATA(&d));\ + /* publish in global subscription list */ \ + event_hdl_publish(NULL, e, EVENT_HDL_CB_DATA(&d)) ; \ + }) + +/* fill common proxy event data members struct + * must be called with server lock or under thread isolate + */ +static inline void _proxy_event_hdl_prepare(struct event_hdl_cb_data_proxy *cb_data, + struct proxy *proxy) +{ + /* safe data assignments */ + cb_data->safe.cap = proxy->cap; + cb_data->safe.uuid = proxy->uuid; + snprintf(cb_data->safe.name, sizeof(cb_data->safe.name), "%s", proxy->id); + snprintf(cb_data->safe.guid, sizeof(cb_data->safe.guid), "%s", proxy->guid.key); +} + /* try to find among known options the one that looks closest to by * counting transitions between letters, digits and other characters. Will * return the best matching word if found, otherwise NULL. An optional array @@ -5041,6 +5065,7 @@ static int cli_parse_add_backend(char **args, char *payload, struct appctx *appc { struct proxy *px, *defpx; struct post_proxy_check_fct *ppcf; + struct event_hdl_cb_data_proxy e_cb_data; const char *be_name, *def_name, *guid = NULL, *err; char *msg = NULL; enum pr_mode mode = 0; @@ -5198,6 +5223,11 @@ static int cli_parse_add_backend(char **args, char *payload, struct appctx *appc * setup_new_proxy() via alloc_new_proxy(). */ main_proxies_register(px); + + /* backend creation cannot fail anymore, time to publish the PROXY_ADD event */ + _proxy_event_hdl_prepare(&e_cb_data, px); + _proxy_event_hdl_publish(EVENT_HDL_SUB_PROXY_ADD, e_cb_data, px); + thread_release(); if (unlikely(!be_supports_dynamic_srv(px, &msg))) @@ -5302,6 +5332,7 @@ int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm /* Handler for "delete backend". Runs under thread isolation. Always returns 1. */ static int cli_parse_delete_backend(char **args, char *payload, struct appctx *appctx, void *private) { + struct event_hdl_cb_data_proxy e_cb_data; struct watcher *px_watch; struct proxy *px; const char *msg; @@ -5343,6 +5374,10 @@ static int cli_parse_delete_backend(char **args, char *payload, struct appctx *a */ flt_deinit_new_proxy(px); + /* backend deletion cannot fail anymore, time to publish the PROXY_DEL event */ + _proxy_event_hdl_prepare(&e_cb_data, px); + _proxy_event_hdl_publish(EVENT_HDL_SUB_PROXY_DEL, e_cb_data, px); + thread_release(); ha_notice("Backend deleted.\n"); @@ -5419,6 +5454,7 @@ static int cli_parse_enable_frontend(char **args, char *payload, struct appctx * static int cli_parse_publish_backend(char **args, char *payload, struct appctx *appctx, void *private) { + struct event_hdl_cb_data_proxy e_cb_data; struct proxy *px; usermsgs_clr("CLI"); @@ -5435,6 +5471,11 @@ static int cli_parse_publish_backend(char **args, char *payload, struct appctx * thread_isolate(); px->flags &= ~PR_FL_BE_UNPUBLISHED; + + /* backend publish cannot fail anymore, time to publish the PROXY_PUB event */ + _proxy_event_hdl_prepare(&e_cb_data, px); + _proxy_event_hdl_publish(EVENT_HDL_SUB_PROXY_PUB, e_cb_data, px); + thread_release(); ha_notice("Backend published.\n"); @@ -5443,6 +5484,7 @@ static int cli_parse_publish_backend(char **args, char *payload, struct appctx * static int cli_parse_unpublish_backend(char **args, char *payload, struct appctx *appctx, void *private) { + struct event_hdl_cb_data_proxy e_cb_data; struct proxy *px; usermsgs_clr("CLI"); @@ -5459,6 +5501,11 @@ static int cli_parse_unpublish_backend(char **args, char *payload, struct appctx thread_isolate(); px->flags |= PR_FL_BE_UNPUBLISHED; + + /* backend unpublish cannot fail anymore, time to publish the PROXY_UNPUB event */ + _proxy_event_hdl_prepare(&e_cb_data, px); + _proxy_event_hdl_publish(EVENT_HDL_SUB_PROXY_UNPUB, e_cb_data, px); + thread_release(); ha_notice("Backend unpublished.\n");