mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-27 05:41:10 +01:00
MINOR: stconn: Rename SC_FL_SHUTR in SC_FL_ABRT_DONE
Here again, it is just a flag renaming. In SC flags, there is no longer shutdown for reads but aborts. For now this flag is set when a read0 is detected. It is of couse not accurate. This will be changed later.
This commit is contained in:
parent
df7cd710a8
commit
0c370eee6d
@ -514,7 +514,7 @@ static inline int channel_may_recv(const struct channel *chn)
|
||||
/* Returns true if the channel's input is already closed */
|
||||
static inline int channel_input_closed(struct channel *chn)
|
||||
{
|
||||
return ((chn_prod(chn)->flags & SC_FL_SHUTR) != 0);
|
||||
return ((chn_prod(chn)->flags & SC_FL_ABRT_DONE) != 0);
|
||||
}
|
||||
|
||||
/* Returns true if the channel's output is already closed */
|
||||
|
||||
@ -286,7 +286,7 @@ static inline void sc_shutw(struct stconn *sc)
|
||||
__attribute__((warn_unused_result))
|
||||
static inline int sc_is_recv_allowed(const struct stconn *sc)
|
||||
{
|
||||
if (sc->flags & SC_FL_SHUTR)
|
||||
if (sc->flags & SC_FL_ABRT_DONE)
|
||||
return 0;
|
||||
|
||||
if (sc_ep_test(sc, SE_FL_APPLET_NEED_CONN))
|
||||
@ -371,7 +371,7 @@ static inline int sc_is_send_allowed(const struct stconn *sc)
|
||||
|
||||
static inline int sc_rcv_may_expire(const struct stconn *sc)
|
||||
{
|
||||
if ((sc->flags & SC_FL_SHUTR) ||
|
||||
if ((sc->flags & SC_FL_ABRT_DONE) ||
|
||||
(sc_ic(sc)->flags & (CF_READ_TIMEOUT|CF_READ_EVENT)))
|
||||
return 0;
|
||||
if (sc->flags & (SC_FL_EOI|SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
|
||||
|
||||
@ -160,7 +160,7 @@ enum sc_flags {
|
||||
|
||||
SC_FL_ABRT_WANTED = 0x00002000, /* An abort was requested and must be performed ASAP */
|
||||
SC_FL_SHUT_WANTED = 0x00004000, /* A shutdown was requested and mux be performed ASAP */
|
||||
SC_FL_SHUTR = 0x00008000, /* SC is shut down for writes */
|
||||
SC_FL_ABRT_DONE = 0x00008000, /* An abort was performed for the SC */
|
||||
SC_FL_SHUTW = 0x00010000, /* SC must shut down for writes ASAP */
|
||||
};
|
||||
|
||||
@ -178,7 +178,7 @@ static forceinline char *sc_show_flags(char *buf, size_t len, const char *delim,
|
||||
_(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_SHUTR, _(SC_FL_SHUTW)))))))))))))))));
|
||||
_(SC_FL_ABRT_WANTED, _(SC_FL_SHUT_WANTED, _(SC_FL_ABRT_DONE, _(SC_FL_SHUTW)))))))))))))))));
|
||||
/* epilogue */
|
||||
_(~0U);
|
||||
return buf;
|
||||
|
||||
@ -484,7 +484,7 @@ int ci_getblk_nc(const struct channel *chn,
|
||||
char **blk2, size_t *len2)
|
||||
{
|
||||
if (unlikely(ci_data(chn) == 0)) {
|
||||
if (chn_prod(chn)->flags & SC_FL_SHUTR)
|
||||
if (chn_prod(chn)->flags & SC_FL_ABRT_DONE)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2692,7 +2692,7 @@ send_status:
|
||||
goto read_again;
|
||||
|
||||
missing_data:
|
||||
if (chn_prod(req)->flags & SC_FL_SHUTR) {
|
||||
if (chn_prod(req)->flags & SC_FL_ABRT_DONE) {
|
||||
/* There is no more request or a only a partial one and we
|
||||
* receive a close from the client, we can leave */
|
||||
sc_schedule_shutdown(s->scf);
|
||||
@ -2741,7 +2741,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (chn_prod(rep)->flags & SC_FL_SHUTR) {
|
||||
if (chn_prod(rep)->flags & SC_FL_ABRT_DONE) {
|
||||
/* stream cleanup */
|
||||
|
||||
pcli_write_prompt(s);
|
||||
@ -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_SHUTR|SC_FL_ABRT_WANTED);
|
||||
s->scf->flags &= ~(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 */
|
||||
|
||||
|
||||
@ -1020,7 +1020,7 @@ flt_xfer_data(struct stream *s, struct channel *chn, unsigned int an_bit)
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
if (chn_prod(chn)->flags & SC_FL_SHUTR) {
|
||||
if (chn_prod(chn)->flags & SC_FL_ABRT_DONE) {
|
||||
if (((s->flags & SF_HTX) && htx_is_empty(htxbuf(&chn->buf))) || c_empty(chn)) {
|
||||
ret = 1;
|
||||
goto end;
|
||||
|
||||
@ -151,7 +151,7 @@ static int bwlim_apply_limit(struct filter *filter, struct channel *chn, unsigne
|
||||
*/
|
||||
ret = tokens;
|
||||
if (tokens < conf->min_size) {
|
||||
ret = (chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_SHUTR))
|
||||
ret = (chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_ABRT_DONE))
|
||||
? MIN(len, conf->min_size)
|
||||
: conf->min_size;
|
||||
|
||||
|
||||
@ -111,10 +111,10 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
|
||||
/* Don't connect for now */
|
||||
channel_dont_connect(req);
|
||||
|
||||
/* A SHUTR at this stage means we are performing a "destructive"
|
||||
/* An abort at this stage means we are performing a "destructive"
|
||||
* HTTP upgrade (TCP>H2). In this case, we can leave.
|
||||
*/
|
||||
if (chn_prod(req)->flags & SC_FL_SHUTR) {
|
||||
if (chn_prod(req)->flags & SC_FL_ABRT_DONE) {
|
||||
s->logs.logwait = 0;
|
||||
s->logs.level = 0;
|
||||
stream_abort(s);
|
||||
@ -766,7 +766,7 @@ int http_process_tarpit(struct stream *s, struct channel *req, int an_bit)
|
||||
* there and that the timeout has not expired.
|
||||
*/
|
||||
channel_dont_connect(req);
|
||||
if (!(chn_prod(req)->flags & SC_FL_SHUTR) &&
|
||||
if (!(chn_prod(req)->flags & SC_FL_ABRT_DONE) &&
|
||||
!tick_is_expired(req->analyse_exp, now_ms)) {
|
||||
/* Be sure to drain all data from the request channel */
|
||||
channel_htx_erase(req, htxbuf(&req->buf));
|
||||
@ -1002,7 +1002,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
||||
* it can be abused to exhaust source ports. */
|
||||
if (s->be->options & PR_O_ABRT_CLOSE) {
|
||||
channel_auto_read(req);
|
||||
if ((chn_prod(req)->flags & SC_FL_SHUTR) && !(txn->flags & TX_CON_WANT_TUN))
|
||||
if ((chn_prod(req)->flags & SC_FL_ABRT_DONE) && !(txn->flags & TX_CON_WANT_TUN))
|
||||
s->scb->flags |= SC_FL_NOLINGER;
|
||||
channel_auto_close(req);
|
||||
}
|
||||
@ -1018,7 +1018,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
||||
|
||||
missing_data_or_waiting:
|
||||
/* stop waiting for data if the input is closed before the end */
|
||||
if (msg->msg_state < HTTP_MSG_ENDING && chn_prod(req)->flags & SC_FL_SHUTR)
|
||||
if (msg->msg_state < HTTP_MSG_ENDING && chn_prod(req)->flags & SC_FL_ABRT_DONE)
|
||||
goto return_cli_abort;
|
||||
|
||||
waiting:
|
||||
@ -1132,7 +1132,7 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc)
|
||||
res = &s->res;
|
||||
|
||||
/* Remove any write error from the request, and read error from the response */
|
||||
s->scf->flags &= ~(SC_FL_SHUTR|SC_FL_ABRT_WANTED);
|
||||
s->scf->flags &= ~(SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED);
|
||||
req->flags &= ~CF_WRITE_TIMEOUT;
|
||||
res->flags &= ~(CF_READ_TIMEOUT | CF_READ_EVENT);
|
||||
res->analysers &= AN_RES_FLT_END;
|
||||
@ -1294,8 +1294,8 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
}
|
||||
|
||||
/* 3: client abort with an abortonclose */
|
||||
else if ((chn_prod(rep)->flags & SC_FL_SHUTR) &&
|
||||
(chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||
else if ((chn_prod(rep)->flags & SC_FL_ABRT_DONE) &&
|
||||
(chn_prod(&s->req)->flags & SC_FL_ABRT_DONE) &&
|
||||
(chn_cons(&s->req)->flags & SC_FL_SHUTW)) {
|
||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
|
||||
_HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
|
||||
@ -1318,7 +1318,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
}
|
||||
|
||||
/* 4: close from server, capture the response if the server has started to respond */
|
||||
else if (chn_prod(rep)->flags & SC_FL_SHUTR) {
|
||||
else if (chn_prod(rep)->flags & SC_FL_ABRT_DONE) {
|
||||
if ((txn->flags & TX_L7_RETRY) &&
|
||||
(s->be->retry_type & PR_RE_DISCONNECTED)) {
|
||||
if (co_data(rep) || do_l7_retry(s, s->scb) == 0) {
|
||||
@ -2060,7 +2060,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
||||
if (htx->data != co_data(res))
|
||||
goto missing_data_or_waiting;
|
||||
|
||||
if (!(msg->flags & HTTP_MSGF_XFER_LEN) && (chn_prod(res)->flags & SC_FL_SHUTR)) {
|
||||
if (!(msg->flags & HTTP_MSGF_XFER_LEN) && (chn_prod(res)->flags & SC_FL_ABRT_DONE)) {
|
||||
msg->msg_state = HTTP_MSG_ENDING;
|
||||
goto ending;
|
||||
}
|
||||
@ -2128,8 +2128,8 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
||||
* so we don't want to count this as a server abort. Otherwise it's a
|
||||
* server abort.
|
||||
*/
|
||||
if (msg->msg_state < HTTP_MSG_ENDING && (chn_prod(res)->flags & SC_FL_SHUTR)) {
|
||||
if ((chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||
if (msg->msg_state < HTTP_MSG_ENDING && (chn_prod(res)->flags & SC_FL_ABRT_DONE)) {
|
||||
if ((chn_prod(&s->req)->flags & SC_FL_ABRT_DONE) &&
|
||||
(chn_cons(&s->req)->flags & SC_FL_SHUTW))
|
||||
goto return_cli_abort;
|
||||
/* If we have some pending data, we continue the processing */
|
||||
@ -2674,7 +2674,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 (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
||||
((chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||
((chn_prod(&s->req)->flags & SC_FL_ABRT_DONE) &&
|
||||
(px->options & PR_O_ABRT_CLOSE)))
|
||||
act_opts |= ACT_OPT_FINAL;
|
||||
|
||||
@ -2837,7 +2837,7 @@ resume_execution:
|
||||
/* Always call the action function if defined */
|
||||
if (rule->action_ptr) {
|
||||
if (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
||||
((chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||
((chn_prod(&s->req)->flags & SC_FL_ABRT_DONE) &&
|
||||
(px->options & PR_O_ABRT_CLOSE)))
|
||||
act_opts |= ACT_OPT_FINAL;
|
||||
|
||||
@ -4083,7 +4083,7 @@ enum rule_result http_wait_for_msg_body(struct stream *s, struct channel *chn,
|
||||
}
|
||||
|
||||
/* we get here if we need to wait for more data */
|
||||
if (!(chn_prod(chn)->flags & SC_FL_SHUTR)) {
|
||||
if (!(chn_prod(chn)->flags & SC_FL_ABRT_DONE)) {
|
||||
if (!tick_isset(chn->analyse_exp))
|
||||
chn->analyse_exp = tick_add_ifset(now_ms, time);
|
||||
ret = HTTP_RULE_RES_YIELD;
|
||||
|
||||
@ -615,7 +615,7 @@ static int smp_fetch_body(const struct arg *args, struct sample *smp, const char
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
|
||||
if (!finished && (check || (chn && !channel_full(chn, global.tune.maxrewrite) &&
|
||||
!(chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_SHUTR)))))
|
||||
!(chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_ABRT_DONE)))))
|
||||
smp->flags |= SMP_F_MAY_CHANGE;
|
||||
|
||||
return 1;
|
||||
|
||||
@ -4493,7 +4493,7 @@ static void http_stats_io_handler(struct appctx *appctx)
|
||||
if (appctx->st0 == STAT_HTTP_POST) {
|
||||
if (stats_process_http_post(sc))
|
||||
appctx->st0 = STAT_HTTP_LAST;
|
||||
else if (chn_prod(req)->flags & SC_FL_SHUTR)
|
||||
else if (chn_prod(req)->flags & SC_FL_ABRT_DONE)
|
||||
appctx->st0 = STAT_HTTP_DONE;
|
||||
}
|
||||
|
||||
|
||||
48
src/stconn.c
48
src/stconn.c
@ -507,7 +507,7 @@ struct appctx *sc_applet_create(struct stconn *sc, struct applet *app)
|
||||
static inline int sc_cond_forward_shutw(struct stconn *sc)
|
||||
{
|
||||
/* The close must not be forwarded */
|
||||
if (!(sc->flags & SC_FL_SHUTR) || !(sc->flags & SC_FL_NOHALF))
|
||||
if (!(sc->flags & SC_FL_ABRT_DONE) || !(sc->flags & SC_FL_NOHALF))
|
||||
return 0;
|
||||
|
||||
if (!channel_is_empty(sc_ic(sc))) {
|
||||
@ -534,10 +534,10 @@ static void sc_app_shutr(struct stconn *sc)
|
||||
{
|
||||
struct channel *ic = sc_ic(sc);
|
||||
|
||||
if (sc->flags & SC_FL_SHUTR)
|
||||
if (sc->flags & SC_FL_ABRT_DONE)
|
||||
return;
|
||||
|
||||
sc->flags |= SC_FL_SHUTR;
|
||||
sc->flags |= SC_FL_ABRT_DONE;
|
||||
ic->flags |= CF_READ_EVENT;
|
||||
sc_ep_report_read_activity(sc);
|
||||
|
||||
@ -586,7 +586,7 @@ static void sc_app_shutw(struct stconn *sc)
|
||||
* no risk so we close both sides immediately.
|
||||
*/
|
||||
if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
|
||||
!(sc->flags & SC_FL_SHUTR) && !(ic->flags & CF_DONT_READ))
|
||||
!(sc->flags & SC_FL_ABRT_DONE) && !(ic->flags & CF_DONT_READ))
|
||||
return;
|
||||
|
||||
__fallthrough;
|
||||
@ -599,7 +599,7 @@ static void sc_app_shutw(struct stconn *sc)
|
||||
__fallthrough;
|
||||
default:
|
||||
sc->flags &= ~SC_FL_NOLINGER;
|
||||
sc->flags |= SC_FL_SHUTR;
|
||||
sc->flags |= SC_FL_ABRT_DONE;
|
||||
if (sc->flags & SC_FL_ISBACK)
|
||||
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
||||
}
|
||||
@ -661,9 +661,9 @@ static void sc_app_shutr_conn(struct stconn *sc)
|
||||
|
||||
BUG_ON(!sc_conn(sc));
|
||||
|
||||
if (sc->flags & SC_FL_SHUTR)
|
||||
if (sc->flags & SC_FL_ABRT_DONE)
|
||||
return;
|
||||
sc->flags |= SC_FL_SHUTR;
|
||||
sc->flags |= SC_FL_ABRT_DONE;
|
||||
ic->flags |= CF_READ_EVENT;
|
||||
|
||||
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
||||
@ -731,7 +731,7 @@ static void sc_app_shutw_conn(struct stconn *sc)
|
||||
*/
|
||||
sc_conn_shutw(sc, CO_SHW_NORMAL);
|
||||
|
||||
if (!(sc->flags & SC_FL_SHUTR) && !(ic->flags & CF_DONT_READ))
|
||||
if (!(sc->flags & SC_FL_ABRT_DONE) && !(ic->flags & CF_DONT_READ))
|
||||
return;
|
||||
}
|
||||
|
||||
@ -749,7 +749,7 @@ static void sc_app_shutw_conn(struct stconn *sc)
|
||||
__fallthrough;
|
||||
default:
|
||||
sc->flags &= ~SC_FL_NOLINGER;
|
||||
sc->flags |= SC_FL_SHUTR;
|
||||
sc->flags |= SC_FL_ABRT_DONE;
|
||||
if (sc->flags & SC_FL_ISBACK)
|
||||
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
||||
}
|
||||
@ -857,9 +857,9 @@ static void sc_app_shutr_applet(struct stconn *sc)
|
||||
|
||||
BUG_ON(!sc_appctx(sc));
|
||||
|
||||
if (sc->flags & SC_FL_SHUTR)
|
||||
if (sc->flags & SC_FL_ABRT_DONE)
|
||||
return;
|
||||
sc->flags |= SC_FL_SHUTR;
|
||||
sc->flags |= SC_FL_ABRT_DONE;
|
||||
ic->flags |= CF_READ_EVENT;
|
||||
|
||||
/* Note: on shutr, we don't call the applet */
|
||||
@ -911,7 +911,7 @@ static void sc_app_shutw_applet(struct stconn *sc)
|
||||
* no risk so we close both sides immediately.
|
||||
*/
|
||||
if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
|
||||
!(sc->flags & SC_FL_SHUTR) &&
|
||||
!(sc->flags & SC_FL_ABRT_DONE) &&
|
||||
!(ic->flags & CF_DONT_READ))
|
||||
return;
|
||||
|
||||
@ -926,7 +926,7 @@ static void sc_app_shutw_applet(struct stconn *sc)
|
||||
__fallthrough;
|
||||
default:
|
||||
sc->flags &= ~SC_FL_NOLINGER;
|
||||
sc->flags |= SC_FL_SHUTR;
|
||||
sc->flags |= SC_FL_ABRT_DONE;
|
||||
if (sc->flags & SC_FL_ISBACK)
|
||||
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
||||
}
|
||||
@ -979,7 +979,7 @@ void sc_update_rx(struct stconn *sc)
|
||||
{
|
||||
struct channel *ic = sc_ic(sc);
|
||||
|
||||
if (sc->flags & SC_FL_SHUTR)
|
||||
if (sc->flags & SC_FL_ABRT_DONE)
|
||||
return;
|
||||
|
||||
/* Read not closed, update FD status and timeout for reads */
|
||||
@ -1103,12 +1103,12 @@ 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: SE_FL_ERROR
|
||||
* - A read event: shutdown for reads (CF_READ_EVENT + SHUTR)
|
||||
* - A read event: shutdown for reads (CF_READ_EVENT + ABRT_DONE)
|
||||
* end of input (CF_READ_EVENT + SC_FL_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) && ((sc->flags & SC_FL_EOI) || (sc->flags & SC_FL_SHUTR) || !ic->to_forward || sco->state != SC_ST_EST)) ||
|
||||
((ic->flags & CF_READ_EVENT) && ((sc->flags & SC_FL_EOI) || (sc->flags & SC_FL_ABRT_DONE) || !ic->to_forward || sco->state != SC_ST_EST)) ||
|
||||
sc_ep_test(sc, SE_FL_ERROR) ||
|
||||
|
||||
/* changes on the consumption side */
|
||||
@ -1139,9 +1139,9 @@ static void sc_conn_read0(struct stconn *sc)
|
||||
|
||||
BUG_ON(!sc_conn(sc));
|
||||
|
||||
if (sc->flags & SC_FL_SHUTR)
|
||||
if (sc->flags & SC_FL_ABRT_DONE)
|
||||
return;
|
||||
sc->flags |= SC_FL_SHUTR;
|
||||
sc->flags |= SC_FL_ABRT_DONE;
|
||||
ic->flags |= CF_READ_EVENT;
|
||||
sc_ep_report_read_activity(sc);
|
||||
|
||||
@ -1198,7 +1198,7 @@ static int sc_conn_recv(struct stconn *sc)
|
||||
return 0;
|
||||
|
||||
/* maybe we were called immediately after an asynchronous shutr */
|
||||
if (sc->flags & SC_FL_SHUTR)
|
||||
if (sc->flags & SC_FL_ABRT_DONE)
|
||||
return 1;
|
||||
|
||||
/* we must wait because the mux is not installed yet */
|
||||
@ -1328,7 +1328,7 @@ static int sc_conn_recv(struct stconn *sc)
|
||||
*/
|
||||
while (sc_ep_test(sc, SE_FL_RCV_MORE) ||
|
||||
(!(conn->flags & CO_FL_HANDSHAKE) &&
|
||||
(!sc_ep_test(sc, SE_FL_ERROR | SE_FL_EOS)) && !(sc->flags & SC_FL_SHUTR))) {
|
||||
(!sc_ep_test(sc, SE_FL_ERROR | SE_FL_EOS)) && !(sc->flags & SC_FL_ABRT_DONE))) {
|
||||
int cur_flags = flags;
|
||||
|
||||
/* Compute transient CO_RFL_* flags */
|
||||
@ -1492,7 +1492,7 @@ static int sc_conn_recv(struct stconn *sc)
|
||||
if (sc_ep_test(sc, SE_FL_ERROR))
|
||||
ret = 1;
|
||||
else if (!(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)) &&
|
||||
!(sc->flags & SC_FL_SHUTR)) {
|
||||
!(sc->flags & SC_FL_ABRT_DONE)) {
|
||||
/* Subscribe to receive events if we're blocking on I/O */
|
||||
conn->mux->subscribe(sc, SUB_RETRY_RECV, &sc->wait_event);
|
||||
se_have_no_more_data(sc->sedesc);
|
||||
@ -1609,7 +1609,7 @@ static int sc_conn_send(struct stconn *sc)
|
||||
((oc->to_forward && oc->to_forward != CHN_INFINITE_FORWARD) ||
|
||||
(sc->flags & SC_FL_SND_EXP_MORE) ||
|
||||
(IS_HTX_STRM(s) &&
|
||||
(!(sco->flags & (SC_FL_EOI|SC_FL_SHUTR)) && htx_expect_more(htxbuf(&oc->buf)))))) ||
|
||||
(!(sco->flags & (SC_FL_EOI|SC_FL_ABRT_DONE)) && htx_expect_more(htxbuf(&oc->buf)))))) ||
|
||||
((oc->flags & CF_ISRESP) &&
|
||||
(oc->flags & CF_AUTO_CLOSE) &&
|
||||
(sc->flags & SC_FL_SHUT_WANTED)))
|
||||
@ -1774,7 +1774,7 @@ static int sc_conn_process(struct stconn *sc)
|
||||
* wake callback. Otherwise sc_conn_recv()/sc_conn_send() already take
|
||||
* care of it.
|
||||
*/
|
||||
if (sc_ep_test(sc, SE_FL_EOS) && !(sc->flags & SC_FL_SHUTR)) {
|
||||
if (sc_ep_test(sc, SE_FL_EOS) && !(sc->flags & SC_FL_ABRT_DONE)) {
|
||||
/* we received a shutdown */
|
||||
if (ic->flags & CF_AUTO_CLOSE)
|
||||
sc_schedule_shutdown(sc_opposite(sc));
|
||||
@ -1853,7 +1853,7 @@ static int sc_applet_process(struct stconn *sc)
|
||||
/* If the applet wants to write and the channel is closed, it's a
|
||||
* broken pipe and it must be reported.
|
||||
*/
|
||||
if (!sc_ep_test(sc, SE_FL_HAVE_NO_DATA) && (sc->flags & SC_FL_SHUTR))
|
||||
if (!sc_ep_test(sc, SE_FL_HAVE_NO_DATA) && (sc->flags & SC_FL_ABRT_DONE))
|
||||
sc_ep_set(sc, SE_FL_ERROR);
|
||||
|
||||
/* automatically mark the applet having data available if it reported
|
||||
|
||||
58
src/stream.c
58
src/stream.c
@ -885,7 +885,7 @@ int stream_set_timeout(struct stream *s, enum act_timeout_name name, int timeout
|
||||
* SC_ST_EST state. It must only be called after switching from SC_ST_CON (or
|
||||
* SC_ST_INI or SC_ST_RDY) to SC_ST_EST, but only when a ->proto is defined.
|
||||
* Note that it will switch the interface to SC_ST_DIS if we already have
|
||||
* the SC_FL_SHUTR flag, it means we were able to forward the request, and
|
||||
* the SC_FL_ABRT_DONE flag, it means we were able to forward the request, and
|
||||
* receive the response, before process_stream() had the opportunity to
|
||||
* make the switch from SC_ST_CON to SC_ST_EST. When that happens, we want
|
||||
* to go through back_establish() anyway, to make sure the analysers run.
|
||||
@ -954,7 +954,7 @@ static void back_establish(struct stream *s)
|
||||
}
|
||||
/* If we managed to get the whole response, and we don't have anything
|
||||
* left to send, or can't, switch to SC_ST_DIS now. */
|
||||
if ((s->scb->flags & SC_FL_SHUTR) || (s->scf->flags & SC_FL_SHUTW)) {
|
||||
if ((s->scb->flags & SC_FL_ABRT_DONE) || (s->scf->flags & SC_FL_SHUTW)) {
|
||||
s->scb->state = SC_ST_DIS;
|
||||
DBG_TRACE_STATE("response channel shutdwn for read/write", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
|
||||
}
|
||||
@ -1590,7 +1590,7 @@ static void stream_handle_timeouts(struct stream *s)
|
||||
sc_shutw(s->scb);
|
||||
}
|
||||
|
||||
if (unlikely(!(s->scf->flags & SC_FL_SHUTR) && (s->req.flags & CF_READ_TIMEOUT))) {
|
||||
if (unlikely(!(s->scf->flags & SC_FL_ABRT_DONE) && (s->req.flags & CF_READ_TIMEOUT))) {
|
||||
if (s->scf->flags & SC_FL_NOHALF)
|
||||
s->scf->flags |= SC_FL_NOLINGER;
|
||||
sc_shutr(s->scf);
|
||||
@ -1600,7 +1600,7 @@ static void stream_handle_timeouts(struct stream *s)
|
||||
sc_shutw(s->scf);
|
||||
}
|
||||
|
||||
if (unlikely(!(s->scb->flags & SC_FL_SHUTR) && (s->res.flags & CF_READ_TIMEOUT))) {
|
||||
if (unlikely(!(s->scb->flags & SC_FL_ABRT_DONE) && (s->res.flags & CF_READ_TIMEOUT))) {
|
||||
if (s->scb->flags & SC_FL_NOHALF)
|
||||
s->scb->flags |= SC_FL_NOLINGER;
|
||||
sc_shutr(s->scb);
|
||||
@ -1783,7 +1783,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
* So let's not run a whole stream processing if only an expiration
|
||||
* timeout needs to be refreshed.
|
||||
*/
|
||||
if (!((scf->flags | scb->flags) & (SC_FL_SHUTR|SC_FL_SHUTW)) &&
|
||||
if (!((scf->flags | scb->flags) & (SC_FL_ABRT_DONE|SC_FL_SHUTW)) &&
|
||||
!((req->flags | res->flags) & (CF_READ_EVENT|CF_READ_TIMEOUT|CF_WRITE_EVENT|CF_WRITE_TIMEOUT)) &&
|
||||
!(s->flags & SF_CONN_EXP) &&
|
||||
!((sc_ep_get(scf) | sc_ep_get(scb)) & SE_FL_ERROR) &&
|
||||
@ -1954,7 +1954,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
resync_request:
|
||||
/* Analyse request */
|
||||
if (((req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
|
||||
((scf->flags ^ scf_flags) & (SC_FL_SHUTR|SC_FL_ABRT_WANTED)) ||
|
||||
((scf->flags ^ scf_flags) & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) ||
|
||||
((scb->flags ^ scb_flags) & (SC_FL_SHUTW|SC_FL_SHUT_WANTED)) ||
|
||||
(req->analysers && (chn_cons(req)->flags & SC_FL_SHUTW)) ||
|
||||
scf->state != rq_prod_last ||
|
||||
@ -2042,10 +2042,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
rq_cons_last = scb->state;
|
||||
req->flags &= ~CF_WAKE_ONCE;
|
||||
rqf_last = req->flags;
|
||||
scf_flags = (scf_flags & ~(SC_FL_SHUTR|SC_FL_ABRT_WANTED)) | (scf->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED));
|
||||
scf_flags = (scf_flags & ~(SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) | (scf->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED));
|
||||
scb_flags = (scb_flags & ~(SC_FL_SHUTW|SC_FL_SHUT_WANTED)) | (scb->flags & (SC_FL_SHUTW|SC_FL_SHUT_WANTED));
|
||||
|
||||
if (((scf->flags ^ scf_flags_ana) & SC_FL_SHUTR) || ((scb->flags ^ scb_flags_ana) & SC_FL_SHUTW))
|
||||
if (((scf->flags ^ scf_flags_ana) & SC_FL_ABRT_DONE) || ((scb->flags ^ scb_flags_ana) & SC_FL_SHUTW))
|
||||
goto resync_request;
|
||||
}
|
||||
|
||||
@ -2059,7 +2059,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
/* Analyse response */
|
||||
|
||||
if (((res->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
|
||||
((scb->flags ^ scb_flags) & (SC_FL_SHUTR|SC_FL_ABRT_WANTED)) ||
|
||||
((scb->flags ^ scb_flags) & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) ||
|
||||
((scf->flags ^ scf_flags) & (SC_FL_SHUTW|SC_FL_SHUT_WANTED)) ||
|
||||
(res->analysers && (chn_cons(res)->flags & SC_FL_SHUTW)) ||
|
||||
scf->state != rp_cons_last ||
|
||||
@ -2115,10 +2115,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
rp_prod_last = scb->state;
|
||||
res->flags &= ~CF_WAKE_ONCE;
|
||||
rpf_last = res->flags;
|
||||
scb_flags = (scb_flags & ~(SC_FL_SHUTR|SC_FL_ABRT_WANTED)) | (scb->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED));
|
||||
scb_flags = (scb_flags & ~(SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) | (scb->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED));
|
||||
scf_flags = (scf_flags & ~(SC_FL_SHUTW|SC_FL_SHUT_WANTED)) | (scf->flags & (SC_FL_SHUTW|SC_FL_SHUT_WANTED));
|
||||
|
||||
if (((scb->flags ^ scb_flags_ana) & SC_FL_SHUTR) || ((scf->flags ^ scf_flags_ana) & SC_FL_SHUTW))
|
||||
if (((scb->flags ^ scb_flags_ana) & SC_FL_ABRT_DONE) || ((scf->flags ^ scf_flags_ana) & SC_FL_SHUTW))
|
||||
goto resync_response;
|
||||
}
|
||||
|
||||
@ -2251,7 +2251,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
*/
|
||||
co_set_data(req, htx->data);
|
||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
!(scf->flags & SC_FL_ABRT_DONE) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
channel_htx_forward_forever(req, htx);
|
||||
}
|
||||
else {
|
||||
@ -2260,14 +2260,14 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
*/
|
||||
c_adv(req, ci_data(req));
|
||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
!(scf->flags & SC_FL_ABRT_DONE) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
channel_forward_forever(req);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if it is wise to enable kernel splicing to forward request data */
|
||||
if (!(req->flags & CF_KERN_SPLICING) &&
|
||||
!(scf->flags & SC_FL_SHUTR) &&
|
||||
!(scf->flags & SC_FL_ABRT_DONE) &&
|
||||
req->to_forward &&
|
||||
(global.tune.options & GTUNE_USE_SPLICE) &&
|
||||
(sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->rcv_pipe &&
|
||||
@ -2283,7 +2283,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
|
||||
/* reflect what the L7 analysers have seen last */
|
||||
rqf_last = req->flags;
|
||||
scf_flags = (scf_flags & ~(SC_FL_SHUTR|SC_FL_ABRT_WANTED)) | (scf->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED));
|
||||
scf_flags = (scf_flags & ~(SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) | (scf->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED));
|
||||
scb_flags = (scb_flags & ~(SC_FL_SHUTW|SC_FL_SHUT_WANTED)) | (scb->flags & (SC_FL_SHUTW|SC_FL_SHUT_WANTED));
|
||||
|
||||
/* it's possible that an upper layer has requested a connection setup or abort.
|
||||
@ -2364,7 +2364,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
* the other side's timeout as well. However this doesn't have effect during the
|
||||
* connection setup unless the backend has abortonclose set.
|
||||
*/
|
||||
if (unlikely((req->flags & CF_AUTO_CLOSE) && (scf->flags & SC_FL_SHUTR) &&
|
||||
if (unlikely((req->flags & CF_AUTO_CLOSE) && (scf->flags & SC_FL_ABRT_DONE) &&
|
||||
!(scb->flags & (SC_FL_SHUTW|SC_FL_SHUT_WANTED)) &&
|
||||
(scb->state != SC_ST_CON || (s->be->options & PR_O_ABRT_CLOSE)))) {
|
||||
sc_schedule_shutdown(scb);
|
||||
@ -2379,12 +2379,12 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
}
|
||||
|
||||
/* shutdown(write) done on server side, we must stop the client too */
|
||||
if (unlikely((scb->flags & SC_FL_SHUTW) && !(scf->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED))) &&
|
||||
if (unlikely((scb->flags & SC_FL_SHUTW) && !(scf->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED))) &&
|
||||
!req->analysers)
|
||||
sc_schedule_abort(scf);
|
||||
|
||||
/* shutdown(read) pending */
|
||||
if (unlikely((scf->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED)) == SC_FL_ABRT_WANTED)) {
|
||||
if (unlikely((scf->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) == SC_FL_ABRT_WANTED)) {
|
||||
if (scf->flags & SC_FL_NOHALF)
|
||||
scf->flags |= SC_FL_NOLINGER;
|
||||
sc_shutr(scf);
|
||||
@ -2398,7 +2398,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
goto resync_stconns;
|
||||
|
||||
/* otherwise we want to check if we need to resync the req buffer or not */
|
||||
if (((scf->flags ^ scf_flags) & SC_FL_SHUTR) || ((scb->flags ^ scb_flags) & SC_FL_SHUTW))
|
||||
if (((scf->flags ^ scf_flags) & SC_FL_ABRT_DONE) || ((scb->flags ^ scb_flags) & SC_FL_SHUTW))
|
||||
goto resync_request;
|
||||
|
||||
/* perform output updates to the response buffer */
|
||||
@ -2427,7 +2427,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
*/
|
||||
co_set_data(res, htx->data);
|
||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
!(scf->flags & SC_FL_ABRT_DONE) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
channel_htx_forward_forever(res, htx);
|
||||
}
|
||||
else {
|
||||
@ -2436,7 +2436,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
*/
|
||||
c_adv(res, ci_data(res));
|
||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
!(scf->flags & SC_FL_ABRT_DONE) && !(scb->flags & SC_FL_SHUT_WANTED))
|
||||
channel_forward_forever(res);
|
||||
}
|
||||
|
||||
@ -2447,16 +2447,16 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
if (!req->analysers && s->tunnel_timeout) {
|
||||
scf->ioto = scb->ioto = s->tunnel_timeout;
|
||||
|
||||
if ((scf->flags & (SC_FL_SHUTR|SC_FL_SHUTW)) && tick_isset(sess->fe->timeout.clientfin))
|
||||
if ((scf->flags & (SC_FL_ABRT_DONE|SC_FL_SHUTW)) && tick_isset(sess->fe->timeout.clientfin))
|
||||
scf->ioto = sess->fe->timeout.clientfin;
|
||||
if ((scb->flags & (SC_FL_SHUTR|SC_FL_SHUTW)) && tick_isset(s->be->timeout.serverfin))
|
||||
if ((scb->flags & (SC_FL_ABRT_DONE|SC_FL_SHUTW)) && tick_isset(s->be->timeout.serverfin))
|
||||
scb->ioto = s->be->timeout.serverfin;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if it is wise to enable kernel splicing to forward response data */
|
||||
if (!(res->flags & CF_KERN_SPLICING) &&
|
||||
!(scb->flags & SC_FL_SHUTR) &&
|
||||
!(scb->flags & SC_FL_ABRT_DONE) &&
|
||||
res->to_forward &&
|
||||
(global.tune.options & GTUNE_USE_SPLICE) &&
|
||||
(sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->snd_pipe &&
|
||||
@ -2472,7 +2472,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
|
||||
/* reflect what the L7 analysers have seen last */
|
||||
rpf_last = res->flags;
|
||||
scb_flags = (scb_flags & ~(SC_FL_SHUTR|SC_FL_ABRT_WANTED)) | (scb->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED));
|
||||
scb_flags = (scb_flags & ~(SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) | (scb->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED));
|
||||
scf_flags = (scf_flags & ~(SC_FL_SHUTW|SC_FL_SHUT_WANTED)) | (scf->flags & (SC_FL_SHUTW|SC_FL_SHUT_WANTED));
|
||||
|
||||
/* Let's see if we can send the pending response now */
|
||||
@ -2487,7 +2487,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
*/
|
||||
|
||||
/* first, let's check if the response buffer needs to shutdown(write) */
|
||||
if (unlikely((res->flags & CF_AUTO_CLOSE) && (scb->flags & SC_FL_SHUTR) &&
|
||||
if (unlikely((res->flags & CF_AUTO_CLOSE) && (scb->flags & SC_FL_ABRT_DONE) &&
|
||||
!(scf->flags & (SC_FL_SHUTW|SC_FL_SHUT_WANTED)))) {
|
||||
sc_schedule_shutdown(scf);
|
||||
}
|
||||
@ -2499,12 +2499,12 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
}
|
||||
|
||||
/* shutdown(write) done on the client side, we must stop the server too */
|
||||
if (unlikely((scf->flags & SC_FL_SHUTW) && !(scb->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED))) &&
|
||||
if (unlikely((scf->flags & SC_FL_SHUTW) && !(scb->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED))) &&
|
||||
!res->analysers)
|
||||
sc_schedule_abort(scb);
|
||||
|
||||
/* shutdown(read) pending */
|
||||
if (unlikely((scb->flags & (SC_FL_SHUTR|SC_FL_ABRT_WANTED)) == SC_FL_ABRT_WANTED)) {
|
||||
if (unlikely((scb->flags & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) == SC_FL_ABRT_WANTED)) {
|
||||
if (scb->flags & SC_FL_NOHALF)
|
||||
scb->flags |= SC_FL_NOLINGER;
|
||||
sc_shutr(scb);
|
||||
@ -2519,7 +2519,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
||||
if ((req->flags & ~rqf_last) & CF_MASK_ANALYSER)
|
||||
goto resync_request;
|
||||
|
||||
if (((scb->flags ^ scb_flags) & (SC_FL_SHUTR|SC_FL_ABRT_WANTED)) ||
|
||||
if (((scb->flags ^ scb_flags) & (SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED)) ||
|
||||
((scf->flags ^ scf_flags) & (SC_FL_SHUTW|SC_FL_SHUT_WANTED)))
|
||||
goto resync_response;
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit)
|
||||
* - if one rule returns KO, then return KO
|
||||
*/
|
||||
|
||||
if ((s->scf->flags & (SC_FL_EOI|SC_FL_SHUTR)) || channel_full(req, global.tune.maxrewrite) ||
|
||||
if ((s->scf->flags & (SC_FL_EOI|SC_FL_ABRT_DONE)) || channel_full(req, global.tune.maxrewrite) ||
|
||||
sc_waiting_room(chn_prod(req)) ||
|
||||
!s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
|
||||
partial = SMP_OPT_FINAL;
|
||||
@ -298,7 +298,7 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
* - if one rule returns OK, then return OK
|
||||
* - if one rule returns KO, then return KO
|
||||
*/
|
||||
if ((s->scb->flags & (SC_FL_EOI|SC_FL_SHUTR)) || channel_full(rep, global.tune.maxrewrite) ||
|
||||
if ((s->scb->flags & (SC_FL_EOI|SC_FL_ABRT_DONE)) || channel_full(rep, global.tune.maxrewrite) ||
|
||||
sc_waiting_room(chn_prod(rep)) ||
|
||||
!s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
|
||||
partial = SMP_OPT_FINAL;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user