mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
BUG/MEDIUM: applet: Add a flag to state an applet is using zero-copy forwarding
An issue was introduced when zero-copy forwarding was added to the stats and cache applets. There is no test to be sure the upper layer is ready to use the zero-copy forwarding. So these applets refuse to deliver the response into the applet's output buffer if the zero-copy forwarding is supported by the opposite endpoint. It is especially an issue when a filter, like the compression, is in-use on the response channel. Because of this bug, the response is not delivered and the applet is woken up in loop to produce data. To fix the issue, an appctx flag was added, APPCTX_FL_FASTFWD, to know when the zero-copy forwarding is in-use. We rely on this flag to not fill the outbuf in the applet's I/O handler. No backport needed.
This commit is contained in:
parent
1465eb570b
commit
ece002af1d
@ -47,6 +47,7 @@
|
||||
#define APPCTX_FL_SHUTDOWN 0x00000100 /* applet was shut down (->release() called if any). No more data exchange with SCs */
|
||||
#define APPCTX_FL_WANT_DIE 0x00000200 /* applet was running and requested to die */
|
||||
#define APPCTX_FL_INOUT_BUFS 0x00000400 /* applet uses its own buffers */
|
||||
#define APPCTX_FL_FASTFWD 0x00000800 /* zero-copy forwarding is in-use, don't fill the outbuf */
|
||||
|
||||
struct appctx;
|
||||
struct proxy;
|
||||
|
@ -537,6 +537,9 @@ size_t appctx_rcv_buf(struct stconn *sc, struct buffer *buf, size_t count, unsig
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (flags & CO_RFL_BUF_FLUSH)
|
||||
applet_fl_set(appctx, APPCTX_FL_FASTFWD);
|
||||
|
||||
ret = appctx->applet->rcv_buf(appctx, buf, count, flags);
|
||||
if (ret)
|
||||
applet_fl_clr(appctx, APPCTX_FL_OUTBLK_FULL);
|
||||
@ -648,6 +651,8 @@ int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
|
||||
|
||||
TRACE_ENTER(APPLET_EV_RECV, appctx);
|
||||
|
||||
applet_fl_set(appctx, APPCTX_FL_FASTFWD);
|
||||
|
||||
/* TODO: outbuf must be empty. Find a better way to handle that but for now just return -1 */
|
||||
if (b_data(&appctx->outbuf)) {
|
||||
TRACE_STATE("Output buffer not empty, cannot fast-forward data", APPLET_EV_RECV, appctx);
|
||||
@ -670,6 +675,7 @@ int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags)
|
||||
len = se_nego_ff(sdo, &BUF_NULL, count, nego_flags);
|
||||
if (sdo->iobuf.flags & IOBUF_FL_NO_FF) {
|
||||
sc_ep_clr(sc, SE_FL_MAY_FASTFWD);
|
||||
applet_fl_clr(appctx, APPCTX_FL_FASTFWD);
|
||||
TRACE_DEVEL("Fast-forwarding not supported by opposite endpoint, disable it", APPLET_EV_RECV, appctx);
|
||||
goto end;
|
||||
}
|
||||
|
@ -1757,6 +1757,7 @@ static size_t http_cache_fastfwd(struct appctx *appctx, struct buffer *buf, size
|
||||
|
||||
if (!appctx->to_forward) {
|
||||
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD);
|
||||
applet_fl_clr(appctx, APPCTX_FL_FASTFWD);
|
||||
if (ctx->sent == first->len - sizeof(*cache_ptr)) {
|
||||
applet_set_eoi(appctx);
|
||||
applet_set_eos(appctx);
|
||||
@ -1779,7 +1780,7 @@ static void http_cache_io_handler(struct appctx *appctx)
|
||||
if (applet_fl_test(appctx, APPCTX_FL_OUTBLK_ALLOC|APPCTX_FL_OUTBLK_FULL))
|
||||
goto exit;
|
||||
|
||||
if (se_fl_test(appctx->sedesc, SE_FL_MAY_FASTFWD))
|
||||
if (applet_fl_test(appctx, APPCTX_FL_FASTFWD) && se_fl_test(appctx->sedesc, SE_FL_MAY_FASTFWD))
|
||||
goto exit;
|
||||
|
||||
if (!appctx_get_buf(appctx, &appctx->outbuf)) {
|
||||
@ -1853,6 +1854,7 @@ static void http_cache_io_handler(struct appctx *appctx)
|
||||
res_htx->flags |= HTX_FL_EOM;
|
||||
applet_set_eoi(appctx);
|
||||
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD);
|
||||
applet_fl_clr(appctx, APPCTX_FL_FASTFWD);
|
||||
appctx->st0 = HTX_CACHE_END;
|
||||
}
|
||||
|
||||
|
@ -4471,6 +4471,7 @@ static size_t http_stats_fastfwd(struct appctx *appctx, struct buffer *buf, size
|
||||
ret = b_data(buf);
|
||||
if (stats_dump_stat_to_buffer(sc, buf, NULL)) {
|
||||
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD);
|
||||
applet_fl_clr(appctx, APPCTX_FL_FASTFWD);
|
||||
appctx->st0 = STAT_HTTP_DONE;
|
||||
}
|
||||
|
||||
@ -4495,7 +4496,7 @@ static void http_stats_io_handler(struct appctx *appctx)
|
||||
if (applet_fl_test(appctx, APPCTX_FL_OUTBLK_ALLOC|APPCTX_FL_OUTBLK_FULL))
|
||||
goto out;
|
||||
|
||||
if (se_fl_test(appctx->sedesc, SE_FL_MAY_FASTFWD))
|
||||
if (applet_fl_test(appctx, APPCTX_FL_FASTFWD) && se_fl_test(appctx->sedesc, SE_FL_MAY_FASTFWD))
|
||||
goto out;
|
||||
|
||||
if (!appctx_get_buf(appctx, &appctx->outbuf)) {
|
||||
@ -4560,6 +4561,7 @@ static void http_stats_io_handler(struct appctx *appctx)
|
||||
res_htx->flags |= HTX_FL_EOM;
|
||||
applet_set_eoi(appctx);
|
||||
se_fl_clr(appctx->sedesc, SE_FL_MAY_FASTFWD);
|
||||
applet_fl_clr(appctx, APPCTX_FL_FASTFWD);
|
||||
appctx->st0 = STAT_HTTP_END;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user