]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stconn: Update stream expiration date on blocked sends
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 28 Aug 2023 15:42:24 +0000 (17:42 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 1 Sep 2023 12:18:26 +0000 (14:18 +0200)
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
src/stconn.c

index 7298860e5316893cdb2faa85fc933c89301c57ce..f4c5c862ed3c2c5ce1e1e50621600e51868dd483 100644 (file)
@@ -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
index 8bffba73df0ab4aaa0d5552bbbb728c71cc2a520..e4d876cc51ab8ec3a2ad08d3a719d642d89ab0ad 100644 (file)
@@ -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;