]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stconn: stop to enable/disable reads from streams via si_update_rx
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 10 Feb 2023 16:37:11 +0000 (17:37 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 10 Feb 2023 16:50:35 +0000 (17:50 +0100)
It is not really a bug because it does not fix any known issue. And it is
flagged as MEDIUM because it is sensitive. But if there are some extra calls
to process_stream(), it can be an issue because, in si_update_rx(), we may
disable reading for the SC when outgoing data are blocked in the input
channel. But it is not really the process_stream() job to take care of
that. This may block data receipt.

It is an old code, mainly here to avoid wakeup in loop on the stats
applet. Today, it seems useless and can lead to bugs. An endpoint is
responsible to block the SC if it waits for some room and the opposite
endpoint is responsible to unblock it when some data are sent. The stream
should not interfere on this part.

This patch could be backported to 2.7 after a period of observation. And it
should only be backported to lower versions if an issue is reported.

src/stconn.c

index 9dfd77ca32e406876102cf7b49ad2d1d283f431b..d8e7f8b9cf3338ed63e2803c90f3c51c84050999 100644 (file)
@@ -1041,18 +1041,6 @@ void sc_update_rx(struct stconn *sc)
        else
                sc_will_read(sc);
 
-       if (!channel_is_empty(ic) || !channel_may_recv(ic)) {
-               /* stop reading, imposed by channel's policy or contents */
-               sc_need_room(sc);
-       }
-       else {
-               /* (re)start reading and update timeout. Note: we don't recompute the timeout
-                * every time we get here, otherwise it would risk never to expire. We only
-                * update it if is was not yet set. The stream socket handler will already
-                * have updated it if there has been a completed I/O.
-                */
-               sc_have_room(sc);
-       }
        if (sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
                ic->rex = TICK_ETERNITY;
        else if (!(ic->flags & CF_READ_NOEXP) && !tick_isset(ic->rex))
@@ -1346,6 +1334,7 @@ static int sc_conn_recv(struct stconn *sc)
 
        /* prepare to detect if the mux needs more room */
        sc_ep_clr(sc, SE_FL_WANT_ROOM);
+       BUG_ON(sc_waiting_room(sc));
 
        if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) && !co_data(ic) &&
            global.tune.idle_timer &&