mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MEDIUM: tree-wide: Move flags about shut from the channel to the SC
The purpose of this patch is only a one-to-one replacement, as far as possible. CF_SHUTR(_NOW) and CF_SHUTW(_NOW) flags are now carried by the stream-connecter. CF_ prefix is replaced by SC_FL_ one. Of course, it is not so simple because at many places, we were testing if a channel was shut for reads and writes in same time. To do the same, shut for reads must be tested on one side on the SC and shut for writes on the other side on the opposite SC. A special care was taken with process_stream(). flags of SCs must be saved to be able to detect changes, just like for the channels.
This commit is contained in:
parent
904763f562
commit
87633c3a11
@ -40,12 +40,6 @@
|
|||||||
* - read-only indicators reported by lower data levels :
|
* - read-only indicators reported by lower data levels :
|
||||||
* CF_STREAMER, CF_STREAMER_FAST
|
* CF_STREAMER, CF_STREAMER_FAST
|
||||||
*
|
*
|
||||||
* - write-once status flags reported by the stream connector layer :
|
|
||||||
* CF_SHUTR, CF_SHUTW
|
|
||||||
*
|
|
||||||
* - persistent control flags managed only by application level :
|
|
||||||
* CF_SHUT*_NOW, CF_*_ENA
|
|
||||||
*
|
|
||||||
* The flags have been arranged for readability, so that the read and write
|
* The flags have been arranged for readability, so that the read and write
|
||||||
* bits have the same position in a byte (read being the lower byte and write
|
* bits have the same position in a byte (read being the lower byte and write
|
||||||
* the second one). All flag names are relative to the channel. For instance,
|
* the second one). All flag names are relative to the channel. For instance,
|
||||||
@ -58,10 +52,7 @@
|
|||||||
#define CF_READ_TIMEOUT 0x00000004 /* timeout while waiting for producer */
|
#define CF_READ_TIMEOUT 0x00000004 /* timeout while waiting for producer */
|
||||||
/* unused 0x00000008 */
|
/* unused 0x00000008 */
|
||||||
|
|
||||||
/* unused: 0x00000010 */
|
/* unused: 0x00000010 - 0x00000080 */
|
||||||
#define CF_SHUTR 0x00000020 /* producer has already shut down */
|
|
||||||
#define CF_SHUTR_NOW 0x00000040 /* the producer must shut down for reads ASAP */
|
|
||||||
/* 0x00000080 unused */
|
|
||||||
|
|
||||||
#define CF_WRITE_EVENT 0x00000100 /* a write event detected on consumer side */
|
#define CF_WRITE_EVENT 0x00000100 /* a write event detected on consumer side */
|
||||||
/* unused: 0x00000200 */
|
/* unused: 0x00000200 */
|
||||||
@ -69,37 +60,9 @@
|
|||||||
/* unused 0x00000800 */
|
/* unused 0x00000800 */
|
||||||
|
|
||||||
#define CF_WAKE_WRITE 0x00001000 /* wake the task up when there's write activity */
|
#define CF_WAKE_WRITE 0x00001000 /* wake the task up when there's write activity */
|
||||||
#define CF_SHUTW 0x00002000 /* consumer has already shut down */
|
/* unused: 0x00002000 - 0x00004000 */
|
||||||
#define CF_SHUTW_NOW 0x00004000 /* the consumer must shut down for writes ASAP */
|
|
||||||
#define CF_AUTO_CLOSE 0x00008000 /* producer can forward shutdown to other side */
|
#define CF_AUTO_CLOSE 0x00008000 /* producer can forward shutdown to other side */
|
||||||
|
|
||||||
/* When CF_SHUTR_NOW is set, it is strictly forbidden for the producer to alter
|
|
||||||
* the buffer contents. When CF_SHUTW_NOW is set, the consumer is free to perform
|
|
||||||
* a shutw() when it has consumed the last contents, otherwise the session processor
|
|
||||||
* will do it anyway.
|
|
||||||
*
|
|
||||||
* The SHUT* flags work like this :
|
|
||||||
*
|
|
||||||
* SHUTR SHUTR_NOW meaning
|
|
||||||
* 0 0 normal case, connection still open and data is being read
|
|
||||||
* 0 1 closing : the producer cannot feed data anymore but can close
|
|
||||||
* 1 0 closed: the producer has closed its input channel.
|
|
||||||
* 1 1 impossible
|
|
||||||
*
|
|
||||||
* SHUTW SHUTW_NOW meaning
|
|
||||||
* 0 0 normal case, connection still open and data is being written
|
|
||||||
* 0 1 closing: the consumer can send last data and may then close
|
|
||||||
* 1 0 closed: the consumer has closed its output channel.
|
|
||||||
* 1 1 impossible
|
|
||||||
*
|
|
||||||
* The SHUTW_NOW flag should be set by the session processor when SHUTR and AUTO_CLOSE
|
|
||||||
* are both set. And it may also be set by the producer when it detects SHUTR while
|
|
||||||
* directly forwarding data to the consumer.
|
|
||||||
*
|
|
||||||
* The SHUTR_NOW flag is mostly used to force the producer to abort when an error is
|
|
||||||
* detected on the consumer side.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CF_STREAMER 0x00010000 /* the producer is identified as streaming data */
|
#define CF_STREAMER 0x00010000 /* the producer is identified as streaming data */
|
||||||
#define CF_STREAMER_FAST 0x00020000 /* the consumer seems to eat the stream very fast */
|
#define CF_STREAMER_FAST 0x00020000 /* the consumer seems to eat the stream very fast */
|
||||||
|
|
||||||
@ -120,9 +83,6 @@
|
|||||||
/* Masks which define input events for stream analysers */
|
/* Masks which define input events for stream analysers */
|
||||||
#define CF_MASK_ANALYSER (CF_READ_EVENT|CF_READ_TIMEOUT|CF_WRITE_EVENT|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)
|
|
||||||
|
|
||||||
/* This function is used to report flags in debugging tools. Please reflect
|
/* This function is used to report flags in debugging tools. Please reflect
|
||||||
* below any single-bit flag addition above in the same order via the
|
* below any single-bit flag addition above in the same order via the
|
||||||
* __APPEND_FLAG macro. The new end of the buffer is returned.
|
* __APPEND_FLAG macro. The new end of the buffer is returned.
|
||||||
@ -134,14 +94,14 @@ static forceinline char *chn_show_flags(char *buf, size_t len, const char *delim
|
|||||||
_(0);
|
_(0);
|
||||||
/* flags */
|
/* flags */
|
||||||
_(CF_READ_EVENT, _(CF_READ_TIMEOUT,
|
_(CF_READ_EVENT, _(CF_READ_TIMEOUT,
|
||||||
_(CF_SHUTR, _(CF_SHUTR_NOW, _(CF_WRITE_EVENT,
|
_(CF_WRITE_EVENT,
|
||||||
_(CF_WRITE_TIMEOUT,
|
_(CF_WRITE_TIMEOUT,
|
||||||
_(CF_WAKE_WRITE, _(CF_SHUTW, _(CF_SHUTW_NOW, _(CF_AUTO_CLOSE,
|
_(CF_WAKE_WRITE, _(CF_AUTO_CLOSE,
|
||||||
_(CF_STREAMER, _(CF_STREAMER_FAST, _(CF_WROTE_DATA,
|
_(CF_STREAMER, _(CF_STREAMER_FAST, _(CF_WROTE_DATA,
|
||||||
_(CF_KERN_SPLICING,
|
_(CF_KERN_SPLICING,
|
||||||
_(CF_AUTO_CONNECT, _(CF_DONT_READ,
|
_(CF_AUTO_CONNECT, _(CF_DONT_READ,
|
||||||
_(CF_WAKE_ONCE, _(CF_FLT_ANALYZE,
|
_(CF_WAKE_ONCE, _(CF_FLT_ANALYZE,
|
||||||
_(CF_ISRESP)))))))))))))))))));
|
_(CF_ISRESP)))))))))))))));
|
||||||
/* epilogue */
|
/* epilogue */
|
||||||
_(~0U);
|
_(~0U);
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -514,13 +514,13 @@ static inline int channel_may_recv(const struct channel *chn)
|
|||||||
/* Returns true if the channel's input is already closed */
|
/* Returns true if the channel's input is already closed */
|
||||||
static inline int channel_input_closed(struct channel *chn)
|
static inline int channel_input_closed(struct channel *chn)
|
||||||
{
|
{
|
||||||
return ((chn->flags & CF_SHUTR) != 0);
|
return ((chn_prod(chn)->flags & SC_FL_SHUTR) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if the channel's output is already closed */
|
/* Returns true if the channel's output is already closed */
|
||||||
static inline int channel_output_closed(struct channel *chn)
|
static inline int channel_output_closed(struct channel *chn)
|
||||||
{
|
{
|
||||||
return ((chn->flags & CF_SHUTW) != 0);
|
return ((chn_cons(chn)->flags & SC_FL_SHUTW) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check channel timeouts, and set the corresponding flags. */
|
/* Check channel timeouts, and set the corresponding flags. */
|
||||||
@ -551,19 +551,20 @@ static inline void channel_htx_erase(struct channel *chn, struct htx *htx)
|
|||||||
/* marks the channel as "shutdown" ASAP for reads */
|
/* marks the channel as "shutdown" ASAP for reads */
|
||||||
static inline void channel_shutr_now(struct channel *chn)
|
static inline void channel_shutr_now(struct channel *chn)
|
||||||
{
|
{
|
||||||
chn->flags |= CF_SHUTR_NOW;
|
chn_prod(chn)->flags |= SC_FL_SHUTR_NOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* marks the channel as "shutdown" ASAP for writes */
|
/* marks the channel as "shutdown" ASAP for writes */
|
||||||
static inline void channel_shutw_now(struct channel *chn)
|
static inline void channel_shutw_now(struct channel *chn)
|
||||||
{
|
{
|
||||||
chn->flags |= CF_SHUTW_NOW;
|
chn_cons(chn)->flags |= SC_FL_SHUTW_NOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* marks the channel as "shutdown" ASAP in both directions */
|
/* marks the channel as "shutdown" ASAP in both directions */
|
||||||
static inline void channel_abort(struct channel *chn)
|
static inline void channel_abort(struct channel *chn)
|
||||||
{
|
{
|
||||||
chn->flags |= CF_SHUTR_NOW | CF_SHUTW_NOW;
|
chn_prod(chn)->flags |= SC_FL_SHUTR_NOW;
|
||||||
|
chn_cons(chn)->flags |= SC_FL_SHUTW_NOW;
|
||||||
chn->flags &= ~CF_AUTO_CONNECT;
|
chn->flags &= ~CF_AUTO_CONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -986,8 +987,8 @@ static inline int ci_putstr(struct channel *chn, const char *str)
|
|||||||
static inline int co_getchr(struct channel *chn)
|
static inline int co_getchr(struct channel *chn)
|
||||||
{
|
{
|
||||||
/* closed or empty + imminent close = -2; empty = -1 */
|
/* closed or empty + imminent close = -2; empty = -1 */
|
||||||
if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
|
if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
return -2;
|
return -2;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ static inline int sc_is_recv_allowed(const struct stconn *sc)
|
|||||||
{
|
{
|
||||||
struct channel *ic = sc_ic(sc);
|
struct channel *ic = sc_ic(sc);
|
||||||
|
|
||||||
if (ic->flags & CF_SHUTR)
|
if (chn_prod(ic)->flags & SC_FL_SHUTR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (sc_ep_test(sc, SE_FL_APPLET_NEED_CONN))
|
if (sc_ep_test(sc, SE_FL_APPLET_NEED_CONN))
|
||||||
@ -367,7 +367,7 @@ static inline int sc_is_send_allowed(const struct stconn *sc)
|
|||||||
{
|
{
|
||||||
struct channel *oc = sc_oc(sc);
|
struct channel *oc = sc_oc(sc);
|
||||||
|
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return !sc_ep_test(sc, SE_FL_WAIT_DATA | SE_FL_WONT_CONSUME);
|
return !sc_ep_test(sc, SE_FL_WAIT_DATA | SE_FL_WONT_CONSUME);
|
||||||
@ -375,7 +375,8 @@ static inline int sc_is_send_allowed(const struct stconn *sc)
|
|||||||
|
|
||||||
static inline int sc_rcv_may_expire(const struct stconn *sc)
|
static inline int sc_rcv_may_expire(const struct stconn *sc)
|
||||||
{
|
{
|
||||||
if (sc_ic(sc)->flags & (CF_SHUTR|CF_READ_TIMEOUT|CF_READ_EVENT))
|
if ((chn_prod(sc_ic(sc))->flags & SC_FL_SHUTR) ||
|
||||||
|
(sc_ic(sc)->flags & (CF_READ_TIMEOUT|CF_READ_EVENT)))
|
||||||
return 0;
|
return 0;
|
||||||
if (sc->flags & (SC_FL_EOI|SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
|
if (sc->flags & (SC_FL_EOI|SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
|
||||||
return 0;
|
return 0;
|
||||||
@ -386,7 +387,8 @@ static inline int sc_rcv_may_expire(const struct stconn *sc)
|
|||||||
|
|
||||||
static inline int sc_snd_may_expire(const struct stconn *sc)
|
static inline int sc_snd_may_expire(const struct stconn *sc)
|
||||||
{
|
{
|
||||||
if (sc_oc(sc)->flags & (CF_SHUTW|CF_WRITE_TIMEOUT|CF_WRITE_EVENT))
|
if ((chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW) ||
|
||||||
|
(sc_oc(sc)->flags & (CF_WRITE_TIMEOUT|CF_WRITE_EVENT)))
|
||||||
return 0;
|
return 0;
|
||||||
if (sc_ep_test(sc, SE_FL_WONT_CONSUME))
|
if (sc_ep_test(sc, SE_FL_WONT_CONSUME))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -109,6 +109,33 @@ static forceinline char *se_show_flags(char *buf, size_t len, const char *delim,
|
|||||||
|
|
||||||
/* stconn flags.
|
/* stconn flags.
|
||||||
* Please also update the sc_show_flags() function below in case of changes.
|
* Please also update the sc_show_flags() function below in case of changes.
|
||||||
|
*
|
||||||
|
* When SC_FL_SHUTR_NOW is set, it is strictly forbidden for the producer to alter
|
||||||
|
* the buffer contents. When SC_FL_SHUTW_NOW is set, the consumer is free to perform
|
||||||
|
* a shutw() when it has consumed the last contents, otherwise the session processor
|
||||||
|
* will do it anyway.
|
||||||
|
*
|
||||||
|
* The SHUT* flags work like this :
|
||||||
|
*
|
||||||
|
* SHUTR SHUTR_NOW meaning
|
||||||
|
* 0 0 normal case, connection still open and data is being read
|
||||||
|
* 0 1 closing : the producer cannot feed data anymore but can close
|
||||||
|
* 1 0 closed: the producer has closed its input channel.
|
||||||
|
* 1 1 impossible
|
||||||
|
*
|
||||||
|
* SHUTW SHUTW_NOW meaning
|
||||||
|
* 0 0 normal case, connection still open and data is being written
|
||||||
|
* 0 1 closing: the consumer can send last data and may then close
|
||||||
|
* 1 0 closed: the consumer has closed its output channel.
|
||||||
|
* 1 1 impossible
|
||||||
|
*
|
||||||
|
* The SHUTW_NOW flag should be set by the session processor when SHUTR and AUTO_CLOSE
|
||||||
|
* are both set. And it may also be set by the producer when it detects SHUTR while
|
||||||
|
* directly forwarding data to the consumer.
|
||||||
|
*
|
||||||
|
* The SHUTR_NOW flag is mostly used to force the producer to abort when an error is
|
||||||
|
* detected on the consumer side.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
enum sc_flags {
|
enum sc_flags {
|
||||||
SC_FL_NONE = 0x00000000, /* Just for initialization purposes */
|
SC_FL_NONE = 0x00000000, /* Just for initialization purposes */
|
||||||
@ -130,6 +157,11 @@ enum sc_flags {
|
|||||||
SC_FL_SND_ASAP = 0x00000800, /* Don't wait for sending. cleared when all data were sent */
|
SC_FL_SND_ASAP = 0x00000800, /* Don't wait for sending. cleared when all data were sent */
|
||||||
SC_FL_SND_NEVERWAIT = 0x00001000, /* Never wait for sending (permanent) */
|
SC_FL_SND_NEVERWAIT = 0x00001000, /* Never wait for sending (permanent) */
|
||||||
SC_FL_SND_EXP_MORE = 0x00001000, /* More data expected to be sent very soon. cleared when all data were sent */
|
SC_FL_SND_EXP_MORE = 0x00001000, /* More data expected to be sent very soon. cleared when all data were sent */
|
||||||
|
|
||||||
|
SC_FL_SHUTR_NOW = 0x00002000, /* SC is shut down for reads */
|
||||||
|
SC_FL_SHUTW_NOW = 0x00004000, /* SC must shut down for reads ASAP */
|
||||||
|
SC_FL_SHUTR = 0x00008000, /* SC is shut down for writes */
|
||||||
|
SC_FL_SHUTW = 0x00010000, /* SC must shut down for writes ASAP */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This function is used to report flags in debugging tools. Please reflect
|
/* This function is used to report flags in debugging tools. Please reflect
|
||||||
@ -145,7 +177,8 @@ static forceinline char *sc_show_flags(char *buf, size_t len, const char *delim,
|
|||||||
_(SC_FL_ISBACK, _(SC_FL_EOI, _(SC_FL_NOLINGER, _(SC_FL_NOHALF,
|
_(SC_FL_ISBACK, _(SC_FL_EOI, _(SC_FL_NOLINGER, _(SC_FL_NOHALF,
|
||||||
_(SC_FL_DONT_WAKE, _(SC_FL_INDEP_STR, _(SC_FL_WONT_READ,
|
_(SC_FL_DONT_WAKE, _(SC_FL_INDEP_STR, _(SC_FL_WONT_READ,
|
||||||
_(SC_FL_NEED_BUFF, _(SC_FL_NEED_ROOM,
|
_(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_RCV_ONCE, _(SC_FL_SND_ASAP, _(SC_FL_SND_NEVERWAIT, _(SC_FL_SND_EXP_MORE,
|
||||||
|
_(SC_FL_SHUTR_NOW, _(SC_FL_SHUTW_NOW, _(SC_FL_SHUTR, _(SC_FL_SHUTW)))))))))))))))));
|
||||||
/* epilogue */
|
/* epilogue */
|
||||||
_(~0U);
|
_(~0U);
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -624,7 +624,8 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
|
|||||||
int max_lines;
|
int max_lines;
|
||||||
int i, j, max;
|
int i, j, max;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side ! */
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
@ -887,7 +888,8 @@ static int cli_io_handler_show_tasks(struct appctx *appctx)
|
|||||||
int thr, queue;
|
int thr, queue;
|
||||||
int i, max;
|
int i, max;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side ! */
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* It's not possible to scan queues in small chunks and yield in the
|
/* It's not possible to scan queues in small chunks and yield in the
|
||||||
@ -1027,7 +1029,8 @@ static int cli_io_handler_show_activity(struct appctx *appctx)
|
|||||||
struct timeval up;
|
struct timeval up;
|
||||||
int thr;
|
int thr;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side ! */
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
|
@ -471,7 +471,7 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state)
|
|||||||
(b_size(sc_ib(sc)) && !b_data(sc_ib(sc)) && sc->flags & SC_FL_NEED_ROOM) || // asks for room in an empty buffer
|
(b_size(sc_ib(sc)) && !b_data(sc_ib(sc)) && sc->flags & SC_FL_NEED_ROOM) || // asks for room in an empty buffer
|
||||||
(b_data(sc_ob(sc)) && sc_is_send_allowed(sc)) || // asks for data already present
|
(b_data(sc_ob(sc)) && sc_is_send_allowed(sc)) || // asks for data already present
|
||||||
(!b_data(sc_ib(sc)) && b_data(sc_ob(sc)) && // didn't return anything ...
|
(!b_data(sc_ib(sc)) && b_data(sc_ob(sc)) && // didn't return anything ...
|
||||||
(sc_oc(sc)->flags & (CF_WRITE_EVENT|CF_SHUTW_NOW)) == CF_SHUTW_NOW))) { // ... and left data pending after a shut
|
(!(sc_oc(sc)->flags & CF_WRITE_EVENT) && (chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW_NOW))))) { // ... and left data pending after a shut
|
||||||
rate = update_freq_ctr(&app->call_rate, 1);
|
rate = update_freq_ctr(&app->call_rate, 1);
|
||||||
if (rate >= 100000 && app->call_rate.prev_ctr) // looped like this more than 100k times over last second
|
if (rate >= 100000 && app->call_rate.prev_ctr) // looped like this more than 100k times over last second
|
||||||
stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate));
|
stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate));
|
||||||
|
@ -1956,7 +1956,7 @@ int srv_redispatch_connect(struct stream *s)
|
|||||||
static int back_may_abort_req(struct channel *req, struct stream *s)
|
static int back_may_abort_req(struct channel *req, struct stream *s)
|
||||||
{
|
{
|
||||||
return (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
return (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
||||||
((req->flags & (CF_SHUTW_NOW|CF_SHUTW)) && /* empty and client aborted */
|
((chn_cons(req)->flags & (SC_FL_SHUTW_NOW|SC_FL_SHUTW)) && /* empty and client aborted */
|
||||||
(channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE))));
|
(channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2246,8 +2246,8 @@ void back_handle_st_con(struct stream *s)
|
|||||||
DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
|
DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
|
||||||
|
|
||||||
/* the client might want to abort */
|
/* the client might want to abort */
|
||||||
if ((rep->flags & CF_SHUTW) ||
|
if ((chn_cons(rep)->flags & SC_FL_SHUTW) ||
|
||||||
((req->flags & CF_SHUTW_NOW) &&
|
((chn_cons(req)->flags & SC_FL_SHUTW_NOW) &&
|
||||||
(channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
|
(channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
|
||||||
sc->flags |= SC_FL_NOLINGER;
|
sc->flags |= SC_FL_NOLINGER;
|
||||||
sc_shutw(sc);
|
sc_shutw(sc);
|
||||||
@ -2470,8 +2470,8 @@ void back_handle_st_rdy(struct stream *s)
|
|||||||
*/
|
*/
|
||||||
if (!(req->flags & CF_WROTE_DATA)) {
|
if (!(req->flags & CF_WROTE_DATA)) {
|
||||||
/* client abort ? */
|
/* client abort ? */
|
||||||
if ((rep->flags & CF_SHUTW) ||
|
if ((chn_cons(rep)->flags & SC_FL_SHUTW) ||
|
||||||
((req->flags & CF_SHUTW_NOW) &&
|
((chn_cons(req)->flags & SC_FL_SHUTW_NOW) &&
|
||||||
(channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
|
(channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
|
||||||
/* give up */
|
/* give up */
|
||||||
sc->flags |= SC_FL_NOLINGER;
|
sc->flags |= SC_FL_NOLINGER;
|
||||||
|
@ -206,8 +206,8 @@ int co_getdelim(const struct channel *chn, char *str, int len, const char *delim
|
|||||||
max = len;
|
max = len;
|
||||||
|
|
||||||
/* closed or empty + imminent close = -1; empty = 0 */
|
/* closed or empty + imminent close = -1; empty = 0 */
|
||||||
if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
|
if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -252,7 +252,7 @@ int co_getdelim(const struct channel *chn, char *str, int len, const char *delim
|
|||||||
if (ret > 0 && ret < len &&
|
if (ret > 0 && ret < len &&
|
||||||
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
||||||
!found &&
|
!found &&
|
||||||
!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
|
!(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
if (max)
|
if (max)
|
||||||
@ -279,8 +279,8 @@ int co_getword(const struct channel *chn, char *str, int len, char sep)
|
|||||||
max = len;
|
max = len;
|
||||||
|
|
||||||
/* closed or empty + imminent close = -1; empty = 0 */
|
/* closed or empty + imminent close = -1; empty = 0 */
|
||||||
if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
|
if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ int co_getword(const struct channel *chn, char *str, int len, char sep)
|
|||||||
if (ret > 0 && ret < len &&
|
if (ret > 0 && ret < len &&
|
||||||
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
||||||
*(str-1) != sep &&
|
*(str-1) != sep &&
|
||||||
!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
|
!(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
if (max)
|
if (max)
|
||||||
@ -330,8 +330,8 @@ int co_getline(const struct channel *chn, char *str, int len)
|
|||||||
max = len;
|
max = len;
|
||||||
|
|
||||||
/* closed or empty + imminent close = -1; empty = 0 */
|
/* closed or empty + imminent close = -1; empty = 0 */
|
||||||
if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
|
if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ int co_getline(const struct channel *chn, char *str, int len)
|
|||||||
if (ret > 0 && ret < len &&
|
if (ret > 0 && ret < len &&
|
||||||
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
(ret < co_data(chn) || channel_may_recv(chn)) &&
|
||||||
*(str-1) != '\n' &&
|
*(str-1) != '\n' &&
|
||||||
!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
|
!(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
if (max)
|
if (max)
|
||||||
@ -372,11 +372,11 @@ int co_getline(const struct channel *chn, char *str, int len)
|
|||||||
*/
|
*/
|
||||||
int co_getchar(const struct channel *chn, char *c)
|
int co_getchar(const struct channel *chn, char *c)
|
||||||
{
|
{
|
||||||
if (chn->flags & CF_SHUTW)
|
if (chn_cons(chn)->flags & SC_FL_SHUTW)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (unlikely(co_data(chn) == 0)) {
|
if (unlikely(co_data(chn) == 0)) {
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -395,11 +395,11 @@ int co_getchar(const struct channel *chn, char *c)
|
|||||||
*/
|
*/
|
||||||
int co_getblk(const struct channel *chn, char *blk, int len, int offset)
|
int co_getblk(const struct channel *chn, char *blk, int len, int offset)
|
||||||
{
|
{
|
||||||
if (chn->flags & CF_SHUTW)
|
if (chn_cons(chn)->flags & SC_FL_SHUTW)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (len + offset > co_data(chn) || co_data(chn) == 0) {
|
if (len + offset > co_data(chn) || co_data(chn) == 0) {
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -418,7 +418,7 @@ int co_getblk(const struct channel *chn, char *blk, int len, int offset)
|
|||||||
int co_getblk_nc(const struct channel *chn, const char **blk1, size_t *len1, const char **blk2, size_t *len2)
|
int co_getblk_nc(const struct channel *chn, const char **blk1, size_t *len1, const char **blk2, size_t *len2)
|
||||||
{
|
{
|
||||||
if (unlikely(co_data(chn) == 0)) {
|
if (unlikely(co_data(chn) == 0)) {
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -460,7 +460,7 @@ int co_getline_nc(const struct channel *chn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) {
|
||||||
/* If we have found no LF and the buffer is shut, then
|
/* If we have found no LF and the buffer is shut, then
|
||||||
* the resulting string is made of the concatenation of
|
* the resulting string is made of the concatenation of
|
||||||
* the pending blocks (1 or 2).
|
* the pending blocks (1 or 2).
|
||||||
@ -484,7 +484,7 @@ int ci_getblk_nc(const struct channel *chn,
|
|||||||
char **blk2, size_t *len2)
|
char **blk2, size_t *len2)
|
||||||
{
|
{
|
||||||
if (unlikely(ci_data(chn) == 0)) {
|
if (unlikely(ci_data(chn) == 0)) {
|
||||||
if (chn->flags & CF_SHUTR)
|
if (chn_prod(chn)->flags & SC_FL_SHUTR)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -536,7 +536,7 @@ int ci_getline_nc(const struct channel *chn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chn->flags & CF_SHUTW) {
|
if (chn_cons(chn)->flags & SC_FL_SHUTW) {
|
||||||
/* If we have found no LF and the buffer is shut, then
|
/* If we have found no LF and the buffer is shut, then
|
||||||
* the resulting string is made of the concatenation of
|
* the resulting string is made of the concatenation of
|
||||||
* the pending blocks (1 or 2).
|
* the pending blocks (1 or 2).
|
||||||
|
19
src/cli.c
19
src/cli.c
@ -1213,7 +1213,8 @@ static int cli_io_handler_show_env(struct appctx *appctx)
|
|||||||
struct stconn *sc = appctx_sc(appctx);
|
struct stconn *sc = appctx_sc(appctx);
|
||||||
char **var = ctx->var;
|
char **var = ctx->var;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
@ -1251,7 +1252,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
|
|||||||
int fd = fdctx->fd;
|
int fd = fdctx->fd;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
@ -2685,7 +2687,7 @@ int pcli_wait_for_request(struct stream *s, struct channel *req, int an_bit)
|
|||||||
goto read_again;
|
goto read_again;
|
||||||
|
|
||||||
missing_data:
|
missing_data:
|
||||||
if (req->flags & CF_SHUTR) {
|
if (chn_prod(req)->flags & SC_FL_SHUTR) {
|
||||||
/* There is no more request or a only a partial one and we
|
/* There is no more request or a only a partial one and we
|
||||||
* receive a close from the client, we can leave */
|
* receive a close from the client, we can leave */
|
||||||
channel_shutw_now(&s->res);
|
channel_shutw_now(&s->res);
|
||||||
@ -2709,7 +2711,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
|||||||
struct proxy *be = s->be;
|
struct proxy *be = s->be;
|
||||||
|
|
||||||
if (sc_ep_test(s->scb, SE_FL_ERR_PENDING|SE_FL_ERROR) || (rep->flags & (CF_READ_TIMEOUT|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)))) {
|
((chn_cons(rep)->flags & SC_FL_SHUTW) && (rep->to_forward || co_data(rep)))) {
|
||||||
pcli_reply_and_close(s, "Can't connect to the target CLI!\n");
|
pcli_reply_and_close(s, "Can't connect to the target CLI!\n");
|
||||||
s->req.analysers &= ~AN_REQ_WAIT_CLI;
|
s->req.analysers &= ~AN_REQ_WAIT_CLI;
|
||||||
s->res.analysers &= ~AN_RES_WAIT_CLI;
|
s->res.analysers &= ~AN_RES_WAIT_CLI;
|
||||||
@ -2734,7 +2736,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rep->flags & CF_SHUTR) {
|
if (chn_prod(rep)->flags & SC_FL_SHUTR) {
|
||||||
/* stream cleanup */
|
/* stream cleanup */
|
||||||
|
|
||||||
pcli_write_prompt(s);
|
pcli_write_prompt(s);
|
||||||
@ -2823,9 +2825,11 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
|||||||
sockaddr_free(&s->scb->dst);
|
sockaddr_free(&s->scb->dst);
|
||||||
|
|
||||||
sc_set_state(s->scb, SC_ST_INI);
|
sc_set_state(s->scb, SC_ST_INI);
|
||||||
|
s->scb->flags &= ~(SC_FL_SHUTW|SC_FL_SHUTW_NOW);
|
||||||
s->scb->flags &= SC_FL_ISBACK | SC_FL_DONT_WAKE; /* we're in the context of process_stream */
|
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_STREAMER|CF_STREAMER_FAST|CF_WROTE_DATA);
|
|
||||||
s->res.flags &= ~(CF_SHUTR|CF_SHUTR_NOW|CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_EVENT|CF_WROTE_DATA|CF_READ_EVENT);
|
s->req.flags &= ~(CF_AUTO_CONNECT|CF_STREAMER|CF_STREAMER_FAST|CF_WROTE_DATA);
|
||||||
|
s->res.flags &= ~(CF_STREAMER|CF_STREAMER_FAST|CF_WRITE_EVENT|CF_WROTE_DATA|CF_READ_EVENT);
|
||||||
s->flags &= ~(SF_DIRECT|SF_ASSIGNED|SF_BE_ASSIGNED|SF_FORCE_PRST|SF_IGNORE_PRST);
|
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_CURR_SESS|SF_REDIRECTABLE|SF_SRV_REUSED);
|
||||||
s->flags &= ~(SF_ERR_MASK|SF_FINST_MASK|SF_REDISP);
|
s->flags &= ~(SF_ERR_MASK|SF_FINST_MASK|SF_REDISP);
|
||||||
@ -2846,6 +2850,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
|||||||
s->store_count = 0;
|
s->store_count = 0;
|
||||||
s->uniq_id = global.req_count++;
|
s->uniq_id = global.req_count++;
|
||||||
|
|
||||||
|
s->scf->flags &= ~(SC_FL_SHUTR|SC_FL_SHUTR_NOW);
|
||||||
s->scf->flags &= ~SC_FL_SND_NEVERWAIT;
|
s->scf->flags &= ~SC_FL_SND_NEVERWAIT;
|
||||||
s->scf->flags |= SC_FL_RCV_ONCE; /* one read is usually enough */
|
s->scf->flags |= SC_FL_RCV_ONCE; /* one read is usually enough */
|
||||||
|
|
||||||
|
@ -313,7 +313,8 @@ static int cli_io_handler_show_threads(struct appctx *appctx)
|
|||||||
struct stconn *sc = appctx_sc(appctx);
|
struct stconn *sc = appctx_sc(appctx);
|
||||||
int thr;
|
int thr;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (appctx->st0)
|
if (appctx->st0)
|
||||||
@ -1160,7 +1161,8 @@ static int debug_iohandler_fd(struct appctx *appctx)
|
|||||||
int ret = 1;
|
int ret = 1;
|
||||||
int i, fd;
|
int i, fd;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
@ -1367,7 +1369,8 @@ static int debug_iohandler_memstats(struct appctx *appctx)
|
|||||||
const char *pfx = ctx->match;
|
const char *pfx = ctx->match;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (!ctx->width) {
|
if (!ctx->width) {
|
||||||
|
@ -1016,11 +1016,11 @@ flt_xfer_data(struct stream *s, struct channel *chn, unsigned int an_bit)
|
|||||||
* - the input in closed and no data is pending
|
* - the input in closed and no data is pending
|
||||||
* - There is a READ/WRITE timeout
|
* - There is a READ/WRITE timeout
|
||||||
*/
|
*/
|
||||||
if (chn->flags & CF_SHUTW) {
|
if (chn_cons(chn)->flags & SC_FL_SHUTW) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (chn->flags & CF_SHUTR) {
|
if (chn_prod(chn)->flags & SC_FL_SHUTR) {
|
||||||
if (((s->flags & SF_HTX) && htx_is_empty(htxbuf(&chn->buf))) || c_empty(chn)) {
|
if (((s->flags & SF_HTX) && htx_is_empty(htxbuf(&chn->buf))) || c_empty(chn)) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -151,7 +151,7 @@ static int bwlim_apply_limit(struct filter *filter, struct channel *chn, unsigne
|
|||||||
*/
|
*/
|
||||||
ret = tokens;
|
ret = tokens;
|
||||||
if (tokens < conf->min_size) {
|
if (tokens < conf->min_size) {
|
||||||
ret = ((chn_prod(chn)->flags & SC_FL_EOI) || (chn->flags & CF_SHUTR))
|
ret = (chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_SHUTR))
|
||||||
? MIN(len, conf->min_size)
|
? MIN(len, conf->min_size)
|
||||||
: conf->min_size;
|
: conf->min_size;
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
|
|||||||
/* A SHUTR at this stage means we are performing a "destructive"
|
/* A SHUTR at this stage means we are performing a "destructive"
|
||||||
* HTTP upgrade (TCP>H2). In this case, we can leave.
|
* HTTP upgrade (TCP>H2). In this case, we can leave.
|
||||||
*/
|
*/
|
||||||
if (req->flags & CF_SHUTR) {
|
if (chn_prod(req)->flags & SC_FL_SHUTR) {
|
||||||
s->logs.logwait = 0;
|
s->logs.logwait = 0;
|
||||||
s->logs.level = 0;
|
s->logs.level = 0;
|
||||||
channel_abort(&s->req);
|
channel_abort(&s->req);
|
||||||
@ -767,7 +767,7 @@ int http_process_tarpit(struct stream *s, struct channel *req, int an_bit)
|
|||||||
* there and that the timeout has not expired.
|
* there and that the timeout has not expired.
|
||||||
*/
|
*/
|
||||||
channel_dont_connect(req);
|
channel_dont_connect(req);
|
||||||
if (!(req->flags & CF_SHUTR) &&
|
if (!(chn_prod(req)->flags & SC_FL_SHUTR) &&
|
||||||
!tick_is_expired(req->analyse_exp, now_ms)) {
|
!tick_is_expired(req->analyse_exp, now_ms)) {
|
||||||
/* Be sure to drain all data from the request channel */
|
/* Be sure to drain all data from the request channel */
|
||||||
channel_htx_erase(req, htxbuf(&req->buf));
|
channel_htx_erase(req, htxbuf(&req->buf));
|
||||||
@ -985,7 +985,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
|||||||
if (!(txn->flags & TX_CON_WANT_TUN))
|
if (!(txn->flags & TX_CON_WANT_TUN))
|
||||||
channel_dont_close(req);
|
channel_dont_close(req);
|
||||||
|
|
||||||
if ((req->flags & CF_SHUTW) && co_data(req)) {
|
if ((chn_cons(req)->flags & SC_FL_SHUTW) && co_data(req)) {
|
||||||
/* request errors are most likely due to the server aborting the
|
/* request errors are most likely due to the server aborting the
|
||||||
* transfer. */
|
* transfer. */
|
||||||
goto return_srv_abort;
|
goto return_srv_abort;
|
||||||
@ -1004,7 +1004,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
|||||||
* it can be abused to exhaust source ports. */
|
* it can be abused to exhaust source ports. */
|
||||||
if (s->be->options & PR_O_ABRT_CLOSE) {
|
if (s->be->options & PR_O_ABRT_CLOSE) {
|
||||||
channel_auto_read(req);
|
channel_auto_read(req);
|
||||||
if ((req->flags & CF_SHUTR) && !(txn->flags & TX_CON_WANT_TUN))
|
if ((chn_prod(req)->flags & SC_FL_SHUTR) && !(txn->flags & TX_CON_WANT_TUN))
|
||||||
s->scb->flags |= SC_FL_NOLINGER;
|
s->scb->flags |= SC_FL_NOLINGER;
|
||||||
channel_auto_close(req);
|
channel_auto_close(req);
|
||||||
}
|
}
|
||||||
@ -1020,12 +1020,12 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
|
|||||||
|
|
||||||
missing_data_or_waiting:
|
missing_data_or_waiting:
|
||||||
/* stop waiting for data if the input is closed before the end */
|
/* stop waiting for data if the input is closed before the end */
|
||||||
if (msg->msg_state < HTTP_MSG_ENDING && req->flags & CF_SHUTR)
|
if (msg->msg_state < HTTP_MSG_ENDING && chn_prod(req)->flags & SC_FL_SHUTR)
|
||||||
goto return_cli_abort;
|
goto return_cli_abort;
|
||||||
|
|
||||||
waiting:
|
waiting:
|
||||||
/* waiting for the last bits to leave the buffer */
|
/* waiting for the last bits to leave the buffer */
|
||||||
if (req->flags & CF_SHUTW)
|
if (chn_cons(req)->flags & SC_FL_SHUTW)
|
||||||
goto return_srv_abort;
|
goto return_srv_abort;
|
||||||
|
|
||||||
/* When TE: chunked is used, we need to get there again to parse remaining
|
/* When TE: chunked is used, we need to get there again to parse remaining
|
||||||
@ -1132,9 +1132,11 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc)
|
|||||||
|
|
||||||
req = &s->req;
|
req = &s->req;
|
||||||
res = &s->res;
|
res = &s->res;
|
||||||
|
|
||||||
/* Remove any write error from the request, and read error from the response */
|
/* Remove any write error from the request, and read error from the response */
|
||||||
req->flags &= ~(CF_WRITE_TIMEOUT | CF_SHUTW | CF_SHUTW_NOW);
|
s->scf->flags &= ~(SC_FL_SHUTR|SC_FL_SHUTR_NOW);
|
||||||
res->flags &= ~(CF_READ_TIMEOUT | CF_SHUTR | CF_READ_EVENT | CF_SHUTR_NOW);
|
req->flags &= ~CF_WRITE_TIMEOUT;
|
||||||
|
res->flags &= ~(CF_READ_TIMEOUT | CF_READ_EVENT);
|
||||||
res->analysers &= AN_RES_FLT_END;
|
res->analysers &= AN_RES_FLT_END;
|
||||||
s->conn_err_type = STRM_ET_NONE;
|
s->conn_err_type = STRM_ET_NONE;
|
||||||
s->flags &= ~(SF_CONN_EXP | SF_ERR_MASK | SF_FINST_MASK);
|
s->flags &= ~(SF_CONN_EXP | SF_ERR_MASK | SF_FINST_MASK);
|
||||||
@ -1144,6 +1146,7 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc)
|
|||||||
res->analyse_exp = TICK_ETERNITY;
|
res->analyse_exp = TICK_ETERNITY;
|
||||||
res->total = 0;
|
res->total = 0;
|
||||||
|
|
||||||
|
s->scb->flags &= ~(SC_FL_SHUTW|SC_FL_SHUTW_NOW);
|
||||||
if (sc_reset_endp(s->scb) < 0) {
|
if (sc_reset_endp(s->scb) < 0) {
|
||||||
if (!(s->flags & SF_ERR_MASK))
|
if (!(s->flags & SF_ERR_MASK))
|
||||||
s->flags |= SF_ERR_INTERNAL;
|
s->flags |= SF_ERR_INTERNAL;
|
||||||
@ -1293,7 +1296,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 3: client abort with an abortonclose */
|
/* 3: client abort with an abortonclose */
|
||||||
else if ((rep->flags & CF_SHUTR) && ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))) {
|
else if ((chn_prod(rep)->flags & SC_FL_SHUTR) &&
|
||||||
|
(chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||||
|
(chn_cons(&s->req)->flags & SC_FL_SHUTW)) {
|
||||||
_HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
|
_HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
|
||||||
_HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
|
_HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
|
||||||
if (sess->listener && sess->listener->counters)
|
if (sess->listener && sess->listener->counters)
|
||||||
@ -1315,7 +1320,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 */
|
/* 4: close from server, capture the response if the server has started to respond */
|
||||||
else if (rep->flags & CF_SHUTR) {
|
else if (chn_prod(rep)->flags & SC_FL_SHUTR) {
|
||||||
if ((txn->flags & TX_L7_RETRY) &&
|
if ((txn->flags & TX_L7_RETRY) &&
|
||||||
(s->be->retry_type & PR_RE_DISCONNECTED)) {
|
(s->be->retry_type & PR_RE_DISCONNECTED)) {
|
||||||
if (co_data(rep) || do_l7_retry(s, s->scb) == 0) {
|
if (co_data(rep) || do_l7_retry(s, s->scb) == 0) {
|
||||||
@ -2057,7 +2062,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
|||||||
if (htx->data != co_data(res))
|
if (htx->data != co_data(res))
|
||||||
goto missing_data_or_waiting;
|
goto missing_data_or_waiting;
|
||||||
|
|
||||||
if (!(msg->flags & HTTP_MSGF_XFER_LEN) && res->flags & CF_SHUTR) {
|
if (!(msg->flags & HTTP_MSGF_XFER_LEN) && (chn_prod(res)->flags & SC_FL_SHUTR)) {
|
||||||
msg->msg_state = HTTP_MSG_ENDING;
|
msg->msg_state = HTTP_MSG_ENDING;
|
||||||
goto ending;
|
goto ending;
|
||||||
}
|
}
|
||||||
@ -2101,7 +2106,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
|||||||
|
|
||||||
channel_dont_close(res);
|
channel_dont_close(res);
|
||||||
|
|
||||||
if ((res->flags & CF_SHUTW) && co_data(res)) {
|
if ((chn_cons(res)->flags & SC_FL_SHUTW) && co_data(res)) {
|
||||||
/* response errors are most likely due to the client aborting
|
/* response errors are most likely due to the client aborting
|
||||||
* the transfer. */
|
* the transfer. */
|
||||||
goto return_cli_abort;
|
goto return_cli_abort;
|
||||||
@ -2117,7 +2122,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
missing_data_or_waiting:
|
missing_data_or_waiting:
|
||||||
if (res->flags & CF_SHUTW)
|
if (chn_cons(res)->flags & SC_FL_SHUTW)
|
||||||
goto return_cli_abort;
|
goto return_cli_abort;
|
||||||
|
|
||||||
/* stop waiting for data if the input is closed before the end. If the
|
/* stop waiting for data if the input is closed before the end. If the
|
||||||
@ -2125,8 +2130,9 @@ 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
|
* so we don't want to count this as a server abort. Otherwise it's a
|
||||||
* server abort.
|
* server abort.
|
||||||
*/
|
*/
|
||||||
if (msg->msg_state < HTTP_MSG_ENDING && res->flags & CF_SHUTR) {
|
if (msg->msg_state < HTTP_MSG_ENDING && (chn_prod(res)->flags & SC_FL_SHUTR)) {
|
||||||
if ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))
|
if ((chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||||
|
(chn_cons(&s->req)->flags & SC_FL_SHUTW))
|
||||||
goto return_cli_abort;
|
goto return_cli_abort;
|
||||||
/* If we have some pending data, we continue the processing */
|
/* If we have some pending data, we continue the processing */
|
||||||
if (htx_is_empty(htx))
|
if (htx_is_empty(htx))
|
||||||
@ -2670,7 +2676,7 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
|
|||||||
/* Always call the action function if defined */
|
/* Always call the action function if defined */
|
||||||
if (rule->action_ptr) {
|
if (rule->action_ptr) {
|
||||||
if (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
if (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
||||||
((s->req.flags & CF_SHUTR) &&
|
((chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||||
(px->options & PR_O_ABRT_CLOSE)))
|
(px->options & PR_O_ABRT_CLOSE)))
|
||||||
act_opts |= ACT_OPT_FINAL;
|
act_opts |= ACT_OPT_FINAL;
|
||||||
|
|
||||||
@ -2833,7 +2839,7 @@ static enum rule_result http_res_get_intercept_rule(struct proxy *px, struct lis
|
|||||||
/* Always call the action function if defined */
|
/* Always call the action function if defined */
|
||||||
if (rule->action_ptr) {
|
if (rule->action_ptr) {
|
||||||
if (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
if (sc_ep_test(s->scf, SE_FL_ERROR) ||
|
||||||
((s->req.flags & CF_SHUTR) &&
|
((chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
|
||||||
(px->options & PR_O_ABRT_CLOSE)))
|
(px->options & PR_O_ABRT_CLOSE)))
|
||||||
act_opts |= ACT_OPT_FINAL;
|
act_opts |= ACT_OPT_FINAL;
|
||||||
|
|
||||||
@ -4081,7 +4087,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 */
|
/* we get here if we need to wait for more data */
|
||||||
if (!(chn->flags & CF_SHUTR)) {
|
if (!(chn_prod(chn)->flags & SC_FL_SHUTR)) {
|
||||||
if (!tick_isset(chn->analyse_exp))
|
if (!tick_isset(chn->analyse_exp))
|
||||||
chn->analyse_exp = tick_add_ifset(now_ms, time);
|
chn->analyse_exp = tick_add_ifset(now_ms, time);
|
||||||
ret = HTTP_RULE_RES_YIELD;
|
ret = HTTP_RULE_RES_YIELD;
|
||||||
@ -4270,7 +4276,7 @@ static void http_end_request(struct stream *s)
|
|||||||
txn->rsp.msg_state != HTTP_MSG_CLOSED)
|
txn->rsp.msg_state != HTTP_MSG_CLOSED)
|
||||||
goto check_channel_flags;
|
goto check_channel_flags;
|
||||||
|
|
||||||
if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
|
if (!(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))) {
|
||||||
channel_shutr_now(chn);
|
channel_shutr_now(chn);
|
||||||
channel_shutw_now(chn);
|
channel_shutw_now(chn);
|
||||||
}
|
}
|
||||||
@ -4304,7 +4310,7 @@ static void http_end_request(struct stream *s)
|
|||||||
|
|
||||||
check_channel_flags:
|
check_channel_flags:
|
||||||
/* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
|
/* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) {
|
||||||
/* if we've just closed an output, let's switch */
|
/* if we've just closed an output, let's switch */
|
||||||
txn->req.msg_state = HTTP_MSG_CLOSING;
|
txn->req.msg_state = HTTP_MSG_CLOSING;
|
||||||
goto http_msg_closing;
|
goto http_msg_closing;
|
||||||
@ -4369,7 +4375,7 @@ static void http_end_response(struct stream *s)
|
|||||||
/* we're not expecting any new data to come for this
|
/* we're not expecting any new data to come for this
|
||||||
* transaction, so we can close it.
|
* transaction, so we can close it.
|
||||||
*/
|
*/
|
||||||
if (!(chn->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
|
if (!(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))) {
|
||||||
channel_shutr_now(chn);
|
channel_shutr_now(chn);
|
||||||
channel_shutw_now(chn);
|
channel_shutw_now(chn);
|
||||||
}
|
}
|
||||||
@ -4400,7 +4406,7 @@ static void http_end_response(struct stream *s)
|
|||||||
|
|
||||||
check_channel_flags:
|
check_channel_flags:
|
||||||
/* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
|
/* Here, we are in HTTP_MSG_DONE or HTTP_MSG_TUNNEL */
|
||||||
if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW)) {
|
if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) {
|
||||||
/* if we've just closed an output, let's switch */
|
/* if we've just closed an output, let's switch */
|
||||||
txn->rsp.msg_state = HTTP_MSG_CLOSING;
|
txn->rsp.msg_state = HTTP_MSG_CLOSING;
|
||||||
goto http_msg_closing;
|
goto http_msg_closing;
|
||||||
|
@ -615,7 +615,7 @@ static int smp_fetch_body(const struct arg *args, struct sample *smp, const char
|
|||||||
smp->flags = SMP_F_VOL_TEST;
|
smp->flags = SMP_F_VOL_TEST;
|
||||||
|
|
||||||
if (!finished && (check || (chn && !channel_full(chn, global.tune.maxrewrite) &&
|
if (!finished && (check || (chn && !channel_full(chn, global.tune.maxrewrite) &&
|
||||||
!(chn_prod(chn)->flags & SC_FL_EOI) && !(chn->flags & CF_SHUTR))))
|
!(chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_SHUTR)))))
|
||||||
smp->flags |= SMP_F_MAY_CHANGE;
|
smp->flags |= SMP_F_MAY_CHANGE;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -348,7 +348,8 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
|
|||||||
struct stconn *sc = appctx_sc(appctx);
|
struct stconn *sc = appctx_sc(appctx);
|
||||||
struct pat_ref_elt *elt;
|
struct pat_ref_elt *elt;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW)) {
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW)) {
|
||||||
/* If we're forced to shut down, we might have to remove our
|
/* If we're forced to shut down, we might have to remove our
|
||||||
* reference to the last ref_elt being dumped.
|
* reference to the last ref_elt being dumped.
|
||||||
*/
|
*/
|
||||||
|
@ -567,7 +567,8 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
|
|||||||
char *uptime = NULL;
|
char *uptime = NULL;
|
||||||
char *reloadtxt = NULL;
|
char *reloadtxt = NULL;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (up < 0) /* must never be negative because of clock drift */
|
if (up < 0) /* must never be negative because of clock drift */
|
||||||
@ -713,10 +714,10 @@ static int cli_io_handler_show_loadstatus(struct appctx *appctx)
|
|||||||
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
env = getenv("HAPROXY_LOAD_SUCCESS");
|
env = getenv("HAPROXY_LOAD_SUCCESS");
|
||||||
if (!env)
|
if (!env)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3208,7 +3208,8 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
|||||||
struct stconn *sc = appctx_sc(appctx);
|
struct stconn *sc = appctx_sc(appctx);
|
||||||
extern const char *monthname[12];
|
extern const char *monthname[12];
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
|
@ -8261,7 +8261,8 @@ static int cli_io_handler_dump_quic(struct appctx *appctx)
|
|||||||
if (ctx->thr >= global.nbthread)
|
if (ctx->thr >= global.nbthread)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW)) {
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW)) {
|
||||||
/* If we're forced to shut down, we might have to remove our
|
/* If we're forced to shut down, we might have to remove our
|
||||||
* reference to the last stream being dumped.
|
* reference to the last stream being dumped.
|
||||||
*/
|
*/
|
||||||
|
@ -349,7 +349,8 @@ int cli_io_handler_show_ring(struct appctx *appctx)
|
|||||||
size_t len, cnt;
|
size_t len, cnt;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock);
|
HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock);
|
||||||
@ -422,7 +423,7 @@ int cli_io_handler_show_ring(struct appctx *appctx)
|
|||||||
/* we've drained everything and are configured to wait for more
|
/* we've drained everything and are configured to wait for more
|
||||||
* data or an event (keypress, close)
|
* data or an event (keypress, close)
|
||||||
*/
|
*/
|
||||||
if (!sc_oc(sc)->output && !(sc_oc(sc)->flags & CF_SHUTW)) {
|
if (!sc_oc(sc)->output && !(chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW)) {
|
||||||
/* let's be woken up once new data arrive */
|
/* let's be woken up once new data arrive */
|
||||||
HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock);
|
HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock);
|
||||||
LIST_APPEND(&ring->waiters, &appctx->wait_entry);
|
LIST_APPEND(&ring->waiters, &appctx->wait_entry);
|
||||||
|
@ -2148,7 +2148,8 @@ static int cli_io_handler_commit_cert(struct appctx *appctx)
|
|||||||
struct ckch_store *old_ckchs, *new_ckchs = NULL;
|
struct ckch_store *old_ckchs, *new_ckchs = NULL;
|
||||||
struct ckch_inst *ckchi;
|
struct ckch_inst *ckchi;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -2824,7 +2825,8 @@ static int cli_io_handler_commit_cafile_crlfile(struct appctx *appctx)
|
|||||||
struct ckch_inst_link *ckchi_link;
|
struct ckch_inst_link *ckchi_link;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* The ctx was already validated by the ca-file/crl-file parsing
|
/* The ctx was already validated by the ca-file/crl-file parsing
|
||||||
|
@ -1116,7 +1116,8 @@ static int cli_io_handler_add_crtlist(struct appctx *appctx)
|
|||||||
/* for each bind_conf which use the crt-list, a new ckch_inst must be
|
/* for each bind_conf which use the crt-list, a new ckch_inst must be
|
||||||
* created.
|
* created.
|
||||||
*/
|
*/
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW))
|
/* FIXME: Don't watch the other side !*/
|
||||||
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
switch (ctx->state) {
|
switch (ctx->state) {
|
||||||
|
@ -4473,7 +4473,7 @@ static void http_stats_io_handler(struct appctx *appctx)
|
|||||||
if (appctx->st0 == STAT_HTTP_POST) {
|
if (appctx->st0 == STAT_HTTP_POST) {
|
||||||
if (stats_process_http_post(sc))
|
if (stats_process_http_post(sc))
|
||||||
appctx->st0 = STAT_HTTP_LAST;
|
appctx->st0 = STAT_HTTP_LAST;
|
||||||
else if (req->flags & CF_SHUTR)
|
else if (chn_prod(req)->flags & SC_FL_SHUTR)
|
||||||
appctx->st0 = STAT_HTTP_DONE;
|
appctx->st0 = STAT_HTTP_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
133
src/stconn.c
133
src/stconn.c
@ -501,13 +501,13 @@ struct appctx *sc_applet_create(struct stconn *sc, struct applet *app)
|
|||||||
|
|
||||||
/* Conditionally forward the close to the write side. It return 1 if it can be
|
/* Conditionally forward the close to the write side. It return 1 if it can be
|
||||||
* forwarded. It is the caller responsibility to forward the close to the write
|
* forwarded. It is the caller responsibility to forward the close to the write
|
||||||
* side. Otherwise, 0 is returned. In this case, CF_SHUTW_NOW flag may be set on
|
* side. Otherwise, 0 is returned. In this case, SC_FL_SHUTW_NOW flag may be set on
|
||||||
* the channel if we are only waiting for the outgoing data to be flushed.
|
* the consumer SC if we are only waiting for the outgoing data to be flushed.
|
||||||
*/
|
*/
|
||||||
static inline int sc_cond_forward_shutw(struct stconn *sc)
|
static inline int sc_cond_forward_shutw(struct stconn *sc)
|
||||||
{
|
{
|
||||||
/* The close must not be forwarded */
|
/* The close must not be forwarded */
|
||||||
if (!(sc_ic(sc)->flags & CF_SHUTR) || !(sc->flags & SC_FL_NOHALF))
|
if (!(chn_prod(sc_ic(sc))->flags & SC_FL_SHUTR) || !(sc->flags & SC_FL_NOHALF))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!channel_is_empty(sc_ic(sc))) {
|
if (!channel_is_empty(sc_ic(sc))) {
|
||||||
@ -534,15 +534,17 @@ static void sc_app_shutr(struct stconn *sc)
|
|||||||
{
|
{
|
||||||
struct channel *ic = sc_ic(sc);
|
struct channel *ic = sc_ic(sc);
|
||||||
|
|
||||||
if (ic->flags & CF_SHUTR)
|
if (chn_prod(ic)->flags & SC_FL_SHUTR)
|
||||||
return;
|
return;
|
||||||
ic->flags |= CF_SHUTR|CF_READ_EVENT;
|
|
||||||
|
chn_prod(ic)->flags |= SC_FL_SHUTR;
|
||||||
|
ic->flags |= CF_READ_EVENT;
|
||||||
sc_ep_report_read_activity(sc);
|
sc_ep_report_read_activity(sc);
|
||||||
|
|
||||||
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sc_oc(sc)->flags & CF_SHUTW) {
|
if (chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW) {
|
||||||
sc->state = SC_ST_DIS;
|
sc->state = SC_ST_DIS;
|
||||||
if (sc->flags & SC_FL_ISBACK)
|
if (sc->flags & SC_FL_ISBACK)
|
||||||
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
||||||
@ -567,10 +569,11 @@ static void sc_app_shutw(struct stconn *sc)
|
|||||||
struct channel *ic = sc_ic(sc);
|
struct channel *ic = sc_ic(sc);
|
||||||
struct channel *oc = sc_oc(sc);
|
struct channel *oc = sc_oc(sc);
|
||||||
|
|
||||||
oc->flags &= ~CF_SHUTW_NOW;
|
chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
return;
|
return;
|
||||||
oc->flags |= CF_SHUTW|CF_WRITE_EVENT;
|
chn_cons(oc)->flags |= SC_FL_SHUTW;
|
||||||
|
oc->flags |= CF_WRITE_EVENT;
|
||||||
sc_set_hcto(sc);
|
sc_set_hcto(sc);
|
||||||
|
|
||||||
switch (sc->state) {
|
switch (sc->state) {
|
||||||
@ -583,7 +586,7 @@ static void sc_app_shutw(struct stconn *sc)
|
|||||||
* no risk so we close both sides immediately.
|
* no risk so we close both sides immediately.
|
||||||
*/
|
*/
|
||||||
if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
|
if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
|
||||||
!(ic->flags & (CF_SHUTR|CF_DONT_READ)))
|
!(chn_prod(ic)->flags & SC_FL_SHUTR) && !(ic->flags & CF_DONT_READ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__fallthrough;
|
__fallthrough;
|
||||||
@ -596,7 +599,7 @@ static void sc_app_shutw(struct stconn *sc)
|
|||||||
__fallthrough;
|
__fallthrough;
|
||||||
default:
|
default:
|
||||||
sc->flags &= ~SC_FL_NOLINGER;
|
sc->flags &= ~SC_FL_NOLINGER;
|
||||||
ic->flags |= CF_SHUTR;
|
chn_prod(ic)->flags |= SC_FL_SHUTR;
|
||||||
if (sc->flags & SC_FL_ISBACK)
|
if (sc->flags & SC_FL_ISBACK)
|
||||||
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
||||||
}
|
}
|
||||||
@ -627,7 +630,7 @@ static void sc_app_chk_snd(struct stconn *sc)
|
|||||||
{
|
{
|
||||||
struct channel *oc = sc_oc(sc);
|
struct channel *oc = sc_oc(sc);
|
||||||
|
|
||||||
if (unlikely(sc->state != SC_ST_EST || (oc->flags & CF_SHUTW)))
|
if (unlikely(sc->state != SC_ST_EST || (chn_cons(oc)->flags & SC_FL_SHUTW)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!sc_ep_test(sc, SE_FL_WAIT_DATA) || /* not waiting for data */
|
if (!sc_ep_test(sc, SE_FL_WAIT_DATA) || /* not waiting for data */
|
||||||
@ -658,14 +661,15 @@ static void sc_app_shutr_conn(struct stconn *sc)
|
|||||||
|
|
||||||
BUG_ON(!sc_conn(sc));
|
BUG_ON(!sc_conn(sc));
|
||||||
|
|
||||||
if (ic->flags & CF_SHUTR)
|
if (chn_prod(ic)->flags & SC_FL_SHUTR)
|
||||||
return;
|
return;
|
||||||
ic->flags |= CF_SHUTR|CF_READ_EVENT;
|
chn_prod(ic)->flags |= SC_FL_SHUTR;
|
||||||
|
ic->flags |= CF_READ_EVENT;
|
||||||
|
|
||||||
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sc_oc(sc)->flags & CF_SHUTW) {
|
if (chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW) {
|
||||||
sc_conn_shut(sc);
|
sc_conn_shut(sc);
|
||||||
sc->state = SC_ST_DIS;
|
sc->state = SC_ST_DIS;
|
||||||
if (sc->flags & SC_FL_ISBACK)
|
if (sc->flags & SC_FL_ISBACK)
|
||||||
@ -690,10 +694,11 @@ static void sc_app_shutw_conn(struct stconn *sc)
|
|||||||
|
|
||||||
BUG_ON(!sc_conn(sc));
|
BUG_ON(!sc_conn(sc));
|
||||||
|
|
||||||
oc->flags &= ~CF_SHUTW_NOW;
|
chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
return;
|
return;
|
||||||
oc->flags |= CF_SHUTW|CF_WRITE_EVENT;
|
chn_cons(oc)->flags |= SC_FL_SHUTW;
|
||||||
|
oc->flags |= CF_WRITE_EVENT;
|
||||||
sc_set_hcto(sc);
|
sc_set_hcto(sc);
|
||||||
|
|
||||||
switch (sc->state) {
|
switch (sc->state) {
|
||||||
@ -726,7 +731,7 @@ static void sc_app_shutw_conn(struct stconn *sc)
|
|||||||
*/
|
*/
|
||||||
sc_conn_shutw(sc, CO_SHW_NORMAL);
|
sc_conn_shutw(sc, CO_SHW_NORMAL);
|
||||||
|
|
||||||
if (!(ic->flags & (CF_SHUTR|CF_DONT_READ)))
|
if (!(chn_prod(ic)->flags & SC_FL_SHUTR) && !(ic->flags & CF_DONT_READ))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,7 +749,7 @@ static void sc_app_shutw_conn(struct stconn *sc)
|
|||||||
__fallthrough;
|
__fallthrough;
|
||||||
default:
|
default:
|
||||||
sc->flags &= ~SC_FL_NOLINGER;
|
sc->flags &= ~SC_FL_NOLINGER;
|
||||||
ic->flags |= CF_SHUTR;
|
chn_prod(ic)->flags |= SC_FL_SHUTR;
|
||||||
if (sc->flags & SC_FL_ISBACK)
|
if (sc->flags & SC_FL_ISBACK)
|
||||||
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
||||||
}
|
}
|
||||||
@ -778,7 +783,7 @@ static void sc_app_chk_snd_conn(struct stconn *sc)
|
|||||||
BUG_ON(!sc_conn(sc));
|
BUG_ON(!sc_conn(sc));
|
||||||
|
|
||||||
if (unlikely(!sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST) ||
|
if (unlikely(!sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST) ||
|
||||||
(oc->flags & CF_SHUTW)))
|
(chn_cons(oc)->flags & SC_FL_SHUTW)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (unlikely(channel_is_empty(oc))) /* called with nothing to send ! */
|
if (unlikely(channel_is_empty(oc))) /* called with nothing to send ! */
|
||||||
@ -807,14 +812,14 @@ static void sc_app_chk_snd_conn(struct stconn *sc)
|
|||||||
* ->o limit was reached. Maybe we just wrote the last
|
* ->o limit was reached. Maybe we just wrote the last
|
||||||
* chunk and need to close.
|
* chunk and need to close.
|
||||||
*/
|
*/
|
||||||
if (((oc->flags & (CF_SHUTW|CF_AUTO_CLOSE|CF_SHUTW_NOW)) ==
|
if ((oc->flags & CF_AUTO_CLOSE) &&
|
||||||
(CF_AUTO_CLOSE|CF_SHUTW_NOW)) &&
|
((chn_cons(oc)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) == SC_FL_SHUTW_NOW) &&
|
||||||
sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST)) {
|
sc_state_in(sc->state, SC_SB_RDY|SC_SB_EST)) {
|
||||||
sc_shutw(sc);
|
sc_shutw(sc);
|
||||||
goto out_wakeup;
|
goto out_wakeup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == 0)
|
if ((chn_cons(oc)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) == 0)
|
||||||
sc_ep_set(sc, SE_FL_WAIT_DATA);
|
sc_ep_set(sc, SE_FL_WAIT_DATA);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -827,7 +832,7 @@ static void sc_app_chk_snd_conn(struct stconn *sc)
|
|||||||
/* in case of special condition (error, shutdown, end of write...), we
|
/* in case of special condition (error, shutdown, end of write...), we
|
||||||
* have to notify the task.
|
* have to notify the task.
|
||||||
*/
|
*/
|
||||||
if (likely((oc->flags & CF_SHUTW) ||
|
if (likely((chn_cons(oc)->flags & SC_FL_SHUTW) ||
|
||||||
((oc->flags & CF_WRITE_EVENT) && sc->state < SC_ST_EST) ||
|
((oc->flags & CF_WRITE_EVENT) && sc->state < SC_ST_EST) ||
|
||||||
((oc->flags & CF_WAKE_WRITE) &&
|
((oc->flags & CF_WAKE_WRITE) &&
|
||||||
((channel_is_empty(oc) && !oc->to_forward) ||
|
((channel_is_empty(oc) && !oc->to_forward) ||
|
||||||
@ -852,16 +857,17 @@ static void sc_app_shutr_applet(struct stconn *sc)
|
|||||||
|
|
||||||
BUG_ON(!sc_appctx(sc));
|
BUG_ON(!sc_appctx(sc));
|
||||||
|
|
||||||
if (ic->flags & CF_SHUTR)
|
if (chn_prod(ic)->flags & SC_FL_SHUTR)
|
||||||
return;
|
return;
|
||||||
ic->flags |= CF_SHUTR|CF_READ_EVENT;
|
chn_prod(ic)->flags |= SC_FL_SHUTR;
|
||||||
|
ic->flags |= CF_READ_EVENT;
|
||||||
|
|
||||||
/* Note: on shutr, we don't call the applet */
|
/* Note: on shutr, we don't call the applet */
|
||||||
|
|
||||||
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sc_oc(sc)->flags & CF_SHUTW) {
|
if (chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW) {
|
||||||
appctx_shut(__sc_appctx(sc));
|
appctx_shut(__sc_appctx(sc));
|
||||||
sc->state = SC_ST_DIS;
|
sc->state = SC_ST_DIS;
|
||||||
if (sc->flags & SC_FL_ISBACK)
|
if (sc->flags & SC_FL_ISBACK)
|
||||||
@ -885,10 +891,11 @@ static void sc_app_shutw_applet(struct stconn *sc)
|
|||||||
|
|
||||||
BUG_ON(!sc_appctx(sc));
|
BUG_ON(!sc_appctx(sc));
|
||||||
|
|
||||||
oc->flags &= ~CF_SHUTW_NOW;
|
chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
return;
|
return;
|
||||||
oc->flags |= CF_SHUTW|CF_WRITE_EVENT;
|
chn_cons(oc)->flags |= SC_FL_SHUTW;
|
||||||
|
oc->flags |= CF_WRITE_EVENT;
|
||||||
sc_set_hcto(sc);
|
sc_set_hcto(sc);
|
||||||
|
|
||||||
/* on shutw we always wake the applet up */
|
/* on shutw we always wake the applet up */
|
||||||
@ -904,7 +911,8 @@ static void sc_app_shutw_applet(struct stconn *sc)
|
|||||||
* no risk so we close both sides immediately.
|
* no risk so we close both sides immediately.
|
||||||
*/
|
*/
|
||||||
if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
|
if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
|
||||||
!(ic->flags & (CF_SHUTR|CF_DONT_READ)))
|
!(chn_prod(ic)->flags & SC_FL_SHUTR) &&
|
||||||
|
!(ic->flags & CF_DONT_READ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__fallthrough;
|
__fallthrough;
|
||||||
@ -918,7 +926,7 @@ static void sc_app_shutw_applet(struct stconn *sc)
|
|||||||
__fallthrough;
|
__fallthrough;
|
||||||
default:
|
default:
|
||||||
sc->flags &= ~SC_FL_NOLINGER;
|
sc->flags &= ~SC_FL_NOLINGER;
|
||||||
ic->flags |= CF_SHUTR;
|
chn_prod(ic)->flags |= SC_FL_SHUTR;
|
||||||
if (sc->flags & SC_FL_ISBACK)
|
if (sc->flags & SC_FL_ISBACK)
|
||||||
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
__sc_strm(sc)->conn_exp = TICK_ETERNITY;
|
||||||
}
|
}
|
||||||
@ -944,7 +952,7 @@ static void sc_app_chk_snd_applet(struct stconn *sc)
|
|||||||
|
|
||||||
BUG_ON(!sc_appctx(sc));
|
BUG_ON(!sc_appctx(sc));
|
||||||
|
|
||||||
if (unlikely(sc->state != SC_ST_EST || (oc->flags & CF_SHUTW)))
|
if (unlikely(sc->state != SC_ST_EST || (chn_cons(oc)->flags & SC_FL_SHUTW)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* we only wake the applet up if it was waiting for some data and is ready to consume it */
|
/* we only wake the applet up if it was waiting for some data and is ready to consume it */
|
||||||
@ -971,7 +979,7 @@ void sc_update_rx(struct stconn *sc)
|
|||||||
{
|
{
|
||||||
struct channel *ic = sc_ic(sc);
|
struct channel *ic = sc_ic(sc);
|
||||||
|
|
||||||
if (ic->flags & CF_SHUTR)
|
if (chn_prod(ic)->flags & SC_FL_SHUTR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Read not closed, update FD status and timeout for reads */
|
/* Read not closed, update FD status and timeout for reads */
|
||||||
@ -996,14 +1004,14 @@ void sc_update_tx(struct stconn *sc)
|
|||||||
{
|
{
|
||||||
struct channel *oc = sc_oc(sc);
|
struct channel *oc = sc_oc(sc);
|
||||||
|
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Write not closed, update FD status and timeout for writes */
|
/* Write not closed, update FD status and timeout for writes */
|
||||||
if (channel_is_empty(oc)) {
|
if (channel_is_empty(oc)) {
|
||||||
/* stop writing */
|
/* stop writing */
|
||||||
if (!sc_ep_test(sc, SE_FL_WAIT_DATA)) {
|
if (!sc_ep_test(sc, SE_FL_WAIT_DATA)) {
|
||||||
if ((oc->flags & CF_SHUTW_NOW) == 0)
|
if ((chn_cons(oc)->flags & SC_FL_SHUTW_NOW) == 0)
|
||||||
sc_ep_set(sc, SE_FL_WAIT_DATA);
|
sc_ep_set(sc, SE_FL_WAIT_DATA);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -1034,17 +1042,17 @@ static void sc_notify(struct stconn *sc)
|
|||||||
if (channel_is_empty(oc)) {
|
if (channel_is_empty(oc)) {
|
||||||
struct connection *conn = sc_conn(sc);
|
struct connection *conn = sc_conn(sc);
|
||||||
|
|
||||||
if (((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW) &&
|
if (((chn_cons(oc)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) == SC_FL_SHUTW_NOW) &&
|
||||||
(sc->state == SC_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS))))
|
(sc->state == SC_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS))))
|
||||||
sc_shutw(sc);
|
sc_shutw(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* indicate that we may be waiting for data from the output channel or
|
/* indicate that we may be waiting for data from the output channel or
|
||||||
* we're about to close and can't expect more data if SHUTW_NOW is there.
|
* we're about to close and can't expect more data if SC_FL_SHUTW_NOW is there.
|
||||||
*/
|
*/
|
||||||
if (!(oc->flags & (CF_SHUTW|CF_SHUTW_NOW)))
|
if (!(chn_cons(oc)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
|
||||||
sc_ep_set(sc, SE_FL_WAIT_DATA);
|
sc_ep_set(sc, SE_FL_WAIT_DATA);
|
||||||
else if ((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW)
|
else if ((chn_cons(oc)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) == SC_FL_SHUTW_NOW)
|
||||||
sc_ep_clr(sc, SE_FL_WAIT_DATA);
|
sc_ep_clr(sc, SE_FL_WAIT_DATA);
|
||||||
|
|
||||||
if (oc->flags & CF_DONT_READ)
|
if (oc->flags & CF_DONT_READ)
|
||||||
@ -1100,18 +1108,19 @@ static void sc_notify(struct stconn *sc)
|
|||||||
* data received and no fast-forwarding (CF_READ_EVENT + !to_forward)
|
* 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)
|
* 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) || (ic->flags & CF_SHUTR) || !ic->to_forward || sco->state != SC_ST_EST)) ||
|
((ic->flags & CF_READ_EVENT) && ((sc->flags & SC_FL_EOI) || (chn_prod(ic)->flags & SC_FL_SHUTR) || !ic->to_forward || sco->state != SC_ST_EST)) ||
|
||||||
sc_ep_test(sc, SE_FL_ERROR) ||
|
sc_ep_test(sc, SE_FL_ERROR) ||
|
||||||
|
|
||||||
/* changes on the consumption side */
|
/* changes on the consumption side */
|
||||||
sc_ep_test(sc, SE_FL_ERR_PENDING) ||
|
sc_ep_test(sc, SE_FL_ERR_PENDING) ||
|
||||||
((oc->flags & CF_WRITE_EVENT) &&
|
((oc->flags & CF_WRITE_EVENT) &&
|
||||||
((sc->state < SC_ST_EST) ||
|
((sc->state < SC_ST_EST) ||
|
||||||
(oc->flags & CF_SHUTW) ||
|
(chn_cons(oc)->flags & SC_FL_SHUTW) ||
|
||||||
(((oc->flags & CF_WAKE_WRITE) ||
|
(((oc->flags & CF_WAKE_WRITE) ||
|
||||||
!(oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW|CF_SHUTW))) &&
|
(!(oc->flags & CF_AUTO_CLOSE) &&
|
||||||
(sco->state != SC_ST_EST ||
|
!(chn_cons(oc)->flags & (SC_FL_SHUTW_NOW|SC_FL_SHUTW)))) &&
|
||||||
(channel_is_empty(oc) && !oc->to_forward)))))) {
|
(sco->state != SC_ST_EST ||
|
||||||
|
(channel_is_empty(oc) && !oc->to_forward)))))) {
|
||||||
task_wakeup(task, TASK_WOKEN_IO);
|
task_wakeup(task, TASK_WOKEN_IO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1131,15 +1140,16 @@ static void sc_conn_read0(struct stconn *sc)
|
|||||||
|
|
||||||
BUG_ON(!sc_conn(sc));
|
BUG_ON(!sc_conn(sc));
|
||||||
|
|
||||||
if (ic->flags & CF_SHUTR)
|
if (chn_prod(ic)->flags & SC_FL_SHUTR)
|
||||||
return;
|
return;
|
||||||
ic->flags |= CF_SHUTR|CF_READ_EVENT;
|
chn_prod(ic)->flags |= SC_FL_SHUTR;
|
||||||
|
ic->flags |= CF_READ_EVENT;
|
||||||
sc_ep_report_read_activity(sc);
|
sc_ep_report_read_activity(sc);
|
||||||
|
|
||||||
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
goto do_close;
|
goto do_close;
|
||||||
|
|
||||||
if (sc_cond_forward_shutw(sc)) {
|
if (sc_cond_forward_shutw(sc)) {
|
||||||
@ -1156,8 +1166,8 @@ static void sc_conn_read0(struct stconn *sc)
|
|||||||
/* OK we completely close the socket here just as if we went through sc_shut[rw]() */
|
/* OK we completely close the socket here just as if we went through sc_shut[rw]() */
|
||||||
sc_conn_shut(sc);
|
sc_conn_shut(sc);
|
||||||
|
|
||||||
oc->flags &= ~CF_SHUTW_NOW;
|
chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
|
||||||
oc->flags |= CF_SHUTW;
|
chn_cons(oc)->flags |= SC_FL_SHUTW;
|
||||||
|
|
||||||
sc->state = SC_ST_DIS;
|
sc->state = SC_ST_DIS;
|
||||||
if (sc->flags & SC_FL_ISBACK)
|
if (sc->flags & SC_FL_ISBACK)
|
||||||
@ -1189,7 +1199,7 @@ static int sc_conn_recv(struct stconn *sc)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* maybe we were called immediately after an asynchronous shutr */
|
/* maybe we were called immediately after an asynchronous shutr */
|
||||||
if (ic->flags & CF_SHUTR)
|
if (chn_prod(ic)->flags & SC_FL_SHUTR)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* we must wait because the mux is not installed yet */
|
/* we must wait because the mux is not installed yet */
|
||||||
@ -1320,7 +1330,7 @@ static int sc_conn_recv(struct stconn *sc)
|
|||||||
*/
|
*/
|
||||||
while (sc_ep_test(sc, SE_FL_RCV_MORE) ||
|
while (sc_ep_test(sc, SE_FL_RCV_MORE) ||
|
||||||
(!(conn->flags & CO_FL_HANDSHAKE) &&
|
(!(conn->flags & CO_FL_HANDSHAKE) &&
|
||||||
(!sc_ep_test(sc, SE_FL_ERROR | SE_FL_EOS)) && !(ic->flags & CF_SHUTR))) {
|
(!sc_ep_test(sc, SE_FL_ERROR | SE_FL_EOS)) && !(chn_prod(ic)->flags & SC_FL_SHUTR))) {
|
||||||
int cur_flags = flags;
|
int cur_flags = flags;
|
||||||
|
|
||||||
/* Compute transient CO_RFL_* flags */
|
/* Compute transient CO_RFL_* flags */
|
||||||
@ -1361,7 +1371,7 @@ static int sc_conn_recv(struct stconn *sc)
|
|||||||
cur_read += ret;
|
cur_read += ret;
|
||||||
|
|
||||||
/* if we're allowed to directly forward data, we must update ->o */
|
/* if we're allowed to directly forward data, we must update ->o */
|
||||||
if (ic->to_forward && !(ic->flags & (CF_SHUTW|CF_SHUTW_NOW))) {
|
if (ic->to_forward && !(chn_cons(ic)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))) {
|
||||||
unsigned long fwd = ret;
|
unsigned long fwd = ret;
|
||||||
if (ic->to_forward != CHN_INFINITE_FORWARD) {
|
if (ic->to_forward != CHN_INFINITE_FORWARD) {
|
||||||
if (fwd > ic->to_forward)
|
if (fwd > ic->to_forward)
|
||||||
@ -1484,7 +1494,7 @@ static int sc_conn_recv(struct stconn *sc)
|
|||||||
if (sc_ep_test(sc, SE_FL_ERROR))
|
if (sc_ep_test(sc, SE_FL_ERROR))
|
||||||
ret = 1;
|
ret = 1;
|
||||||
else if (!(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)) &&
|
else if (!(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)) &&
|
||||||
!(ic->flags & CF_SHUTR)) {
|
!(chn_prod(ic)->flags & SC_FL_SHUTR)) {
|
||||||
/* Subscribe to receive events if we're blocking on I/O */
|
/* Subscribe to receive events if we're blocking on I/O */
|
||||||
conn->mux->subscribe(sc, SUB_RETRY_RECV, &sc->wait_event);
|
conn->mux->subscribe(sc, SUB_RETRY_RECV, &sc->wait_event);
|
||||||
se_have_no_more_data(sc->sedesc);
|
se_have_no_more_data(sc->sedesc);
|
||||||
@ -1554,7 +1564,7 @@ static int sc_conn_send(struct stconn *sc)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* we might have been called just after an asynchronous shutw */
|
/* we might have been called just after an asynchronous shutw */
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* we must wait because the mux is not installed yet */
|
/* we must wait because the mux is not installed yet */
|
||||||
@ -1599,9 +1609,10 @@ static int sc_conn_send(struct stconn *sc)
|
|||||||
((oc->to_forward && oc->to_forward != CHN_INFINITE_FORWARD) ||
|
((oc->to_forward && oc->to_forward != CHN_INFINITE_FORWARD) ||
|
||||||
(sc->flags & SC_FL_SND_EXP_MORE) ||
|
(sc->flags & SC_FL_SND_EXP_MORE) ||
|
||||||
(IS_HTX_STRM(s) &&
|
(IS_HTX_STRM(s) &&
|
||||||
(!(sco->flags & SC_FL_EOI) && !(oc->flags & CF_SHUTR) && htx_expect_more(htxbuf(&oc->buf)))))) ||
|
(!(sco->flags & SC_FL_EOI) && !(chn_prod(oc)->flags & SC_FL_SHUTR) && htx_expect_more(htxbuf(&oc->buf)))))) ||
|
||||||
((oc->flags & CF_ISRESP) &&
|
((oc->flags & CF_ISRESP) &&
|
||||||
((oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW)) == (CF_AUTO_CLOSE|CF_SHUTW_NOW))))
|
(oc->flags & CF_AUTO_CLOSE) &&
|
||||||
|
(chn_cons(oc)->flags & SC_FL_SHUTW_NOW)))
|
||||||
send_flag |= CO_SFL_MSG_MORE;
|
send_flag |= CO_SFL_MSG_MORE;
|
||||||
|
|
||||||
if (oc->flags & CF_STREAMER)
|
if (oc->flags & CF_STREAMER)
|
||||||
@ -1685,7 +1696,7 @@ void sc_conn_sync_send(struct stconn *sc)
|
|||||||
|
|
||||||
oc->flags &= ~CF_WRITE_EVENT;
|
oc->flags &= ~CF_WRITE_EVENT;
|
||||||
|
|
||||||
if (oc->flags & CF_SHUTW)
|
if (chn_cons(oc)->flags & SC_FL_SHUTW)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (channel_is_empty(oc))
|
if (channel_is_empty(oc))
|
||||||
@ -1763,7 +1774,7 @@ static int sc_conn_process(struct stconn *sc)
|
|||||||
* wake callback. Otherwise sc_conn_recv()/sc_conn_send() already take
|
* wake callback. Otherwise sc_conn_recv()/sc_conn_send() already take
|
||||||
* care of it.
|
* care of it.
|
||||||
*/
|
*/
|
||||||
if (sc_ep_test(sc, SE_FL_EOS) && !(ic->flags & CF_SHUTR)) {
|
if (sc_ep_test(sc, SE_FL_EOS) && !(chn_prod(ic)->flags & SC_FL_SHUTR)) {
|
||||||
/* we received a shutdown */
|
/* we received a shutdown */
|
||||||
if (ic->flags & CF_AUTO_CLOSE)
|
if (ic->flags & CF_AUTO_CLOSE)
|
||||||
channel_shutw_now(ic);
|
channel_shutw_now(ic);
|
||||||
@ -1842,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
|
/* If the applet wants to write and the channel is closed, it's a
|
||||||
* broken pipe and it must be reported.
|
* broken pipe and it must be reported.
|
||||||
*/
|
*/
|
||||||
if (!sc_ep_test(sc, SE_FL_HAVE_NO_DATA) && (ic->flags & CF_SHUTR))
|
if (!sc_ep_test(sc, SE_FL_HAVE_NO_DATA) && (chn_prod(ic)->flags & SC_FL_SHUTR))
|
||||||
sc_ep_set(sc, SE_FL_ERROR);
|
sc_ep_set(sc, SE_FL_ERROR);
|
||||||
|
|
||||||
/* automatically mark the applet having data available if it reported
|
/* automatically mark the applet having data available if it reported
|
||||||
|
@ -5043,8 +5043,8 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
* - STATE_DONE : nothing left to dump, the buffer may contain some
|
* - STATE_DONE : nothing left to dump, the buffer may contain some
|
||||||
* data though.
|
* data though.
|
||||||
*/
|
*/
|
||||||
|
/* FIXME: Don't watch the other side !*/
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW)) {
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW)) {
|
||||||
/* in case of abort, remove any refcount we might have set on an entry */
|
/* in case of abort, remove any refcount we might have set on an entry */
|
||||||
if (ctx->state == STATE_DUMP) {
|
if (ctx->state == STATE_DUMP) {
|
||||||
stksess_kill_if_expired(ctx->t, ctx->entry, 1);
|
stksess_kill_if_expired(ctx->t, ctx->entry, 1);
|
||||||
|
129
src/stream.c
129
src/stream.c
@ -879,7 +879,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_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.
|
* 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
|
* Note that it will switch the interface to SC_ST_DIS if we already have
|
||||||
* the CF_SHUTR flag, it means we were able to forward the request, and
|
* the SC_FL_SHUTR flag, it means we were able to forward the request, and
|
||||||
* receive the response, before process_stream() had the opportunity to
|
* 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
|
* 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.
|
* to go through back_establish() anyway, to make sure the analysers run.
|
||||||
@ -948,7 +948,7 @@ static void back_establish(struct stream *s)
|
|||||||
}
|
}
|
||||||
/* If we managed to get the whole response, and we don't have anything
|
/* 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. */
|
* left to send, or can't, switch to SC_ST_DIS now. */
|
||||||
if (rep->flags & (CF_SHUTR | CF_SHUTW)) {
|
if ((s->scb->flags & SC_FL_SHUTR) || (s->scf->flags & SC_FL_SHUTW)) {
|
||||||
s->scb->state = SC_ST_DIS;
|
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);
|
DBG_TRACE_STATE("response channel shutdwn for read/write", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
|
||||||
}
|
}
|
||||||
@ -1578,12 +1578,12 @@ static void stream_handle_timeouts(struct stream *s)
|
|||||||
|
|
||||||
sc_check_timeouts(s->scf);
|
sc_check_timeouts(s->scf);
|
||||||
channel_check_timeout(&s->req);
|
channel_check_timeout(&s->req);
|
||||||
if (unlikely((s->req.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
|
if (unlikely(!(s->scb->flags & SC_FL_SHUTW) && (s->req.flags & CF_WRITE_TIMEOUT))) {
|
||||||
s->scb->flags |= SC_FL_NOLINGER;
|
s->scb->flags |= SC_FL_NOLINGER;
|
||||||
sc_shutw(s->scb);
|
sc_shutw(s->scb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely((s->req.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
|
if (unlikely(!(s->scf->flags & SC_FL_SHUTR) && (s->req.flags & CF_READ_TIMEOUT))) {
|
||||||
if (s->scf->flags & SC_FL_NOHALF)
|
if (s->scf->flags & SC_FL_NOHALF)
|
||||||
s->scf->flags |= SC_FL_NOLINGER;
|
s->scf->flags |= SC_FL_NOLINGER;
|
||||||
sc_shutr(s->scf);
|
sc_shutr(s->scf);
|
||||||
@ -1591,16 +1591,16 @@ static void stream_handle_timeouts(struct stream *s)
|
|||||||
|
|
||||||
sc_check_timeouts(s->scb);
|
sc_check_timeouts(s->scb);
|
||||||
channel_check_timeout(&s->res);
|
channel_check_timeout(&s->res);
|
||||||
if (unlikely((s->res.flags & (CF_SHUTW|CF_WRITE_TIMEOUT)) == CF_WRITE_TIMEOUT)) {
|
if (unlikely(!(s->scf->flags & SC_FL_SHUTW) && (s->res.flags & CF_WRITE_TIMEOUT))) {
|
||||||
s->scf->flags |= SC_FL_NOLINGER;
|
s->scf->flags |= SC_FL_NOLINGER;
|
||||||
sc_shutw(s->scf);
|
sc_shutw(s->scf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely((s->res.flags & (CF_SHUTR|CF_READ_TIMEOUT)) == CF_READ_TIMEOUT)) {
|
if (unlikely(!(s->scb->flags & SC_FL_SHUTR) && (s->res.flags & CF_READ_TIMEOUT))) {
|
||||||
if (s->scb->flags & SC_FL_NOHALF)
|
if (s->scb->flags & SC_FL_NOHALF)
|
||||||
s->scb->flags |= SC_FL_NOLINGER;
|
s->scb->flags |= SC_FL_NOLINGER;
|
||||||
sc_shutr(s->scb);
|
sc_shutr(s->scb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HAS_FILTERS(s))
|
if (HAS_FILTERS(s))
|
||||||
flt_stream_check_timeouts(s);
|
flt_stream_check_timeouts(s);
|
||||||
@ -1711,6 +1711,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
struct server *srv;
|
struct server *srv;
|
||||||
struct stream *s = context;
|
struct stream *s = context;
|
||||||
struct session *sess = s->sess;
|
struct session *sess = s->sess;
|
||||||
|
unsigned int scf_flags, scb_flags;
|
||||||
unsigned int rqf_last, rpf_last;
|
unsigned int rqf_last, rpf_last;
|
||||||
unsigned int rq_prod_last, rq_cons_last;
|
unsigned int rq_prod_last, rq_cons_last;
|
||||||
unsigned int rp_cons_last, rp_prod_last;
|
unsigned int rp_cons_last, rp_prod_last;
|
||||||
@ -1760,6 +1761,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
scf->flags |= SC_FL_DONT_WAKE;
|
scf->flags |= SC_FL_DONT_WAKE;
|
||||||
scb->flags |= SC_FL_DONT_WAKE;
|
scb->flags |= SC_FL_DONT_WAKE;
|
||||||
|
|
||||||
|
/* Keep a copy of SC flags */
|
||||||
|
scf_flags = scf->flags;
|
||||||
|
scb_flags = scb->flags;
|
||||||
|
|
||||||
/* update pending events */
|
/* update pending events */
|
||||||
s->pending_events |= (state & TASK_WOKEN_ANY);
|
s->pending_events |= (state & TASK_WOKEN_ANY);
|
||||||
|
|
||||||
@ -1774,9 +1779,8 @@ 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
|
* So let's not run a whole stream processing if only an expiration
|
||||||
* timeout needs to be refreshed.
|
* timeout needs to be refreshed.
|
||||||
*/
|
*/
|
||||||
if (!((req->flags | res->flags) &
|
if (!((scf->flags | scb->flags) & (SC_FL_SHUTR|SC_FL_SHUTW)) &&
|
||||||
(CF_SHUTR|CF_READ_EVENT|CF_READ_TIMEOUT|CF_SHUTW|
|
!((req->flags | res->flags) & (CF_READ_EVENT|CF_READ_TIMEOUT|CF_WRITE_EVENT|CF_WRITE_TIMEOUT)) &&
|
||||||
CF_WRITE_EVENT|CF_WRITE_TIMEOUT)) &&
|
|
||||||
!(s->flags & SF_CONN_EXP) &&
|
!(s->flags & SF_CONN_EXP) &&
|
||||||
!((sc_ep_get(scf) | scb->flags) & SE_FL_ERROR) &&
|
!((sc_ep_get(scf) | scb->flags) & SE_FL_ERROR) &&
|
||||||
((s->pending_events & TASK_WOKEN_ANY) == TASK_WOKEN_TIMER)) {
|
((s->pending_events & TASK_WOKEN_ANY) == TASK_WOKEN_TIMER)) {
|
||||||
@ -1946,12 +1950,14 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
resync_request:
|
resync_request:
|
||||||
/* Analyse request */
|
/* Analyse request */
|
||||||
if (((req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
|
if (((req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
|
||||||
((req->flags ^ rqf_last) & CF_MASK_STATIC) ||
|
((scf->flags ^ scf_flags) & (SC_FL_SHUTR|SC_FL_SHUTR_NOW)) ||
|
||||||
(req->analysers && (req->flags & CF_SHUTW)) ||
|
((scb->flags ^ scb_flags) & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) ||
|
||||||
|
(req->analysers && (chn_cons(req)->flags & SC_FL_SHUTW)) ||
|
||||||
scf->state != rq_prod_last ||
|
scf->state != rq_prod_last ||
|
||||||
scb->state != rq_cons_last ||
|
scb->state != rq_cons_last ||
|
||||||
s->pending_events & TASK_WOKEN_MSG) {
|
s->pending_events & TASK_WOKEN_MSG) {
|
||||||
unsigned int flags = req->flags;
|
unsigned int scf_flags_ana = scf->flags;
|
||||||
|
unsigned int scb_flags_ana = scb->flags;
|
||||||
|
|
||||||
if (sc_state_in(scf->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) {
|
if (sc_state_in(scf->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) {
|
||||||
int max_loops = global.tune.maxpollevents;
|
int max_loops = global.tune.maxpollevents;
|
||||||
@ -2032,8 +2038,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
rq_cons_last = scb->state;
|
rq_cons_last = scb->state;
|
||||||
req->flags &= ~CF_WAKE_ONCE;
|
req->flags &= ~CF_WAKE_ONCE;
|
||||||
rqf_last = req->flags;
|
rqf_last = req->flags;
|
||||||
|
scf_flags = (scf_flags & ~(SC_FL_SHUTR|SC_FL_SHUTR_NOW)) | (scf->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW));
|
||||||
|
scb_flags = (scb_flags & ~(SC_FL_SHUTW|SC_FL_SHUTW_NOW)) | (scb->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW));
|
||||||
|
|
||||||
if ((req->flags ^ flags) & (CF_SHUTR|CF_SHUTW))
|
if (((scf->flags ^ scf_flags_ana) & SC_FL_SHUTR) || ((scb->flags ^ scb_flags_ana) & SC_FL_SHUTW))
|
||||||
goto resync_request;
|
goto resync_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2047,12 +2055,14 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
/* Analyse response */
|
/* Analyse response */
|
||||||
|
|
||||||
if (((res->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
|
if (((res->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
|
||||||
(res->flags ^ rpf_last) & CF_MASK_STATIC ||
|
((scb->flags ^ scb_flags) & (SC_FL_SHUTR|SC_FL_SHUTR_NOW)) ||
|
||||||
(res->analysers && (res->flags & CF_SHUTW)) ||
|
((scf->flags ^ scf_flags) & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) ||
|
||||||
scf->state != rp_cons_last ||
|
(res->analysers && (chn_cons(res)->flags & SC_FL_SHUTW)) ||
|
||||||
scb->state != rp_prod_last ||
|
scf->state != rp_cons_last ||
|
||||||
s->pending_events & TASK_WOKEN_MSG) {
|
scb->state != rp_prod_last ||
|
||||||
unsigned int flags = res->flags;
|
s->pending_events & TASK_WOKEN_MSG) {
|
||||||
|
unsigned int scb_flags_ana = scb->flags;
|
||||||
|
unsigned int scf_flags_ana = scf->flags;
|
||||||
|
|
||||||
if (sc_state_in(scb->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) {
|
if (sc_state_in(scb->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) {
|
||||||
int max_loops = global.tune.maxpollevents;
|
int max_loops = global.tune.maxpollevents;
|
||||||
@ -2101,8 +2111,10 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
rp_prod_last = scb->state;
|
rp_prod_last = scb->state;
|
||||||
res->flags &= ~CF_WAKE_ONCE;
|
res->flags &= ~CF_WAKE_ONCE;
|
||||||
rpf_last = res->flags;
|
rpf_last = res->flags;
|
||||||
|
scb_flags = (scb_flags & ~(SC_FL_SHUTR|SC_FL_SHUTR_NOW)) | (scb->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW));
|
||||||
|
scf_flags = (scf_flags & ~(SC_FL_SHUTW|SC_FL_SHUTW_NOW)) | (scf->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW));
|
||||||
|
|
||||||
if ((res->flags ^ flags) & (CF_SHUTR|CF_SHUTW))
|
if (((scb->flags ^ scb_flags_ana) & SC_FL_SHUTR) || ((scf->flags ^ scf_flags_ana) & SC_FL_SHUTW))
|
||||||
goto resync_response;
|
goto resync_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2212,13 +2224,13 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
|
|
||||||
/* If no one is interested in analysing data, it's time to forward
|
/* If no one is interested in analysing data, it's time to forward
|
||||||
* everything. We configure the buffer to forward indefinitely.
|
* everything. We configure the buffer to forward indefinitely.
|
||||||
* Note that we're checking CF_SHUTR_NOW as an indication of a possible
|
* Note that we're checking SC_FL_SHUTR_NOW as an indication of a possible
|
||||||
* recent call to channel_abort().
|
* recent call to channel_abort().
|
||||||
*/
|
*/
|
||||||
if (unlikely((!req->analysers || (req->analysers == AN_REQ_FLT_END && !(req->flags & CF_FLT_ANALYZE))) &&
|
if (unlikely((!req->analysers || (req->analysers == AN_REQ_FLT_END && !(req->flags & CF_FLT_ANALYZE))) &&
|
||||||
!(req->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
|
!(scf->flags & SC_FL_SHUTR_NOW) && !(scb->flags & SC_FL_SHUTW) &&
|
||||||
(sc_state_in(scf->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) &&
|
(sc_state_in(scf->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) &&
|
||||||
(req->to_forward != CHN_INFINITE_FORWARD))) {
|
(req->to_forward != CHN_INFINITE_FORWARD))) {
|
||||||
/* This buffer is freewheeling, there's no analyser
|
/* This buffer is freewheeling, there's no analyser
|
||||||
* attached to it. If any data are left in, we'll permit them to
|
* attached to it. If any data are left in, we'll permit them to
|
||||||
* move.
|
* move.
|
||||||
@ -2234,7 +2246,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
* to the consumer.
|
* to the consumer.
|
||||||
*/
|
*/
|
||||||
co_set_data(req, htx->data);
|
co_set_data(req, htx->data);
|
||||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) && !(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||||
|
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUTW_NOW))
|
||||||
channel_htx_forward_forever(req, htx);
|
channel_htx_forward_forever(req, htx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2242,13 +2255,15 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
* to the consumer (which might possibly not be connected yet).
|
* to the consumer (which might possibly not be connected yet).
|
||||||
*/
|
*/
|
||||||
c_adv(req, ci_data(req));
|
c_adv(req, ci_data(req));
|
||||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) && !(req->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||||
|
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUTW_NOW))
|
||||||
channel_forward_forever(req);
|
channel_forward_forever(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if it is wise to enable kernel splicing to forward request data */
|
/* check if it is wise to enable kernel splicing to forward request data */
|
||||||
if (!(req->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
|
if (!(req->flags & CF_KERN_SPLICING) &&
|
||||||
|
!(scf->flags & SC_FL_SHUTR) &&
|
||||||
req->to_forward &&
|
req->to_forward &&
|
||||||
(global.tune.options & GTUNE_USE_SPLICE) &&
|
(global.tune.options & GTUNE_USE_SPLICE) &&
|
||||||
(sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->rcv_pipe &&
|
(sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->rcv_pipe &&
|
||||||
@ -2264,6 +2279,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
|
|
||||||
/* reflect what the L7 analysers have seen last */
|
/* reflect what the L7 analysers have seen last */
|
||||||
rqf_last = req->flags;
|
rqf_last = req->flags;
|
||||||
|
scf_flags = (scf_flags & ~(SC_FL_SHUTR|SC_FL_SHUTR_NOW)) | (scf->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW));
|
||||||
|
scb_flags = (scb_flags & ~(SC_FL_SHUTW|SC_FL_SHUTW_NOW)) | (scb->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW));
|
||||||
|
|
||||||
/* it's possible that an upper layer has requested a connection setup or abort.
|
/* it's possible that an upper layer has requested a connection setup or abort.
|
||||||
* There are 2 situations where we decide to establish a new connection :
|
* There are 2 situations where we decide to establish a new connection :
|
||||||
@ -2271,7 +2288,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
* - the CF_AUTO_CONNECT flag is set (active connection)
|
* - the CF_AUTO_CONNECT flag is set (active connection)
|
||||||
*/
|
*/
|
||||||
if (scb->state == SC_ST_INI) {
|
if (scb->state == SC_ST_INI) {
|
||||||
if (!(req->flags & CF_SHUTW)) {
|
if (!(scb->flags & SC_FL_SHUTW)) {
|
||||||
if ((req->flags & CF_AUTO_CONNECT) || !channel_is_empty(req)) {
|
if ((req->flags & CF_AUTO_CONNECT) || !channel_is_empty(req)) {
|
||||||
/* If we have an appctx, there is no connect method, so we
|
/* If we have an appctx, there is no connect method, so we
|
||||||
* immediately switch to the connected state, otherwise we
|
* immediately switch to the connected state, otherwise we
|
||||||
@ -2343,14 +2360,14 @@ 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
|
* the other side's timeout as well. However this doesn't have effect during the
|
||||||
* connection setup unless the backend has abortonclose set.
|
* connection setup unless the backend has abortonclose set.
|
||||||
*/
|
*/
|
||||||
if (unlikely((req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
|
if (unlikely((req->flags & CF_AUTO_CLOSE) && (scf->flags & SC_FL_SHUTR) &&
|
||||||
(CF_AUTO_CLOSE|CF_SHUTR) &&
|
!(scb->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) &&
|
||||||
(scb->state != SC_ST_CON || (s->be->options & PR_O_ABRT_CLOSE)))) {
|
(scb->state != SC_ST_CON || (s->be->options & PR_O_ABRT_CLOSE)))) {
|
||||||
channel_shutw_now(req);
|
channel_shutw_now(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shutdown(write) pending */
|
/* shutdown(write) pending */
|
||||||
if (unlikely((req->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
|
if (unlikely((scb->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) == SC_FL_SHUTW_NOW &&
|
||||||
channel_is_empty(req))) {
|
channel_is_empty(req))) {
|
||||||
if (sc_ep_test(s->scf, SE_FL_ERROR))
|
if (sc_ep_test(s->scf, SE_FL_ERROR))
|
||||||
scb->flags |= SC_FL_NOLINGER;
|
scb->flags |= SC_FL_NOLINGER;
|
||||||
@ -2358,12 +2375,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 */
|
/* shutdown(write) done on server side, we must stop the client too */
|
||||||
if (unlikely((req->flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW &&
|
if (unlikely((scb->flags & SC_FL_SHUTW) && !(scf->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW))) &&
|
||||||
!req->analysers))
|
!req->analysers)
|
||||||
channel_shutr_now(req);
|
channel_shutr_now(req);
|
||||||
|
|
||||||
/* shutdown(read) pending */
|
/* shutdown(read) pending */
|
||||||
if (unlikely((req->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
|
if (unlikely((scf->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW)) == SC_FL_SHUTR_NOW)) {
|
||||||
if (scf->flags & SC_FL_NOHALF)
|
if (scf->flags & SC_FL_NOHALF)
|
||||||
scf->flags |= SC_FL_NOLINGER;
|
scf->flags |= SC_FL_NOLINGER;
|
||||||
sc_shutr(scf);
|
sc_shutr(scf);
|
||||||
@ -2377,20 +2394,20 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
goto resync_stconns;
|
goto resync_stconns;
|
||||||
|
|
||||||
/* otherwise we want to check if we need to resync the req buffer or not */
|
/* otherwise we want to check if we need to resync the req buffer or not */
|
||||||
if ((req->flags ^ rqf_last) & (CF_SHUTR|CF_SHUTW))
|
if (((scf->flags ^ scf_flags) & SC_FL_SHUTR) || ((scb->flags ^ scb_flags) & SC_FL_SHUTW))
|
||||||
goto resync_request;
|
goto resync_request;
|
||||||
|
|
||||||
/* perform output updates to the response buffer */
|
/* perform output updates to the response buffer */
|
||||||
|
|
||||||
/* If no one is interested in analysing data, it's time to forward
|
/* If no one is interested in analysing data, it's time to forward
|
||||||
* everything. We configure the buffer to forward indefinitely.
|
* everything. We configure the buffer to forward indefinitely.
|
||||||
* Note that we're checking CF_SHUTR_NOW as an indication of a possible
|
* Note that we're checking SC_FL_SHUTR_NOW as an indication of a possible
|
||||||
* recent call to channel_abort().
|
* recent call to channel_abort().
|
||||||
*/
|
*/
|
||||||
if (unlikely((!res->analysers || (res->analysers == AN_RES_FLT_END && !(res->flags & CF_FLT_ANALYZE))) &&
|
if (unlikely((!res->analysers || (res->analysers == AN_RES_FLT_END && !(res->flags & CF_FLT_ANALYZE))) &&
|
||||||
!(res->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
|
!(scf->flags & SC_FL_SHUTR_NOW) && !(scb->flags & SC_FL_SHUTW_NOW) &&
|
||||||
sc_state_in(scb->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO) &&
|
sc_state_in(scb->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO) &&
|
||||||
(res->to_forward != CHN_INFINITE_FORWARD))) {
|
(res->to_forward != CHN_INFINITE_FORWARD))) {
|
||||||
/* This buffer is freewheeling, there's no analyser
|
/* This buffer is freewheeling, there's no analyser
|
||||||
* attached to it. If any data are left in, we'll permit them to
|
* attached to it. If any data are left in, we'll permit them to
|
||||||
* move.
|
* move.
|
||||||
@ -2405,7 +2422,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
* to the consumer.
|
* to the consumer.
|
||||||
*/
|
*/
|
||||||
co_set_data(res, htx->data);
|
co_set_data(res, htx->data);
|
||||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) && !(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||||
|
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUTW_NOW))
|
||||||
channel_htx_forward_forever(res, htx);
|
channel_htx_forward_forever(res, htx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2413,7 +2431,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
* to the consumer.
|
* to the consumer.
|
||||||
*/
|
*/
|
||||||
c_adv(res, ci_data(res));
|
c_adv(res, ci_data(res));
|
||||||
if ((global.tune.options & GTUNE_USE_FAST_FWD) && !(res->flags & (CF_SHUTR|CF_SHUTW_NOW)))
|
if ((global.tune.options & GTUNE_USE_FAST_FWD) &&
|
||||||
|
!(scf->flags & SC_FL_SHUTR) && !(scb->flags & SC_FL_SHUTW_NOW))
|
||||||
channel_forward_forever(res);
|
channel_forward_forever(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2424,15 +2443,16 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
if (!req->analysers && s->tunnel_timeout) {
|
if (!req->analysers && s->tunnel_timeout) {
|
||||||
scf->ioto = scb->ioto = s->tunnel_timeout;
|
scf->ioto = scb->ioto = s->tunnel_timeout;
|
||||||
|
|
||||||
if (((req->flags & CF_SHUTR) || (res->flags & CF_SHUTW)) && tick_isset(sess->fe->timeout.clientfin))
|
if ((scf->flags & (SC_FL_SHUTR|SC_FL_SHUTW)) && tick_isset(sess->fe->timeout.clientfin))
|
||||||
scf->ioto = sess->fe->timeout.clientfin;
|
scf->ioto = sess->fe->timeout.clientfin;
|
||||||
if (((res->flags & CF_SHUTR) || (req->flags & CF_SHUTW)) && tick_isset(s->be->timeout.serverfin))
|
if ((scb->flags & (SC_FL_SHUTR|SC_FL_SHUTW)) && tick_isset(s->be->timeout.serverfin))
|
||||||
scb->ioto = s->be->timeout.serverfin;
|
scb->ioto = s->be->timeout.serverfin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if it is wise to enable kernel splicing to forward response data */
|
/* check if it is wise to enable kernel splicing to forward response data */
|
||||||
if (!(res->flags & (CF_KERN_SPLICING|CF_SHUTR)) &&
|
if (!(res->flags & CF_KERN_SPLICING) &&
|
||||||
|
!(scb->flags & SC_FL_SHUTR) &&
|
||||||
res->to_forward &&
|
res->to_forward &&
|
||||||
(global.tune.options & GTUNE_USE_SPLICE) &&
|
(global.tune.options & GTUNE_USE_SPLICE) &&
|
||||||
(sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->snd_pipe &&
|
(sc_conn(scf) && __sc_conn(scf)->xprt && __sc_conn(scf)->xprt->snd_pipe &&
|
||||||
@ -2448,6 +2468,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
|
|
||||||
/* reflect what the L7 analysers have seen last */
|
/* reflect what the L7 analysers have seen last */
|
||||||
rpf_last = res->flags;
|
rpf_last = res->flags;
|
||||||
|
scb_flags = (scb_flags & ~(SC_FL_SHUTR|SC_FL_SHUTR_NOW)) | (scb->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW));
|
||||||
|
scf_flags = (scf_flags & ~(SC_FL_SHUTW|SC_FL_SHUTW_NOW)) | (scf->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW));
|
||||||
|
|
||||||
/* Let's see if we can send the pending response now */
|
/* Let's see if we can send the pending response now */
|
||||||
sc_conn_sync_send(scf);
|
sc_conn_sync_send(scf);
|
||||||
@ -2461,24 +2483,24 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* first, let's check if the response buffer needs to shutdown(write) */
|
/* first, let's check if the response buffer needs to shutdown(write) */
|
||||||
if (unlikely((res->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
|
if (unlikely((res->flags & CF_AUTO_CLOSE) && (scb->flags & SC_FL_SHUTR) &&
|
||||||
(CF_AUTO_CLOSE|CF_SHUTR))) {
|
!(scf->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))) {
|
||||||
channel_shutw_now(res);
|
channel_shutw_now(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shutdown(write) pending */
|
/* shutdown(write) pending */
|
||||||
if (unlikely((res->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW &&
|
if (unlikely((scf->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) == SC_FL_SHUTW_NOW &&
|
||||||
channel_is_empty(res))) {
|
channel_is_empty(res))) {
|
||||||
sc_shutw(scf);
|
sc_shutw(scf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shutdown(write) done on the client side, we must stop the server too */
|
/* shutdown(write) done on the client side, we must stop the server too */
|
||||||
if (unlikely((res->flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW) &&
|
if (unlikely((scf->flags & SC_FL_SHUTW) && !(scb->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW))) &&
|
||||||
!res->analysers)
|
!res->analysers)
|
||||||
channel_shutr_now(res);
|
channel_shutr_now(res);
|
||||||
|
|
||||||
/* shutdown(read) pending */
|
/* shutdown(read) pending */
|
||||||
if (unlikely((res->flags & (CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTR_NOW)) {
|
if (unlikely((scb->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW)) == SC_FL_SHUTR_NOW)) {
|
||||||
if (scb->flags & SC_FL_NOHALF)
|
if (scb->flags & SC_FL_NOHALF)
|
||||||
scb->flags |= SC_FL_NOLINGER;
|
scb->flags |= SC_FL_NOLINGER;
|
||||||
sc_shutr(scb);
|
sc_shutr(scb);
|
||||||
@ -2493,7 +2515,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
|
|||||||
if ((req->flags & ~rqf_last) & CF_MASK_ANALYSER)
|
if ((req->flags & ~rqf_last) & CF_MASK_ANALYSER)
|
||||||
goto resync_request;
|
goto resync_request;
|
||||||
|
|
||||||
if ((res->flags ^ rpf_last) & CF_MASK_STATIC)
|
if (((scb->flags ^ scb_flags) & (SC_FL_SHUTR|SC_FL_SHUTR_NOW)) ||
|
||||||
|
((scf->flags ^ scf_flags) & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
|
||||||
goto resync_response;
|
goto resync_response;
|
||||||
|
|
||||||
if (((req->flags ^ rqf_last) | (res->flags ^ rpf_last)) & CF_MASK_ANALYSER)
|
if (((req->flags ^ rqf_last) | (res->flags ^ rpf_last)) & CF_MASK_ANALYSER)
|
||||||
@ -2751,7 +2774,7 @@ void default_srv_error(struct stream *s, struct stconn *sc)
|
|||||||
/* kill a stream and set the termination flags to <why> (one of SF_ERR_*) */
|
/* kill a stream and set the termination flags to <why> (one of SF_ERR_*) */
|
||||||
void stream_shutdown(struct stream *stream, int why)
|
void stream_shutdown(struct stream *stream, int why)
|
||||||
{
|
{
|
||||||
if (stream->req.flags & (CF_SHUTW|CF_SHUTW_NOW))
|
if (stream->scb->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
channel_shutw_now(&stream->req);
|
channel_shutw_now(&stream->req);
|
||||||
@ -3576,7 +3599,7 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(sc_ic(sc)->flags & CF_SHUTW)) {
|
if (unlikely(chn_cons(sc_ic(sc))->flags & SC_FL_SHUTW)) {
|
||||||
/* If we're forced to shut down, we might have to remove our
|
/* If we're forced to shut down, we might have to remove our
|
||||||
* reference to the last stream being dumped.
|
* reference to the last stream being dumped.
|
||||||
*/
|
*/
|
||||||
|
@ -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 one rule returns KO, then return KO
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((s->scf->flags & SC_FL_EOI) || (req->flags & CF_SHUTR) || channel_full(req, global.tune.maxrewrite) ||
|
if ((s->scf->flags & (SC_FL_EOI|SC_FL_SHUTR)) || channel_full(req, global.tune.maxrewrite) ||
|
||||||
sc_waiting_room(chn_prod(req)) ||
|
sc_waiting_room(chn_prod(req)) ||
|
||||||
!s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
|
!s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
|
||||||
partial = SMP_OPT_FINAL;
|
partial = SMP_OPT_FINAL;
|
||||||
@ -299,7 +299,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 OK, then return OK
|
||||||
* - if one rule returns KO, then return KO
|
* - if one rule returns KO, then return KO
|
||||||
*/
|
*/
|
||||||
if ((s->scb->flags & SC_FL_EOI) || (rep->flags & CF_SHUTR) || channel_full(rep, global.tune.maxrewrite) ||
|
if ((s->scb->flags & (SC_FL_EOI|SC_FL_SHUTR)) || channel_full(rep, global.tune.maxrewrite) ||
|
||||||
sc_waiting_room(chn_prod(rep)) ||
|
sc_waiting_room(chn_prod(rep)) ||
|
||||||
!s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
|
!s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
|
||||||
partial = SMP_OPT_FINAL;
|
partial = SMP_OPT_FINAL;
|
||||||
|
Loading…
Reference in New Issue
Block a user