diff --git a/include/haproxy/stconn-t.h b/include/haproxy/stconn-t.h index ce0876ba0..951b79073 100644 --- a/include/haproxy/stconn-t.h +++ b/include/haproxy/stconn-t.h @@ -142,7 +142,7 @@ enum sc_flags { SC_FL_ISBACK = 0x00000001, /* Set for SC on back-side */ SC_FL_EOI = 0x00000002, /* End of input was reached. no more data will be received from the endpoint */ - /* not used: 0x00000004 */ + SC_FL_ERROR = 0x00000004, /* A fatal error was reported */ SC_FL_NOLINGER = 0x00000008, /* may close without lingering. One-shot. */ SC_FL_NOHALF = 0x00000010, /* no half close, close both sides at once */ @@ -174,11 +174,11 @@ static forceinline char *sc_show_flags(char *buf, size_t len, const char *delim, /* prologue */ _(0); /* flags */ - _(SC_FL_ISBACK, _(SC_FL_EOI, _(SC_FL_NOLINGER, _(SC_FL_NOHALF, + _(SC_FL_ISBACK, _(SC_FL_EOI, _(SC_FL_ERROR, _(SC_FL_NOLINGER, _(SC_FL_NOHALF, _(SC_FL_DONT_WAKE, _(SC_FL_INDEP_STR, _(SC_FL_WONT_READ, _(SC_FL_NEED_BUFF, _(SC_FL_NEED_ROOM, _(SC_FL_RCV_ONCE, _(SC_FL_SND_ASAP, _(SC_FL_SND_NEVERWAIT, _(SC_FL_SND_EXP_MORE, - _(SC_FL_ABRT_WANTED, _(SC_FL_SHUT_WANTED, _(SC_FL_ABRT_DONE, _(SC_FL_SHUT_DONE))))))))))))))))); + _(SC_FL_ABRT_WANTED, _(SC_FL_SHUT_WANTED, _(SC_FL_ABRT_DONE, _(SC_FL_SHUT_DONE)))))))))))))))))); /* epilogue */ _(~0U); return buf; diff --git a/src/cli.c b/src/cli.c index d8c3d44ab..5f859b93d 100644 --- a/src/cli.c +++ b/src/cli.c @@ -2830,7 +2830,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit) sockaddr_free(&s->scb->dst); sc_set_state(s->scb, SC_ST_INI); - s->scb->flags &= ~(SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED); + s->scb->flags &= ~(SC_FL_ERROR|SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED); s->scb->flags &= SC_FL_ISBACK | SC_FL_DONT_WAKE; /* we're in the context of process_stream */ s->req.flags &= ~(CF_AUTO_CONNECT|CF_STREAMER|CF_STREAMER_FAST|CF_WROTE_DATA); @@ -2855,7 +2855,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit) s->store_count = 0; s->uniq_id = global.req_count++; - s->scf->flags &= ~(SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED); + s->scf->flags &= ~(SC_FL_ERROR|SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED); s->scf->flags &= ~SC_FL_SND_NEVERWAIT; s->scf->flags |= SC_FL_RCV_ONCE; /* one read is usually enough */ diff --git a/src/http_ana.c b/src/http_ana.c index 4ec3a389b..bc9865a1e 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -1144,7 +1144,7 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc) res->analyse_exp = TICK_ETERNITY; res->total = 0; - s->scb->flags &= ~(SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED); + s->scb->flags &= ~(SC_FL_ERROR|SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED); if (sc_reset_endp(s->scb) < 0) { if (!(s->flags & SF_ERR_MASK)) s->flags |= SF_ERR_INTERNAL; diff --git a/src/stconn.c b/src/stconn.c index ceb429b38..c60afcc39 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -1482,8 +1482,10 @@ static int sc_conn_recv(struct stconn *sc) ret = 1; } - if (sc_ep_test(sc, SE_FL_ERROR)) + if (sc_ep_test(sc, SE_FL_ERROR)) { + sc->flags |= SC_FL_ERROR; ret = 1; + } else if (!(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)) && !(sc->flags & SC_FL_ABRT_DONE)) { /* Subscribe to receive events if we're blocking on I/O */ @@ -1663,6 +1665,8 @@ static int sc_conn_send(struct stconn *sc) if (sc_ep_test(sc, SE_FL_ERROR | SE_FL_ERR_PENDING)) { oc->flags |= CF_WRITE_EVENT; BUG_ON(sc_ep_test(sc, SE_FL_EOS|SE_FL_ERROR|SE_FL_ERR_PENDING) == (SE_FL_EOS|SE_FL_ERR_PENDING)); + if (sc_ep_test(sc, SE_FL_ERROR)) + sc_ep_set(sc, SC_FL_ERROR); return 1; } @@ -1734,8 +1738,10 @@ static int sc_conn_process(struct stconn *sc) */ if (sc->state >= SC_ST_CON) { - if (sc_is_conn_error(sc)) + if (sc_is_conn_error(sc)) { sc_ep_set(sc, SE_FL_ERROR); + sc->flags |= SC_FL_ERROR; + } } /* If we had early data, and the handshake ended, then @@ -1784,6 +1790,9 @@ static int sc_conn_process(struct stconn *sc) ic->flags |= CF_READ_EVENT; } + if (sc_ep_test(sc, SE_FL_ERROR)) + sc->flags |= SC_FL_ERROR; + /* Second step : update the stream connector and channels, try to forward any * pending data, then possibly wake the stream up based on the new * stream connector status. @@ -1836,6 +1845,9 @@ static int sc_applet_process(struct stconn *sc) ic->flags |= CF_READ_EVENT; } + if (sc_ep_test(sc, SE_FL_ERROR)) + sc->flags |= SC_FL_ERROR; + if (sc_ep_test(sc, SE_FL_EOS)) { /* we received a shutdown */ sc_abort(sc);