MEDIUM: conn-stream: Use endpoint error instead of conn-stream error
Instead of relying on the conn-stream error, via CS_FL_ERR flags, we now
directly use the error at the endpoint level with the flag CS_EP_ERROR. It
should be safe to do so. But we must be careful because it is still possible
that an error is processed too early. Anyway, a conn-stream has always a
valid endpoint, maybe detached from any endpoint, but valid.
diff --git a/src/backend.c b/src/backend.c
index 7250aa9..5429e35 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1744,8 +1744,8 @@
* sockets, socket pairs, andoccasionally TCP connections on the
* loopback on a heavily loaded system.
*/
- if ((srv_conn->flags & CO_FL_ERROR || s->csb->endp->flags & CS_EP_ERROR))
- s->csb->flags |= CS_FL_ERR;
+ if (srv_conn->flags & CO_FL_ERROR)
+ s->csb->endp->flags |= CS_EP_ERROR;
/* If we had early data, and the handshake ended, then
* we can remove the flag, and attempt to wake the task up,
@@ -1964,7 +1964,7 @@
* allocation problem, so we want to retry now.
*/
cs->si->state = SI_ST_CER;
- cs->flags &= ~CS_FL_ERR;
+ cs->endp->flags &= ~CS_EP_ERROR;
back_handle_st_cer(s);
DBG_TRACE_STATE("connection error, retry", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
@@ -2187,9 +2187,9 @@
done:
/* retryable error ? */
- if ((s->flags & SF_CONN_EXP) || (cs->flags & CS_FL_ERR)) {
+ if ((s->flags & SF_CONN_EXP) || (cs->endp->flags & CS_EP_ERROR)) {
if (!cs->si->err_type) {
- if (cs->flags & CS_FL_ERR)
+ if (cs->endp->flags & CS_EP_ERROR)
cs->si->err_type = SI_ET_CONN_ERR;
else
cs->si->err_type = SI_ET_CONN_TO;
@@ -2215,6 +2215,7 @@
void back_handle_st_cer(struct stream *s)
{
struct conn_stream *cs = s->csb;
+ int must_tar = (cs->endp->flags & CS_EP_ERROR);
DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
@@ -2234,7 +2235,7 @@
_HA_ATOMIC_DEC(&__objt_server(s->target)->cur_sess);
}
- if ((cs->flags & CS_FL_ERR) &&
+ if ((cs->endp->flags & CS_EP_ERROR) &&
conn && conn->err_code == CO_ER_SSL_MISMATCH_SNI) {
/* We tried to connect to a server which is configured
* with "verify required" and which doesn't have the
@@ -2291,7 +2292,7 @@
* layers in an unexpected state (i.e < ST_CONN).
*
* Note: the stream-interface will be switched to ST_REQ, ST_ASS or
- * ST_TAR and CS_FL_ERR and SF_CONN_EXP flags will be unset.
+ * ST_TAR and CS_EP_ERROR and SF_CONN_EXP flags will be unset.
*/
if (cs_reset_endp(cs) < 0) {
if (!cs->si->err_type)
@@ -2319,7 +2320,7 @@
stream_choose_redispatch(s);
- if (cs->flags & CS_FL_ERR) {
+ if (must_tar) {
/* The error was an asynchronous connection error, and we will
* likely have to retry connecting to the same server, most
* likely leading to the same result. To avoid this, we wait
@@ -2345,7 +2346,6 @@
cs->si->state = SI_ST_TAR;
s->conn_exp = tick_add(now_ms, MS_TO_TICKS(delay));
}
- cs->flags &= ~CS_FL_ERR;
DBG_TRACE_STATE("retry a new connection", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
}
@@ -2401,7 +2401,7 @@
}
/* retryable error ? */
- if (cs->flags & CS_FL_ERR) {
+ if (cs->endp->flags & CS_EP_ERROR) {
if (!cs->si->err_type)
cs->si->err_type = SI_ET_CONN_ERR;
cs->si->state = SI_ST_CER;