]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: mux-h2: consider the send list as pending data for the timeout
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 6 Nov 2026 08:56:56 +0000 (09:56 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 9 Nov 2026 12:33:52 +0000 (13:33 +0100)
When no stream connector is attached anymore, h2c_update_timeout() only
looks at the mux buffer to decide whether the connection still has data
to send, in which case it must be armed with the regular data timeout.
Streams may however still be queued in the send list while their data
sits in their own iobuf: they are blocked on a missing mux buffer, so
br_data() on the mux buffer is zero even though some bytes remain to be
sent. Such a connection is then considered idle and armed with neither
the data timeout nor anything else.

Let's also consider the send list in the condition, as it was part of
the original h2c_may_expire() before commit 3439583dd ("MEDIUM: mux-h2:
slightly relax timeout management rules") reduced it to the attached
stream count, with only br_data() being put back afterwards. This
matches what fcgi_conn_update_timeout() does.

This could be backported as far as 2.6.

src/mux_h2.c

index 069e31012201c11311346f70a9336376ced46690..e939ced0d43b5eacaa75543f2a4716eb2f40822d 100644 (file)
@@ -1016,8 +1016,12 @@ static void h2c_update_timeout(struct h2c *h2c)
 
        if (h2c_may_expire(h2c)) {
                /* no more streams attached */
-               if (br_data(h2c->mbuf)) {
-                       /* pending output data: always the regular data timeout */
+               if (br_data(h2c->mbuf) || !LIST_ISEMPTY(&h2c->send_list)) {
+                       /* pending output data, or streams still queued to send
+                        * some (blocked on a missing mux buffer, their data
+                        * being still in their own iobuf): always the regular
+                        * data timeout.
+                        */
                        h2c->task->expire = tick_add_ifset(now_ms, h2c->timeout);
                }
                else {