]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stconn: Report blocked send if sends are blocked by an error
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 24 Oct 2024 09:35:21 +0000 (11:35 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 24 Oct 2024 09:46:33 +0000 (11:46 +0200)
When some data must be sent to the endpoint but an error was previously
reported, nothing is performed and we leave. But, in this case, the SC is not
notified the sends are blocked.

It is indeed an issue if the endpoint reports an error after consuming all
data from the SC. In the endpoint the outgoing data are trashed because of
the error, but on the SC, everything was sent, even if an error was also
reported.

Because of this bug, it is possible to have outgoing data blocked at the SC
level but without any write timeout armed. In some cases, this may lead to
blocking conditions where the stream is never closed.

So now, when outgoing data cannot be sent because an previous error was
triggered, a blocked send is reported. This way, it is possible to report a
write timeout.

This patch should fix the issue #2754. It must be backported as far as 2.8.

src/stconn.c

index 94ea9758ad0d3971136d1007d1164bceceda832d..1d4ebeaf385ce5211e07c7e12d8f1e4226b612f2 100644 (file)
@@ -1615,6 +1615,8 @@ int sc_conn_send(struct stconn *sc)
                BUG_ON(sc_ep_test(sc, SE_FL_EOS|SE_FL_ERROR|SE_FL_ERR_PENDING) == (SE_FL_EOS|SE_FL_ERR_PENDING));
                if (sc_ep_test(sc, SE_FL_ERROR))
                        sc->flags |= SC_FL_ERROR;
+               if (co_data(oc) || sc_ep_have_ff_data(sc))
+                       sc_ep_report_blocked_send(sc, 0);
                return 1;
        }
 
@@ -2209,6 +2211,8 @@ int sc_applet_send(struct stconn *sc)
 
        if (sc_ep_test(sc, SE_FL_ERROR | SE_FL_ERR_PENDING)) {
                BUG_ON(sc_ep_test(sc, SE_FL_EOS|SE_FL_ERROR|SE_FL_ERR_PENDING) == (SE_FL_EOS|SE_FL_ERR_PENDING));
+               if (co_data(oc))
+                       sc_ep_report_blocked_send(sc, 0);
                return 1;
        }