From: Willy Tarreau Date: Wed, 23 Jan 2019 14:15:09 +0000 (+0100) Subject: MEDIUM: stream-int: always mark pending outgoing SI_ST_CON X-Git-Tag: v2.0-dev1~157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf66bd1b8baf4e35d9be3655fe61eb6d017b0cfd;p=thirdparty%2Fhaproxy.git MEDIUM: stream-int: always mark pending outgoing SI_ST_CON 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. --- diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h index cdc2245f68..5800c1e9d4 100644 --- a/include/proto/stream_interface.h +++ b/include/proto/stream_interface.h @@ -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 */ diff --git a/src/stream.c b/src/stream.c index ade70bc7cb..c0f4b070c1 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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); }