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.
This commit is contained in:
Christopher Faulet 2024-07-17 17:06:00 +02:00
parent 230c1570ac
commit 127083a7a2

View File

@ -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);
}