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.
This commit is contained in:
Willy Tarreau 2019-01-23 15:15:09 +01:00
parent e9634bdc22
commit bf66bd1b8b
2 changed files with 6 additions and 11 deletions

View File

@ -491,10 +491,10 @@ static inline int si_connect(struct stream_interface *si, struct connection *con
si->state = SI_ST_CON; si->state = SI_ST_CON;
} }
else { else {
/* reuse the existing connection */ /* try to reuse the existing connection, it will be
* confirmed once we can send on it.
/* the connection is established */ */
si->state = SI_ST_EST; si->state = SI_ST_CON;
} }
/* needs src ip/port for logging */ /* needs src ip/port for logging */

View File

@ -626,10 +626,7 @@ static int sess_update_st_con_tcp(struct stream *s)
struct channel *req = &s->req; struct channel *req = &s->req;
struct channel *rep = &s->res; struct channel *rep = &s->res;
struct conn_stream *srv_cs = objt_cs(si->end); struct conn_stream *srv_cs = objt_cs(si->end);
struct connection *conn = NULL; struct connection *conn = srv_cs ? srv_cs->conn : objt_conn(si->end);
if (!srv_cs)
conn = objt_conn(si->end);
/* If we got an error, or if nothing happened and the connection timed /* 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 * 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->exp = TICK_ETERNITY;
si->state = SI_ST_CER; si->state = SI_ST_CER;
if (srv_cs) if (!(s->flags & SF_SRV_REUSED) && conn) {
conn = srv_cs->conn;
if (conn) {
conn_stop_tracking(conn); conn_stop_tracking(conn);
conn_full_close(conn); conn_full_close(conn);
} }