mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-20 12:40:46 +00:00
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.
This commit is contained in:
parent
81fdeb8ce2
commit
2e56a73459
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
20
src/stconn.c
20
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;
|
||||
}
|
||||
|
||||
|
42
src/stream.c
42
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user