]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MAJOR: channel: Remove flags to report READ or WRITE errors
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 26 Jan 2023 15:18:09 +0000 (16:18 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 22 Feb 2023 13:52:15 +0000 (14:52 +0100)
This patch removes CF_READ_ERROR and CF_WRITE_ERROR flags. We now rely on
SE_FL_ERR_PENDING and SE_FL_ERROR flags. SE_FL_ERR_PENDING is used for write
errors and SE_FL_ERROR for read or unrecoverable errors.

When a connection error is reported, SE_FL_ERROR and SE_FL_EOS are now set and a
read event and a write event are reported to be sure the stream will properly
process the error. At the stream-connector level, it is similar. When an error
is reported during a send, a write event is triggered. On the read side, nothing
more is performed because an error at this stage is enough to wake the stream
up.

A major change is brought with this patch. We stop to check flags of the
ooposite channel to report abort or timeout. It also means when an read or
write error is reported on a side, we no longer update the other side. Thus
a read error on the server side does no long lead to a write error on the
client side. This should ease errors report.

include/haproxy/channel-t.h
include/haproxy/sc_strm.h
src/backend.c
src/cli.c
src/filters.c
src/http_ana.c
src/stconn.c
src/stream.c
src/tcp_rules.c

index 287b712ac3bea35f15d6f005385d23e69ba6e7f5..ef4848bc3fba3712d58e8e0bdf625232f3e54bf1 100644 (file)
@@ -35,7 +35,7 @@
  *
  *   - pure status flags, reported by stream connector layer, which must also
  *     be cleared before doing further I/O :
- *     CF_*_TIMEOUT, CF_*_ERROR
+ *     CF_*_TIMEOUT
  *
  *   - read-only indicators reported by lower data levels :
  *     CF_STREAMER, CF_STREAMER_FAST
@@ -56,7 +56,7 @@
 #define CF_READ_EVENT     0x00000001  /* a read event detected on producer side */
 /* unused: 0x00000002 */
 #define CF_READ_TIMEOUT   0x00000004  /* timeout while waiting for producer */
-#define CF_READ_ERROR     0x00000008  /* unrecoverable error on producer side */
+/* unused 0x00000008 */
 
 /* unused: 0x00000010 */
 #define CF_SHUTR          0x00000020  /* producer has already shut down */
@@ -66,7 +66,7 @@
 #define CF_WRITE_EVENT    0x00000100  /* a write event detected on consumer side */
 /* unused: 0x00000200 */
 #define CF_WRITE_TIMEOUT  0x00000400  /* timeout while waiting for consumer */
-#define CF_WRITE_ERROR    0x00000800  /* unrecoverable error on consumer side */
+/* unused 0x00000800 */
 
 #define CF_WAKE_WRITE     0x00001000  /* wake the task up when there's write activity */
 #define CF_SHUTW          0x00002000  /* consumer has already shut down */
 #define CF_ISRESP         0x80000000  /* 0 = request channel, 1 = response channel */
 
 /* Masks which define input events for stream analysers */
-#define CF_MASK_ANALYSER  (CF_READ_EVENT|CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_EVENT|CF_WRITE_ERROR|CF_WAKE_ONCE)
+#define CF_MASK_ANALYSER  (CF_READ_EVENT|CF_READ_TIMEOUT|CF_WRITE_EVENT|CF_WAKE_ONCE)
 
 /* Mask for static flags which cause analysers to be woken up when they change */
 #define CF_MASK_STATIC    (CF_SHUTR|CF_SHUTW|CF_SHUTR_NOW|CF_SHUTW_NOW)
@@ -135,15 +135,15 @@ static forceinline char *chn_show_flags(char *buf, size_t len, const char *delim
        /* prologue */
        _(0);
        /* flags */
-       _(CF_READ_EVENT, _(CF_READ_TIMEOUT, _(CF_READ_ERROR,
+       _(CF_READ_EVENT, _(CF_READ_TIMEOUT,
        _(CF_SHUTR, _(CF_SHUTR_NOW, _(CF_WRITE_EVENT,
-       _(CF_WRITE_TIMEOUT, _(CF_WRITE_ERROR,
+       _(CF_WRITE_TIMEOUT,
        _(CF_WAKE_WRITE, _(CF_SHUTW, _(CF_SHUTW_NOW, _(CF_AUTO_CLOSE,
        _(CF_STREAMER, _(CF_STREAMER_FAST, _(CF_WROTE_DATA,
        _(CF_KERN_SPLICING, _(CF_READ_DONTWAIT,
        _(CF_AUTO_CONNECT, _(CF_DONT_READ, _(CF_EXPECT_MORE,
        _(CF_SEND_DONTWAIT, _(CF_NEVER_WAIT, _(CF_WAKE_ONCE, _(CF_FLT_ANALYZE,
-       _(CF_EOI, _(CF_ISRESP))))))))))))))))))))))))));
+       _(CF_EOI, _(CF_ISRESP))))))))))))))))))))))));
        /* epilogue */
        _(~0U);
        return buf;
index 82c583a6052cf621626d94581980815857edd4f6..6e66e6c15c3427dcf0a774f4febd9c508e560c42 100644 (file)
@@ -85,16 +85,6 @@ static inline struct stconn *sc_opposite(const struct stconn *sc)
 }
 
 
-/* to be called only when in SC_ST_DIS with SC_FL_ERR */
-static inline void sc_report_error(struct stconn *sc)
-{
-       if (!__sc_strm(sc)->conn_err_type)
-               __sc_strm(sc)->conn_err_type = STRM_ET_DATA_ERR;
-
-       sc_oc(sc)->flags |= CF_WRITE_ERROR;
-       sc_ic(sc)->flags |= CF_READ_ERROR;
-}
-
 /* sets the current and previous state of a stream connector to <state>. This is
  * mainly used to create one in the established state on incoming conncetions.
  */
index 0e5dbfb2f510d824231a994d384ce8725476d20b..5a35bcc99f81ae7668326eb3ba9c5458053050cd 100644 (file)
@@ -1953,7 +1953,7 @@ int srv_redispatch_connect(struct stream *s)
 /* Check if the connection request is in such a state that it can be aborted. */
 static int back_may_abort_req(struct channel *req, struct stream *s)
 {
-       return ((req->flags & (CF_READ_ERROR)) ||
+       return (sc_ep_test(s->scf, SE_FL_ERROR) ||
                ((req->flags & (CF_SHUTW_NOW|CF_SHUTW)) &&  /* empty and client aborted */
                 (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE))));
 }
@@ -2022,7 +2022,8 @@ void back_try_conn_req(struct stream *s)
                        /* Failed and not retryable. */
                        sc_shutr(sc);
                        sc_shutw(sc);
-                       req->flags |= CF_WRITE_ERROR;
+                       sc_ep_set(sc, SE_FL_ERROR|SE_FL_EOS);
+                       req->flags |= CF_WRITE_EVENT;
 
                        s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
 
@@ -2182,7 +2183,8 @@ void back_handle_st_req(struct stream *s)
 
                        sc_shutr(sc);
                        sc_shutw(sc);
-                       s->req.flags |= CF_WRITE_ERROR;
+                       sc_ep_set(sc, SE_FL_ERROR|SE_FL_EOS);
+                       s->req.flags |= CF_WRITE_EVENT;
                        s->conn_err_type = STRM_ET_CONN_RES;
                        sc->state = SC_ST_CLO;
                        if (s->srv_error)
@@ -2208,7 +2210,8 @@ void back_handle_st_req(struct stream *s)
                /* we did not get any server, let's check the cause */
                sc_shutr(sc);
                sc_shutw(sc);
-               s->req.flags |= CF_WRITE_ERROR;
+               sc_ep_set(sc, SE_FL_ERROR|SE_FL_EOS);
+               s->req.flags |= CF_WRITE_EVENT;
                if (!s->conn_err_type)
                        s->conn_err_type = STRM_ET_CONN_OTHER;
                sc->state = SC_ST_CLO;
@@ -2343,8 +2346,9 @@ void back_handle_st_cer(struct stream *s)
 
                /* shutw is enough to stop a connecting socket */
                sc_shutw(sc);
-               s->req.flags |= CF_WRITE_ERROR;
-               s->res.flags |= CF_READ_ERROR;
+               sc_ep_set(sc, SE_FL_ERROR|SE_FL_EOS);
+               s->req.flags |= CF_WRITE_EVENT;
+               s->res.flags |= CF_READ_EVENT;
 
                sc->state = SC_ST_CLO;
                if (s->srv_error)
@@ -2377,8 +2381,9 @@ void back_handle_st_cer(struct stream *s)
 
                /* shutw is enough to stop a connecting socket */
                sc_shutw(sc);
-               s->req.flags |= CF_WRITE_ERROR;
-               s->res.flags |= CF_READ_ERROR;
+               sc_ep_set(sc, SE_FL_ERROR|SE_FL_EOS);
+               s->req.flags |= CF_WRITE_EVENT;
+               s->res.flags |= CF_READ_EVENT;
 
                sc->state = SC_ST_CLO;
                if (s->srv_error)
index 44ca4e85c0cb7220f2c073591c793da28a72018f..c38efa03b2a963848d85f232893b3fa482da1106 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2667,7 +2667,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
        struct proxy *fe = strm_fe(s);
        struct proxy *be = s->be;
 
-       if ((rep->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) ||
+       if (sc_ep_test(s->scb, SE_FL_ERR_PENDING|SE_FL_ERROR) || (rep->flags & (CF_READ_TIMEOUT|CF_WRITE_TIMEOUT)) ||
            ((rep->flags & CF_SHUTW) && (rep->to_forward || co_data(rep)))) {
                pcli_reply_and_close(s, "Can't connect to the target CLI!\n");
                s->req.analysers &= ~AN_REQ_WAIT_CLI;
@@ -2783,8 +2783,8 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
 
                sc_set_state(s->scb, SC_ST_INI);
                s->scb->flags &= SC_FL_ISBACK | SC_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);
-               s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_READ_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_EVENT|CF_NEVER_WAIT|CF_WROTE_DATA|CF_READ_EVENT);
+               s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WROTE_DATA);
+               s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_EVENT|CF_NEVER_WAIT|CF_WROTE_DATA|CF_READ_EVENT);
                s->flags &= ~(SF_DIRECT|SF_ASSIGNED|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);
index 0b98dcf5b99880a8a5caf3aed48e7354b4ad4fef..92aeb3a73509ea6cb2a3a9c8e612f55f485e7e62 100644 (file)
@@ -999,12 +999,6 @@ flt_xfer_data(struct stream *s, struct channel *chn, unsigned int an_bit)
        if (!HAS_DATA_FILTERS(s, chn))
                goto end;
 
-       /* Be sure that the output is still opened. Else we stop the data
-        * filtering. */
-       if ((chn->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) ||
-           ((chn->flags & CF_SHUTW) && (chn->to_forward || co_data(chn))))
-               goto end;
-
        if (s->flags & SF_HTX) {
                struct htx *htx = htxbuf(&chn->buf);
                len = htx->data;
@@ -1017,8 +1011,11 @@ flt_xfer_data(struct stream *s, struct channel *chn, unsigned int an_bit)
                goto end;
        c_adv(chn, ret);
 
-       /* Stop waiting data if the input in closed and no data is pending or if
-        * the output is closed. */
+       /* Stop waiting data if:
+        *  - it the output is closed
+        *  - the input in closed and no data is pending
+        *  - There is a READ/WRITE timeout
+        */
        if (chn->flags & CF_SHUTW) {
                ret = 1;
                goto end;
@@ -1029,6 +1026,10 @@ flt_xfer_data(struct stream *s, struct channel *chn, unsigned int an_bit)
                        goto end;
                }
        }
+       if (chn->flags & (CF_READ_TIMEOUT|CF_WRITE_TIMEOUT)) {
+               ret = 1;
+               goto end;
+       }
 
        /* Wait for data */
        DBG_TRACE_DEVEL("waiting for more data", STRM_EV_STRM_ANA|STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
index ba587df6dcf0c62a6fe5768072d3173fb692321c..31124912380b5b02617741ca5679fee9d8b1d25f 100644 (file)
@@ -785,7 +785,7 @@ int http_process_tarpit(struct stream *s, struct channel *req, int an_bit)
         */
        s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
 
-       http_reply_and_close(s, txn->status, (!(req->flags & CF_READ_ERROR) ? http_error_message(s) : NULL));
+       http_reply_and_close(s, txn->status, (!sc_ep_test(s->scf, SE_FL_ERROR) ? http_error_message(s) : NULL));
        http_set_term_flags(s);
 
        DBG_TRACE_LEAVE(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA, s, txn);
@@ -1134,8 +1134,8 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc)
        req = &s->req;
        res = &s->res;
        /* Remove any write error from the request, and read error from the response */
-       req->flags &= ~(CF_WRITE_ERROR | CF_WRITE_TIMEOUT | CF_SHUTW | CF_SHUTW_NOW);
-       res->flags &= ~(CF_READ_ERROR | CF_READ_TIMEOUT | CF_SHUTR | CF_EOI | CF_READ_EVENT | CF_SHUTR_NOW);
+       req->flags &= ~(CF_WRITE_TIMEOUT | CF_SHUTW | CF_SHUTW_NOW);
+       res->flags &= ~(CF_READ_TIMEOUT | CF_SHUTR | CF_EOI | CF_READ_EVENT | CF_SHUTR_NOW);
        res->analysers &= AN_RES_FLT_END;
        s->conn_err_type = STRM_ET_NONE;
        s->flags &= ~(SF_CONN_EXP | SF_ERR_MASK | SF_FINST_MASK);
@@ -1216,7 +1216,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
   next_one:
        if (unlikely(htx_is_empty(htx) || htx->first == -1)) {
                /* 1: have we encountered a read error ? */
-               if (rep->flags & CF_READ_ERROR) {
+               if (sc_ep_test(s->scb, SE_FL_ERROR)) {
                        struct connection *conn = sc_conn(s->scb);
 
                        /* Perform a L7 retry because server refuses the early data. */
@@ -1342,7 +1342,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
                }
 
                /* 5: write error to client (we don't send any message then) */
-               else if (rep->flags & CF_WRITE_ERROR) {
+               else if (sc_ep_test(s->scf, SE_FL_ERR_PENDING)) {
                        if (txn->flags & TX_NOT_FIRST)
                                goto abort_keep_alive;
 
@@ -2663,7 +2663,7 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
 
                /* Always call the action function if defined */
                if (rule->action_ptr) {
-                       if ((s->req.flags & CF_READ_ERROR) ||
+                       if (sc_ep_test(s->scf, SE_FL_ERROR) ||
                            ((s->req.flags & CF_SHUTR) &&
                             (px->options & PR_O_ABRT_CLOSE)))
                                act_opts |= ACT_OPT_FINAL;
@@ -2826,7 +2826,7 @@ resume_execution:
 
                /* Always call the action function if defined */
                if (rule->action_ptr) {
-                       if ((s->req.flags & CF_READ_ERROR) ||
+                       if (sc_ep_test(s->scf, SE_FL_ERROR) ||
                            ((s->req.flags & CF_SHUTR) &&
                             (px->options & PR_O_ABRT_CLOSE)))
                                act_opts |= ACT_OPT_FINAL;
index 0b3147a00f8528208a2b107a3ce97b803c689bb5..46cb1639218b07d9430f99e63349eb93ff11b1d8 100644 (file)
@@ -846,12 +846,11 @@ static void sc_app_chk_snd_conn(struct stconn *sc)
                        oc->wex = tick_add_ifset(now_ms, oc->wto);
        }
 
-       if (likely(oc->flags & (CF_WRITE_EVENT|CF_WRITE_ERROR))) {
+       if (likely(oc->flags & CF_WRITE_EVENT)) {
                struct channel *ic = sc_ic(sc);
 
                /* update timeout if we have written something */
-               if ((oc->flags & (CF_SHUTW|CF_WRITE_EVENT)) == CF_WRITE_EVENT &&
-                   !channel_is_empty(oc))
+               if (!(oc->flags & CF_SHUTW) && !channel_is_empty(oc))
                        oc->wex = tick_add_ifset(now_ms, oc->wto);
 
                if (tick_isset(ic->rex) && !(sc->flags & SC_FL_INDEP_STR)) {
@@ -1133,8 +1132,8 @@ static void sc_notify(struct stconn *sc)
                sc_ep_clr(sc, SE_FL_WAIT_DATA);
 
        /* update OC timeouts and wake the other side up if it's waiting for room */
-       if (oc->flags & (CF_WRITE_EVENT|CF_WRITE_ERROR)) {
-               if (!(oc->flags & CF_WRITE_ERROR) &&
+       if (oc->flags & (CF_WRITE_EVENT)) {
+               if (sc_ep_test(sc, SE_FL_ERR_PENDING|SE_FL_ERROR) &&
                    !channel_is_empty(oc))
                        if (tick_isset(oc->wex))
                                oc->wex = tick_add_ifset(now_ms, oc->wto);
@@ -1201,17 +1200,17 @@ static void sc_notify(struct stconn *sc)
 
        /* wake the task up only when needed */
        if (/* changes on the production side that must be handled:
-            *  - An error on receipt: CF_READ_ERROR or SE_FL_ERROR
+            *  - An error on receipt: SE_FL_ERROR
             *  - A read event: shutdown for reads (CF_READ_EVENT + SHUTR)
             *                  end of input (CF_READ_EVENT + CF_EOI)
             *                  data received and no fast-forwarding (CF_READ_EVENT + !to_forward)
             *                  read event while consumer side is not established (CF_READ_EVENT + sco->state != SC_ST_EST)
             */
            ((ic->flags & CF_READ_EVENT) && ((ic->flags & (CF_SHUTR|CF_EOI)) || !ic->to_forward || sco->state != SC_ST_EST)) ||
-           (ic->flags & CF_READ_ERROR) || sc_ep_test(sc, SE_FL_ERROR) ||
+           sc_ep_test(sc, SE_FL_ERROR) ||
 
            /* changes on the consumption side */
-           (oc->flags & CF_WRITE_ERROR) ||
+           sc_ep_test(sc, SE_FL_ERR_PENDING) ||
            ((oc->flags & CF_WRITE_EVENT) &&
             ((sc->state < SC_ST_EST) ||
              (oc->flags & CF_SHUTW) ||
@@ -1233,7 +1232,7 @@ static void sc_notify(struct stconn *sc)
 
                task_queue(task);
        }
-       if (ic->flags & (CF_READ_EVENT|CF_READ_ERROR))
+       if (ic->flags & CF_READ_EVENT)
                ic->flags &= ~CF_READ_DONTWAIT;
 }
 
@@ -1777,8 +1776,9 @@ 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;
                if (sc_ep_test(sc, SE_FL_EOS))
-                   sc_ep_set(sc, SE_FL_ERROR);
+                       sc_ep_set(sc, SE_FL_ERROR);
                return 1;
        }
 
index 382aeda49d9906703bb3875b0b444809cc4bcd47..4f964d87b80312552285bc058c62ffc6f758ca08 100644 (file)
@@ -905,14 +905,8 @@ static void back_establish(struct stream *s)
 
        /* errors faced after sending data need to be reported */
        if (sc_ep_test(s->scb, SE_FL_ERROR) && req->flags & CF_WROTE_DATA) {
-               /* Don't add CF_WRITE_ERROR if we're here because
-                * early data were rejected by the server, or
-                * http_wait_for_response() will never be called
-                * to send a 425.
-                */
-               if (conn && conn->err_code != CO_ER_SSL_EARLY_FAILED)
-                       req->flags |= CF_WRITE_ERROR;
-               rep->flags |= CF_READ_ERROR;
+               s->req.flags |= CF_WRITE_EVENT;
+               s->res.flags |= CF_READ_EVENT;
                s->conn_err_type = STRM_ET_DATA_ERR;
                DBG_TRACE_STATE("read/write error", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
        }
@@ -1826,7 +1820,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                if (sc_state_in(scf->state, SC_SB_EST|SC_SB_DIS)) {
                        sc_shutr(scf);
                        sc_shutw(scf);
-                       sc_report_error(scf);
+                       //sc_report_error(scf); TODO: Be sure it is useless
                        if (!(req->analysers) && !(res->analysers)) {
                                _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
                                _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
@@ -1846,7 +1840,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                if (sc_state_in(scb->state, SC_SB_EST|SC_SB_DIS)) {
                        sc_shutr(scb);
                        sc_shutw(scb);
-                       sc_report_error(scb);
+                       //sc_report_error(scb); TODO: Be sure it is useless
                        _HA_ATOMIC_INC(&s->be->be_counters.failed_resp);
                        if (srv)
                                _HA_ATOMIC_INC(&srv->counters.failed_resp);
@@ -2131,10 +2125,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
         */
        srv = objt_server(s->target);
        if (unlikely(!(s->flags & SF_ERR_MASK))) {
-               if (req->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
+               if (sc_ep_test(s->scf, SE_FL_ERROR) || req->flags & (CF_READ_TIMEOUT|CF_WRITE_TIMEOUT)) {
                        /* Report it if the client got an error or a read timeout expired */
                        req->analysers &= AN_REQ_FLT_END;
-                       if (req->flags & CF_READ_ERROR) {
+                       if (sc_ep_test(s->scf, SE_FL_ERROR)) {
                                _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
                                _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
                                if (sess->listener && sess->listener->counters)
@@ -2152,15 +2146,6 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                        _HA_ATOMIC_INC(&srv->counters.cli_aborts);
                                s->flags |= SF_ERR_CLITO;
                        }
-                       else if (req->flags & CF_WRITE_ERROR) {
-                               _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
-                               if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->srv_aborts);
-                               if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.srv_aborts);
-                               s->flags |= SF_ERR_SRVCL;
-                       }
                        else {
                                _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
                                _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
@@ -2185,10 +2170,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                        channel_erase(req);
                        }
                }
-               else if (res->flags & (CF_READ_ERROR|CF_READ_TIMEOUT|CF_WRITE_ERROR|CF_WRITE_TIMEOUT)) {
+               else if (sc_ep_test(s->scb, SE_FL_ERROR) || res->flags & (CF_READ_TIMEOUT|CF_WRITE_TIMEOUT)) {
                        /* Report it if the server got an error or a read timeout expired */
                        res->analysers &= AN_RES_FLT_END;
-                       if (res->flags & CF_READ_ERROR) {
+                       if (sc_ep_test(s->scb, SE_FL_ERROR)) {
                                _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
                                _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
                                if (sess->listener && sess->listener->counters)
@@ -2206,15 +2191,6 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                        _HA_ATOMIC_INC(&srv->counters.srv_aborts);
                                s->flags |= SF_ERR_SRVTO;
                        }
-                       else if (res->flags & CF_WRITE_ERROR) {
-                               _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
-                               if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->cli_aborts);
-                               if (srv)
-                                       _HA_ATOMIC_INC(&srv->counters.cli_aborts);
-                               s->flags |= SF_ERR_CLICL;
-                       }
                        else {
                                _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
                                _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
@@ -2376,7 +2352,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
        /* shutdown(write) pending */
        if (unlikely((req->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
                     channel_is_empty(req))) {
-               if (req->flags & CF_READ_ERROR)
+               if (sc_ep_test(s->scf, SE_FL_ERROR))
                        scb->flags |= SC_FL_NOLINGER;
                sc_shutw(scb);
        }
index 15090e3d2de0e57a09e501542534ccf1201aab82..1d1ce7d8cafd68d05a77bb47c8093b082d57571d 100644 (file)
@@ -121,7 +121,7 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit)
            !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
                partial = SMP_OPT_FINAL;
                /* Action may yield while the inspect_delay is not expired and there is no read error */
-               if ((req->flags & CF_READ_ERROR) || !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
+               if (sc_ep_test(s->scf, SE_FL_ERROR) || !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
                        act_opts |= ACT_OPT_FINAL;
        }
        else
@@ -304,7 +304,7 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit)
            !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
                partial = SMP_OPT_FINAL;
                /* Action may yield while the inspect_delay is not expired and there is no read error */
-               if ((rep->flags & CF_READ_ERROR) || !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
+               if (sc_ep_test(s->scb, SE_FL_ERROR) || !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms))
                        act_opts |= ACT_OPT_FINAL;
        }
        else