From: Christopher Faulet Date: Thu, 21 Jan 2021 15:22:01 +0000 (+0100) Subject: MEDIUM: stream-int: Take care of EOS if the SI wake callback function X-Git-Tag: v2.4-dev7~116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89e34c261b886fb8dcd894792b08ee266f622df5;p=thirdparty%2Fhaproxy.git MEDIUM: stream-int: Take care of EOS if the SI wake callback function Because si_cs_process() is also the SI wake callback function, it may be called from the mux layer. Thus, in such cases, it is performed outside any I/O event and si_cs_recv() is not called. If a read0 is reported by the mux, via the CS_FL_EOS flag, the event is not handled, because only si_cs_recv() take care of this flag for now. It is not a bug, because this does not happens for now. All muxes set this flag when the data layer retrieve data (via mux->rcv_buf()). But it is safer to be prepared to handle it from the wake callback. And in fact, it will be useful to fix the HTTP upgrades of TCP connections (especially TCP>H1>H2 upgrades). To be sure to not handle the same event twice, it is only handled if the shutr is not already set on the input channel. --- diff --git a/src/stream_interface.c b/src/stream_interface.c index 2fc56b8e65..0e2f6819a8 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -607,6 +607,21 @@ static int si_cs_process(struct conn_stream *cs) si->state = SI_ST_RDY; } + /* Report EOS on the channel if it was reached from the mux point of + * view. + * + * Note: This test is only required because si_cs_process is also the SI + * wake callback. Otherwise si_cs_recv()/si_cs_send() already take + * care of it. + */ + if (cs->flags & CS_FL_EOS && !(ic->flags & CF_SHUTR)) { + /* we received a shutdown */ + ic->flags |= CF_READ_NULL; + if (ic->flags & CF_AUTO_CLOSE) + channel_shutw_now(ic); + stream_int_read0(si); + } + /* Report EOI on the channel if it was reached from the mux point of * view. *