MAJOR: channel: Remove flags to report READ or WRITE errors
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.
diff --git a/include/haproxy/channel-t.h b/include/haproxy/channel-t.h
index 287b712..ef4848b 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 @@
/* 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 82c583a..6e66e6c 100644
--- a/include/haproxy/sc_strm.h
+++ b/include/haproxy/sc_strm.h
@@ -85,16 +85,6 @@
}
-/* 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.
*/
diff --git a/src/backend.c b/src/backend.c
index 0e5dbfb..5a35bcc 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1953,7 +1953,7 @@
/* 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 @@
/* 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 @@
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 @@
/* 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 @@
/* 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 @@
/* 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 44ca4e8..c38efa0 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -2667,7 +2667,7 @@
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 @@
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 0b98dcf..92aeb3a 100644
--- a/src/filters.c
+++ b/src/filters.c
@@ -999,12 +999,6 @@
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 @@
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 @@
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 ba587df..3112491 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -785,7 +785,7 @@
*/
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 @@
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 @@
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 @@
}
/* 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 @@
/* 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 @@
/* 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 0b3147a..46cb163 100644
--- a/src/stconn.c
+++ b/src/stconn.c
@@ -846,12 +846,11 @@
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 @@
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 @@
/* 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 @@
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 @@
}
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 382aeda..4f964d8 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -905,14 +905,8 @@
/* 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 @@
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 @@
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 @@
*/
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 @@
_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 @@
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 @@
_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 @@
/* 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 15090e3..1d1ce7d 100644
--- a/src/tcp_rules.c
+++ b/src/tcp_rules.c
@@ -121,7 +121,7 @@
!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 @@
!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