diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index 3fd5090fb..0fb5e7a8b 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -80,7 +80,7 @@ #define SF_SRV_REUSED 0x00100000 /* the server-side connection was reused */ #define SF_SRV_REUSED_ANTICIPATED 0x00200000 /* the connection was reused but the mux is not ready yet */ -#define SF_WEBSOCKET 0x00400000 /* websocket stream */ +#define SF_WEBSOCKET 0x00400000 /* websocket stream */ // TODO: must be removed /* flags for the proxy of the master CLI */ /* 0x0001.. to 0x8000 are reserved for ACCESS_* flags from cli-t.h */ @@ -139,6 +139,8 @@ struct stream { int16_t priority_class; /* priority class of the stream for the pending queue */ int32_t priority_offset; /* priority offset of the stream for the pending queue */ + int conn_retries; /* number of connect retries left */ + struct list list; /* position in the thread's streams list */ struct mt_list by_srv; /* position in server stream list */ struct list back_refs; /* list of users tracking this stream */ diff --git a/include/haproxy/stream.h b/include/haproxy/stream.h index 8024fcee6..93093f74e 100644 --- a/include/haproxy/stream.h +++ b/include/haproxy/stream.h @@ -331,10 +331,10 @@ static inline void stream_choose_redispatch(struct stream *s) (s->be->options & PR_O_REDISP) && !(s->flags & SF_FORCE_PRST) && ((__objt_server(s->target)->cur_state < SRV_ST_RUNNING) || (((s->be->redispatch_after > 0) && - ((s->be->conn_retries - si->conn_retries) % + ((s->be->conn_retries - s->conn_retries) % s->be->redispatch_after == 0)) || ((s->be->redispatch_after < 0) && - ((s->be->conn_retries - si->conn_retries) % + ((s->be->conn_retries - s->conn_retries) % (s->be->conn_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_RR)))) { diff --git a/include/haproxy/stream_interface-t.h b/include/haproxy/stream_interface-t.h index 2e6ef3977..8ed3d4ed0 100644 --- a/include/haproxy/stream_interface-t.h +++ b/include/haproxy/stream_interface-t.h @@ -135,7 +135,6 @@ struct stream_interface { /* struct members below are the "remote" part, as seen from the buffer side */ unsigned int err_type; /* first error detected, one of SI_ET_* */ - int conn_retries; /* number of connect retries left */ unsigned int hcto; /* half-closed timeout (0 = unset) */ struct wait_event wait_event; /* We're in a wait list */ diff --git a/include/haproxy/stream_interface.h b/include/haproxy/stream_interface.h index 60efe1de3..33d5e19f5 100644 --- a/include/haproxy/stream_interface.h +++ b/include/haproxy/stream_interface.h @@ -110,7 +110,6 @@ static inline int si_init(struct stream_interface *si) si->src = NULL; si->dst = NULL; si->err_type = SI_ET_NONE; - si->conn_retries = 0; /* used for logging too */ si->exp = TICK_ETERNITY; si->flags &= SI_FL_ISBACK; si->cs = NULL; @@ -376,7 +375,7 @@ static inline int si_connect(struct stream_interface *si, struct connection *con if (!channel_is_empty(si_oc(si))) conn_flags |= CONNECT_HAS_DATA; - if (si->conn_retries == si_strm(si)->be->conn_retries) + if (si_strm(si)->conn_retries == si_strm(si)->be->conn_retries) conn_flags |= CONNECT_CAN_USE_TFO; if (!conn_ctrl_ready(conn) || !conn_xprt_ready(conn)) { ret = conn->ctrl->connect(conn, conn_flags); diff --git a/src/backend.c b/src/backend.c index a23aecf9b..d2d04d986 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1721,7 +1721,7 @@ skip_reuse: */ ((cli_conn->flags & CO_FL_EARLY_DATA) || ((s->be->retry_type & PR_RE_EARLY_ERROR) && - cs_si(s->csb)->conn_retries == s->be->conn_retries)) && + s->conn_retries == s->be->conn_retries)) && !channel_is_empty(cs_oc(s->csb)) && srv_conn->flags & CO_FL_SSL_WAIT_HS) srv_conn->flags &= ~(CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN); @@ -2251,14 +2251,14 @@ void back_handle_st_cer(struct stream *s) * provided by the client and we don't want to let the * client provoke retries. */ - cs->si->conn_retries = 0; + s->conn_retries = 0; DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s); } } /* ensure that we have enough retries left */ - cs->si->conn_retries--; - if (cs->si->conn_retries < 0 || !(s->be->retry_type & PR_RE_CONN_FAILED)) { + s->conn_retries--; + if (s->conn_retries < 0 || !(s->be->retry_type & PR_RE_CONN_FAILED)) { if (!cs->si->err_type) { cs->si->err_type = SI_ET_CONN_ERR; } diff --git a/src/cli.c b/src/cli.c index 8ebd89673..f3d05d800 100644 --- a/src/cli.c +++ b/src/cli.c @@ -2768,7 +2768,6 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit) cs_si(s->csb)->state = cs_si(s->csb)->prev_state = SI_ST_INI; cs_si(s->csb)->err_type = SI_ET_NONE; - cs_si(s->csb)->conn_retries = 0; /* used for logging too */ cs_si(s->csb)->exp = TICK_ETERNITY; cs_si(s->csb)->flags &= SI_FL_ISBACK | SI_FL_DONT_WAKE; /* we're in the context of process_stream */ s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WROTE_DATA); @@ -2776,6 +2775,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit) s->flags &= ~(SF_DIRECT|SF_ASSIGNED|SF_ADDR_SET|SF_BE_ASSIGNED|SF_FORCE_PRST|SF_IGNORE_PRST); s->flags &= ~(SF_CURR_SESS|SF_REDIRECTABLE|SF_SRV_REUSED); s->flags &= ~(SF_ERR_MASK|SF_FINST_MASK|SF_REDISP); + s->conn_retries = 0; /* used for logging too */ /* reinitialise the current rule list pointer to NULL. We are sure that * any rulelist match the NULL pointer. */ diff --git a/src/http_ana.c b/src/http_ana.c index e56ee561c..7a72a0677 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -1226,8 +1226,8 @@ static __inline int do_l7_retry(struct stream *s, struct stream_interface *si) struct channel *req, *res; int co_data; - si->conn_retries--; - if (si->conn_retries < 0) + s->conn_retries--; + if (s->conn_retries < 0) return -1; if (objt_server(s->target)) { diff --git a/src/log.c b/src/log.c index cbb86e57b..c3b7d92ba 100644 --- a/src/log.c +++ b/src/log.c @@ -2616,8 +2616,8 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t case LOG_FMT_RETRIES: // %rq if (s_flags & SF_REDISP) LOGCHAR('+'); - ret = ltoa_o(((s && cs_si(s->csb)->conn_retries > 0) - ? (be->conn_retries - cs_si(s->csb)->conn_retries) + ret = ltoa_o(((s && s->conn_retries > 0) + ? (be->conn_retries - s->conn_retries) : ((s && cs_si(s->csb)->state != SI_ST_INI) ? be->conn_retries : 0)), tmplog, dst + maxsize - tmplog); if (ret == NULL) @@ -3080,7 +3080,7 @@ void strm_log(struct stream *s) err = (s->flags & SF_REDISP) || ((s->flags & SF_ERR_MASK) > SF_ERR_LOCAL) || (((s->flags & SF_ERR_MASK) == SF_ERR_NONE) && - (cs_si(s->csb)->conn_retries != s->be->conn_retries)) || + (s->conn_retries != s->be->conn_retries)) || ((sess->fe->mode == PR_MODE_HTTP) && s->txn && s->txn->status >= 500); if (!err && (sess->fe->options2 & PR_O2_NOLOGNORM)) diff --git a/src/stream.c b/src/stream.c index fe1e2c299..71460fe87 100644 --- a/src/stream.c +++ b/src/stream.c @@ -212,7 +212,7 @@ static void strm_trace(enum trace_level level, uint64_t mask, const struct trace else { chunk_appendf(&trace_buf, " - t=%p s=(%p,0x%08x) si_f=(%p,0x%08x,0x%x) si_b=(%p,0x%08x,0x%x) retries=%d", task, s, s->flags, si_f, si_f->flags, si_f->err_type, - si_b, si_b->flags, si_b->err_type, si_b->conn_retries); + si_b, si_b->flags, si_b->err_type, s->conn_retries); } if (src->verbosity == STRM_VERB_MINIMAL) @@ -420,6 +420,7 @@ struct stream *stream_new(struct session *sess, struct conn_stream *cs, struct b s->task = t; s->pending_events = 0; + s->conn_retries = 0; t->process = process_stream; t->context = s; t->expire = TICK_ETERNITY; @@ -2160,7 +2161,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) * perform a connection request. */ si_b->state = SI_ST_REQ; /* new connection requested */ - si_b->conn_retries = s->be->conn_retries; + s->conn_retries = s->be->conn_retries; if ((s->be->retry_type &~ PR_RE_CONN_FAILED) && (s->be->mode == PR_MODE_HTTP) && !(s->txn->flags & TX_D_L7_RETRY)) @@ -3154,7 +3155,7 @@ static int stats_dump_full_strm_to_buffer(struct conn_stream *cs, struct stream chunk_appendf(&trash, " flags=0x%x, conn_retries=%d, srv_conn=%p, pend_pos=%p waiting=%d epoch=%#x\n", - strm->flags, strm->csb->si->conn_retries, strm->srv_conn, strm->pend_pos, + strm->flags, strm->conn_retries, strm->srv_conn, strm->pend_pos, LIST_INLIST(&strm->buffer_wait.list), strm->stream_epoch); chunk_appendf(&trash,