diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index 91ef26c5c..43353c367 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -234,6 +234,7 @@ struct stream { * This is a bit field of TASK_WOKEN_* */ int conn_retries; /* number of connect retries performed */ unsigned int conn_exp; /* wake up time for connect, queue, turn-around, ... */ + unsigned int max_retries; /* Maximum number of connection retried (=0 is backend is not set) */ unsigned int conn_err_type; /* first error detected, one of STRM_ET_* */ struct stream *parent; /* Pointer to the parent stream, if any. NULL most of time */ diff --git a/include/haproxy/stream.h b/include/haproxy/stream.h index e806a2a6f..308fb6904 100644 --- a/include/haproxy/stream.h +++ b/include/haproxy/stream.h @@ -350,7 +350,7 @@ static inline void stream_choose_redispatch(struct stream *s) (((s->be->redispatch_after > 0) && (s->conn_retries % s->be->redispatch_after == 0)) || ((s->be->redispatch_after < 0) && - (s->conn_retries % (s->be->conn_retries + 1 + s->be->redispatch_after) == 0))) || + (s->conn_retries % (s->max_retries + 1 + s->be->redispatch_after) == 0))) || (!(s->flags & SF_DIRECT) && s->be->srv_act > 1 && ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI)))) { sess_change_server(s, NULL); diff --git a/src/backend.c b/src/backend.c index e4bd465e9..b2f924c27 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1324,7 +1324,7 @@ static int do_connect_server(struct stream *s, struct connection *conn) if (co_data(&s->res)) conn_flags |= CONNECT_HAS_DATA; - if (s->conn_retries == s->be->conn_retries) + if (s->conn_retries == s->max_retries) conn_flags |= CONNECT_CAN_USE_TFO; if (!conn_ctrl_ready(conn) || !conn_xprt_ready(conn)) { ret = conn->ctrl->connect(conn, conn_flags); @@ -2402,13 +2402,13 @@ void back_handle_st_cer(struct stream *s) * provided by the client and we don't want to let the * client provoke retries. */ - s->conn_retries = s->be->conn_retries; + s->conn_retries = s->max_retries; DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s); } } /* ensure that we have enough retries left */ - if (s->conn_retries >= s->be->conn_retries || !(s->be->retry_type & PR_RE_CONN_FAILED)) { + if (s->conn_retries >= s->max_retries || !(s->be->retry_type & PR_RE_CONN_FAILED)) { if (!s->conn_err_type) { s->conn_err_type = STRM_ET_CONN_ERR; } diff --git a/src/http_ana.c b/src/http_ana.c index a8d1b18fc..d132e5de2 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -1142,7 +1142,7 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc) struct channel *req, *res; int co_data; - if (s->conn_retries >= s->be->conn_retries) + if (s->conn_retries >= s->max_retries) return -1; s->conn_retries++; if (objt_server(s->target)) { diff --git a/src/stream.c b/src/stream.c index f689edd76..d0623a9ad 100644 --- a/src/stream.c +++ b/src/stream.c @@ -430,7 +430,7 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer s->task = t; s->pending_events = 0; - s->conn_retries = 0; + s->conn_retries = s->max_retries = 0; s->conn_exp = TICK_ETERNITY; s->conn_err_type = STRM_ET_NONE; s->prev_conn_state = SC_ST_INI; @@ -1123,6 +1123,9 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an } + /* Se the max connection retries for the stream. */ + s->max_retries = s->be->conn_retries; + /* we don't want to run the TCP or HTTP filters again if the backend has not changed */ if (fe == s->be) { s->req.analysers &= ~AN_REQ_INSPECT_BE;