From: Christopher Faulet Date: Wed, 25 Sep 2024 13:05:07 +0000 (+0200) Subject: MINOR: stream: Rely on a per-stream max connection retries value X-Git-Tag: v3.1-dev9~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91e785edc;p=thirdparty%2Fhaproxy.git MINOR: stream: Rely on a per-stream max connection retries value Instead of directly relying on the backend parameter to limit the number of connection retries, we now use a per-stream value. This value is by default inherited from the backend value when it is set. So for now, there is no change except the stream value is used instead of the backend value. But thanks to this change, it will be possible to dynamically change this value. --- diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index 91ef26c5c6..43353c367f 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 e806a2a6f0..308fb69047 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 e4bd465e98..b2f924c278 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 a8d1b18fc3..d132e5de26 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 f689edd768..d0623a9adb 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;