From: Christopher Faulet Date: Wed, 17 Jul 2024 15:06:00 +0000 (+0200) Subject: MEDIUM: spoe: Set the parent stream for SPOE streams X-Git-Tag: v3.1-dev4~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=127083a7a28ea5bfb6c74658111f90c9650cb09b;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/flt_spoe.c b/src/flt_spoe.c index 6b4fa1527b..f11d2068c0 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); }