MEDIUM: spoe: Forward SPOE context error to the SPOE applet

Errors triggered by a SPOE filter intance, mainly the processing timeout, are
now forwarded to the SPOE applet. This way, an error can be reported to the SPOP
mux stream to abort it early.

Note that, for now, no abort reaon is set because the SPOP connection is not
closed. Only the SPOP stream is aborted. But thanks to this patch, the SPOE
applet can be released immediately, instead of waiting for the ACK frame or an
error on the mux side.

The related issue is #2502.
This commit is contained in:
Christopher Faulet 2024-07-10 08:06:59 +02:00
parent 1755c32949
commit 1dd2e484b0

View File

@ -513,7 +513,6 @@ static void spoe_handle_appctx(struct appctx *appctx)
return; return;
} }
SPOE_APPCTX(appctx)->status_code = SPOP_ERR_NONE;
if (!SPOE_APPCTX(appctx)->spoe_ctx) if (!SPOE_APPCTX(appctx)->spoe_ctx)
appctx->st0 = SPOE_APPCTX_ST_EXIT; appctx->st0 = SPOE_APPCTX_ST_EXIT;
@ -855,6 +854,23 @@ static int spoe_process_actions(struct stream *s, struct spoe_context *ctx, int
/*************************************************************************** /***************************************************************************
* Functions that process SPOE events * Functions that process SPOE events
**************************************************************************/ **************************************************************************/
static inline enum spop_error spoe_ctx_err_to_spop_err(enum spoe_context_error err)
{
switch (err) {
case SPOE_CTX_ERR_NONE:
return SPOP_ERR_NONE;
case SPOE_CTX_ERR_TOUT:
return SPOP_ERR_TOUT;
case SPOE_CTX_ERR_RES:
return SPOP_ERR_RES;
case SPOE_CTX_ERR_TOO_BIG:
return SPOP_ERR_TOO_BIG;
case SPOE_CTX_ERR_INTERRUPT:
return SPOP_ERR_IO;
default:
return SPOP_ERR_UNKNOWN;
}
}
static void spoe_update_stats(struct stream *s, struct spoe_agent *agent, static void spoe_update_stats(struct stream *s, struct spoe_agent *agent,
struct spoe_context *ctx, int dir) struct spoe_context *ctx, int dir)
{ {
@ -936,6 +952,8 @@ static inline void spoe_stop_processing(struct spoe_agent *agent, struct spoe_co
return; return;
_HA_ATOMIC_INC(&agent->counters.nb_processed); _HA_ATOMIC_INC(&agent->counters.nb_processed);
if (sa) { if (sa) {
if (sa->status_code == SPOP_ERR_NONE)
sa->status_code = spoe_ctx_err_to_spop_err(ctx->status_code);
sa->spoe_ctx = NULL; sa->spoe_ctx = NULL;
spoe_wakeup_appctx(sa->owner); spoe_wakeup_appctx(sa->owner);
} }