]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: streams: Don't switch from SI_ST_CON to SI_ST_DIS on read0.
authorOlivier Houchard <ohouchard@haproxy.com>
Tue, 21 May 2019 15:43:50 +0000 (17:43 +0200)
committerOlivier Houchard <cognet@ci0.org>
Tue, 21 May 2019 17:05:09 +0000 (19:05 +0200)
When we receive a read0, and we're still in SI_ST_CON state (so on an
outgoing conneciton), don't immediately switch to SI_ST_DIS, or, we would
never call sess_establish(), and so the analysers will never run.
Instead, let sess_establish() handle that case, and switch to SI_ST_DIS if
we already have CF_SHUTR on the channel.

This should be backported to 1.9.

src/stream.c
src/stream_interface.c

index f0c7ad21f73aefc135d3e33a34ff9bbac66987a4..1e884658290761211b855ba32ce4224690b08114 100644 (file)
@@ -880,6 +880,11 @@ static int sess_update_st_cer(struct stream *s)
  * This function handles the transition between the SI_ST_CON state and the
  * SI_ST_EST state. It must only be called after switching from SI_ST_CON (or
  * SI_ST_INI) to SI_ST_EST, but only when a ->proto is defined.
+ * Note that it will switch the interface to SI_ST_DIS if we already have
+ * the CF_SHUTR flag, it means we were able to forward the request, and
+ * receive the response, before process_stream() had the opportunity to
+ * make the switch from SI_ST_CON to SI_ST_EST. When that happens, we want
+ * to go through sess_establish() anyway, to make sure the analysers run.
  */
 static void sess_establish(struct stream *s)
 {
@@ -928,6 +933,9 @@ static void sess_establish(struct stream *s)
                si_chk_rcv(si);
        }
        req->wex = TICK_ETERNITY;
+       /* If we managed to get the whole response, switch to SI_ST_DIS now. */
+       if (rep->flags & CF_SHUTR)
+               si->state = SI_ST_DIS;
 }
 
 /* Check if the connection request is in such a state that it can be aborted. */
index 3b9c70777017e0c8a5650ea1154ebbf7298a72c4..22391336e7e5c18044662d4120391eed357a5a9a 100644 (file)
@@ -1486,7 +1486,12 @@ static void stream_int_read0(struct stream_interface *si)
 
        si_done_get(si);
 
-       si->state = SI_ST_DIS;
+       /* Don't change the state to SI_ST_DIS yet if we're still
+        * in SI_ST_CON, otherwise it means sess_establish() hasn't
+        * been called yet, and so the analysers would not run.
+        */
+       if (si->state == SI_ST_EST)
+               si->state = SI_ST_DIS;
        si->exp = TICK_ETERNITY;
        return;
 }