From 3479d99d5f4c7fd8afc4e52a92ec3d1fb5c91446 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 28 Aug 2023 17:42:24 +0200 Subject: [PATCH] BUG/MEDIUM: stconn: Update stream expiration date on blocked sends When outgoing data are blocked, we must update the stream expiration date and requeue the task. It is important to be sure to properly handle write timeout, expecially if the stream cannot expire on reads. This bug was introduced when handling of channel's timeouts was refactored to be managed by the stream-connectors. It is an issue if there is no server timeout and the client does not consume the response (or the opposite but it is less common). It is also possible to trigger the same scenario with applets on server side because, most of time, there is no server timeout. This patch must be backported to 2.8. --- src/applet.c | 5 ++++- src/stconn.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/applet.c b/src/applet.c index 7298860e5..f4c5c862e 100644 --- a/src/applet.c +++ b/src/applet.c @@ -467,8 +467,11 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state) if (channel_is_empty(sc_oc(sc))) sc_ep_report_send_activity(sc); - else + else { sc_ep_report_blocked_send(sc); + __sc_strm(sc)->task->expire = tick_first(__sc_strm(sc)->task->expire, sc_ep_snd_ex(sc)); + task_queue(__sc_strm(sc)->task); + } /* measure the call rate and check for anomalies when too high */ if (((b_size(sc_ib(sc)) && sc->flags & SC_FL_NEED_BUFF) || // asks for a buffer which is present diff --git a/src/stconn.c b/src/stconn.c index 8bffba73d..e4d876cc5 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -1133,7 +1133,6 @@ static void sc_notify(struct stconn *sc) (channel_is_empty(oc) && !oc->to_forward)))))) { task_wakeup(task, TASK_WOKEN_IO); } - if (ic->flags & CF_READ_EVENT) sc->flags &= ~SC_FL_RCV_ONCE; } @@ -1694,6 +1693,8 @@ static int sc_conn_send(struct stconn *sc) /* We couldn't send all of our data, let the mux know we'd like to send more */ conn->mux->subscribe(sc, SUB_RETRY_SEND, &sc->wait_event); sc_ep_report_blocked_send(sc); + s->task->expire = tick_first(s->task->expire, sc_ep_snd_ex(sc)); + task_queue(s->task); } return did_send;