BUG/MEDIUM: stconn: Allow expiration update when READ/WRITE event is pending

When a READ or a WRITE activity is reported on a channel, the corresponding
date is updated. the last-read-activity date (lra) is updated and the
first-send-block date (fsb) is reset. The event is also reported at the
channel level by setting CF_READ_EVENT or CF_WRITE_EVENT flags. When one of
these flags is set, this prevent the update of the stream's task expiration
date from sc_notify(). It also prevents corresponding timeout to be reported
from process_stream().

But it is a problem during fast-forwarding stage if no expiration date was
set by the stream. Only process_stream() resets these flags. So a first READ
or WRITE event will prevent any stream's expiration date update till a new
call to process_stream(). But with no expiration date, this will only happen
on shutdown/abort event, blocking the stream for a while.

It is for instance possible to block the stats applet or the cli applet if a
client does not consume the response. The stream may be blocked, the client
timeout is not respected and the stream can only be closed on a client
abort.

So now, we update the stream's expiration date, regardless of reported
READ/WRITE events. It is not a big deal because lra and fsb date are
properly updated. It also means an old READ/WRITE event will no prevent the
stream to report a timeout and it is expected too.

This patch must be backported as far as 2.8. On older versions, timeouts and
stream's expiration date are not updated in the same way and this works as
expected.
This commit is contained in:
Christopher Faulet 2024-02-12 11:37:10 +01:00
parent 5895fa8ce0
commit 2c672f282d

View File

@ -365,8 +365,7 @@ static inline int sc_is_send_allowed(const struct stconn *sc)
static inline int sc_rcv_may_expire(const struct stconn *sc)
{
if ((sc->flags & (SC_FL_ABRT_DONE|SC_FL_EOS)) ||
(sc_ic(sc)->flags & (CF_READ_TIMEOUT|CF_READ_EVENT)))
if ((sc->flags & (SC_FL_ABRT_DONE|SC_FL_EOS)) || (sc_ic(sc)->flags & CF_READ_TIMEOUT))
return 0;
if (sc->flags & (SC_FL_EOI|SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
return 0;
@ -377,8 +376,7 @@ static inline int sc_rcv_may_expire(const struct stconn *sc)
static inline int sc_snd_may_expire(const struct stconn *sc)
{
if ((sc->flags & SC_FL_SHUT_DONE) ||
(sc_oc(sc)->flags & (CF_WRITE_TIMEOUT|CF_WRITE_EVENT)))
if ((sc->flags & SC_FL_SHUT_DONE) || (sc_oc(sc)->flags & CF_WRITE_TIMEOUT))
return 0;
if (sc_ep_test(sc, SE_FL_WONT_CONSUME))
return 0;