From 127083a7a28ea5bfb6c74658111f90c9650cb09b Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 17 Jul 2024 17:06:00 +0200 Subject: [PATCH] MEDIUM: spoe: Set the parent stream for SPOE streams When a SPOE applet is created to send a message to an agent, the parent of the associated stream is set to the one filtered. And the relationship between the streams is removed when the applet is released or when the processing on main stream is finished. In the mean time, it is possible to get variables of the parent stream from the SPOE one. It is not a huge change but this will be amazingly useful. For instance, it is now possible to be sticky on a server using a critera of the main streem. Here is an example using the client source address: listen http bind *:80 tcp-request content set-var(txn.client_src) src filter spoe engine {SPOE-NAME} config /{SPOE-CONFIG} http-request send-spoe-group {SPOE-NAME} {SPOE-MSG} server www 127.0.0.1:8000 backend spoe-backend mode spop timeout server 10s stick-table type ip size 200k expire 30m stick on var(ptxn.client_src) server srv1 ... server srv2 ... server srv3 ... server srv4 ... Of course, the feature is not limited to stick-tables. Everywhere variables are used, it is now possible to get the value set on the parent stream from the SPOE stream. --- src/flt_spoe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/flt_spoe.c b/src/flt_spoe.c index 6b4fa1527..f11d2068c 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -392,6 +392,7 @@ static int spoe_init_appctx(struct appctx *appctx) s->do_log = NULL; s->scb->flags |= SC_FL_RCV_ONCE; + s->parent = spoe_appctx->spoe_ctx->strm; appctx->st0 = SPOE_APPCTX_ST_WAITING_ACK; appctx_wakeup(appctx); @@ -422,6 +423,7 @@ static void spoe_release_appctx(struct appctx *appctx) return; appctx->svcctx = NULL; + appctx_strm(appctx)->parent = NULL; /* Shutdown the server connection, if needed */ if (appctx->st0 != SPOE_APPCTX_ST_END) { @@ -459,8 +461,6 @@ static int spoe_handle_receiving_frame_appctx(struct appctx *appctx) if (b_data(&appctx->inbuf) > spoe_appctx->agent->max_frame_size) { spoe_ctx->state = SPOE_CTX_ST_ERROR; spoe_ctx->status_code = (spoe_appctx->status_code + 0x100); - spoe_ctx->spoe_appctx = NULL; - spoe_appctx->spoe_ctx = NULL; spoe_appctx->status_code = SPOP_ERR_TOO_BIG; appctx->st0 = SPOE_APPCTX_ST_EXIT; task_wakeup(spoe_ctx->strm->task, TASK_WOKEN_MSG); @@ -945,6 +945,7 @@ static inline void spoe_stop_processing(struct spoe_agent *agent, struct spoe_co if (sa->status_code == SPOP_ERR_NONE) sa->status_code = spoe_ctx_err_to_spop_err(ctx->status_code); sa->spoe_ctx = NULL; + appctx_strm(sa->owner)->parent = NULL; appctx_wakeup(sa->owner); }