diff --git a/include/haproxy/channel-t.h b/include/haproxy/channel-t.h index 287b712ac..ef4848bc3 100644 --- a/include/haproxy/channel-t.h +++ b/include/haproxy/channel-t.h @@ -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 */ @@ -120,7 +120,7 @@ #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; diff --git a/include/haproxy/sc_strm.h b/include/haproxy/sc_strm.h index 82c583a60..6e66e6c15 100644 --- a/include/haproxy/sc_strm.h +++ b/include/haproxy/sc_strm.h @@ -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 . This is * mainly used to create one in the established state on incoming conncetions. */ diff --git a/src/backend.c b/src/backend.c index 0e5dbfb2f..5a35bcc99 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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) diff --git a/src/cli.c b/src/cli.c index 44ca4e85c..c38efa03b 100644 --- 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); diff --git a/src/filters.c b/src/filters.c index 0b98dcf5b..92aeb3a73 100644 --- a/src/filters.c +++ b/src/filters.c @@ -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); diff --git a/src/http_ana.c b/src/http_ana.c index ba587df6d..311249123 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -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; diff --git a/src/stconn.c b/src/stconn.c index 0b3147a00..46cb16392 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -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; } diff --git a/src/stream.c b/src/stream.c index 382aeda49..4f964d87b 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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); } diff --git a/src/tcp_rules.c b/src/tcp_rules.c index 15090e3d2..1d1ce7d8c 100644 --- a/src/tcp_rules.c +++ b/src/tcp_rules.c @@ -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