]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stream-int: always mark pending outgoing SI_ST_CON
authorWilly Tarreau <w@1wt.eu>
Wed, 23 Jan 2019 14:15:09 +0000 (15:15 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 24 Jan 2019 18:06:43 +0000 (19:06 +0100)
Before the first send() attempt, we should be in SI_ST_CON, not
SI_ST_EST, since we have not yet attempted to send and we are
allowed to retry. This is particularly important with complex
outgoing muxes which can fail during the first send attempt (e.g.
failed stream ID allocation).

It only requires that sess_update_st_con_tcp() knows about this
possibility, as we must not forcefully close a reused connection
when facing an error in this case, this will be handled later.

This may be backported to 1.9 with care after some observation period.

include/proto/stream_interface.h
src/stream.c

index cdc2245f68ca0d5306df3a2e9ee428e58d80258c..5800c1e9d44fdca8ec1de067103a00e11481e75a 100644 (file)
@@ -491,10 +491,10 @@ static inline int si_connect(struct stream_interface *si, struct connection *con
                si->state = SI_ST_CON;
        }
        else {
-               /* reuse the existing connection */
-
-               /* the connection is established */
-               si->state = SI_ST_EST;
+               /* try to reuse the existing connection, it will be
+                * confirmed once we can send on it.
+                */
+               si->state = SI_ST_CON;
        }
 
        /* needs src ip/port for logging */
index ade70bc7cba390f7829720bb617f42036b5e6c13..c0f4b070c1ec5cdb6c9b7c57701fe5b148658e7c 100644 (file)
@@ -626,10 +626,7 @@ static int sess_update_st_con_tcp(struct stream *s)
        struct channel *req = &s->req;
        struct channel *rep = &s->res;
        struct conn_stream *srv_cs = objt_cs(si->end);
-       struct connection *conn = NULL;
-
-       if (!srv_cs)
-               conn = objt_conn(si->end);
+       struct connection *conn = srv_cs ? srv_cs->conn : objt_conn(si->end);
 
        /* If we got an error, or if nothing happened and the connection timed
         * out, we must give up. The CER state handler will take care of retry
@@ -649,9 +646,7 @@ static int sess_update_st_con_tcp(struct stream *s)
                si->exp   = TICK_ETERNITY;
                si->state = SI_ST_CER;
 
-               if (srv_cs)
-                       conn = srv_cs->conn;
-               if (conn) {
+               if (!(s->flags & SF_SRV_REUSED) && conn) {
                        conn_stop_tracking(conn);
                        conn_full_close(conn);
                }