From 38aac2c7bcfcce040eabd5e6df9b5c2f783a821a Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 4 Feb 2025 18:05:33 +0100 Subject: [PATCH] BUG/MEDIUM: flt-spoe: Properly handle end of stream from the SPOE applet The previous fix ("BUG/MEDIUM: applet: Don't pretend to have more data to handle EOI/EOS/ERROR") revealed an issue with the way the SPOE applet was reporting the end of stream, leading to never shut the applet down. In fact, there is two bug in one. The first one is about the applet shutdown. Since the fix above, the applet is no longer closed. Before, it was closed because it was reported in error. But now, it is just delayed because the applet and the SPOP stream are declared to support half close connections. So the applet is only closed when the SPOP connection is closed. To fix this bug, both side are now stating that half close connections are not supported. The second bug is about the way the end of stream is reported. It is reported when the ACK response is received. But it is too early, because the parent stream must process the response first. So now, we take care to have processed the ACK from the parent applet before reporting an end of stream. This patch must be backported with the commit above to 3.1. --- src/flt_spoe.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/flt_spoe.c b/src/flt_spoe.c index 0e78d49cb..bc1f1042b 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -391,7 +391,8 @@ static int spoe_init_appctx(struct appctx *appctx) applet_need_more_data(appctx); s->do_log = NULL; - s->scb->flags |= SC_FL_RCV_ONCE; + s->scb->flags |= SC_FL_RCV_ONCE | SC_FL_NOHALF; + s->scf->flags |= SC_FL_NOHALF; s->parent = spoe_appctx->spoe_ctx->strm; appctx->st0 = SPOE_APPCTX_ST_WAITING_ACK; @@ -508,13 +509,16 @@ static void spoe_handle_appctx(struct appctx *appctx) goto switchstate; case SPOE_APPCTX_ST_EXIT: - appctx->st0 = SPOE_APPCTX_ST_END; - applet_set_eos(appctx); if (SPOE_APPCTX(appctx)->status_code != SPOP_ERR_NONE) applet_set_error(appctx); else applet_set_eoi(appctx); - __fallthrough; + if (!SPOE_APPCTX(appctx)->spoe_ctx) { + appctx->st0 = SPOE_APPCTX_ST_END; + applet_set_eos(appctx); + goto switchstate; + } + break; case SPOE_APPCTX_ST_END: b_reset(&appctx->inbuf); -- 2.47.3