]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: tree-wide: Move flags about shut from the channel to the SC
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 3 Apr 2023 16:32:50 +0000 (18:32 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 5 Apr 2023 06:57:06 +0000 (08:57 +0200)
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.

26 files changed:
include/haproxy/channel-t.h
include/haproxy/channel.h
include/haproxy/sc_strm.h
include/haproxy/stconn-t.h
src/activity.c
src/applet.c
src/backend.c
src/channel.c
src/cli.c
src/debug.c
src/filters.c
src/flt_bwlim.c
src/http_ana.c
src/http_fetch.c
src/map.c
src/mworker.c
src/proxy.c
src/quic_conn.c
src/ring.c
src/ssl_ckch.c
src/ssl_crtlist.c
src/stats.c
src/stconn.c
src/stick_table.c
src/stream.c
src/tcp_rules.c

index 32f698300c83ea078fcec28ebf6d57c739b6182e..f876d910182753019a33e6ac1023ec128ee8cf77 100644 (file)
  *   - read-only indicators reported by lower data levels :
  *     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
  * 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,
 #define CF_READ_TIMEOUT   0x00000004  /* timeout while waiting for producer */
 /* unused 0x00000008 */
 
-/* unused: 0x00000010 */
-#define CF_SHUTR          0x00000020  /* producer has already shut down */
-#define CF_SHUTR_NOW      0x00000040  /* the producer must shut down for reads ASAP */
-/* 0x00000080 unused */
+/* unused: 0x00000010 - 0x00000080 */
 
 #define CF_WRITE_EVENT    0x00000100  /* a write event detected on consumer side */
 /* unused: 0x00000200 */
 /* unused 0x00000800 */
 
 #define CF_WAKE_WRITE     0x00001000  /* wake the task up when there's write activity */
-#define CF_SHUTW          0x00002000  /* consumer has already shut down */
-#define CF_SHUTW_NOW      0x00004000  /* the consumer must shut down for writes ASAP */
+/* unused: 0x00002000 - 0x00004000 */
 #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_FAST  0x00020000  /* the consumer seems to eat the stream very fast */
 
 /* Masks which define input events for stream analysers */
 #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
  * below any single-bit flag addition above in the same order via the
  * __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);
        /* flags */
        _(CF_READ_EVENT, _(CF_READ_TIMEOUT,
-       _(CF_SHUTR, _(CF_SHUTR_NOW, _(CF_WRITE_EVENT,
+       _(CF_WRITE_EVENT,
        _(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_KERN_SPLICING,
        _(CF_AUTO_CONNECT, _(CF_DONT_READ,
        _(CF_WAKE_ONCE, _(CF_FLT_ANALYZE,
-       _(CF_ISRESP)))))))))))))))))));
+       _(CF_ISRESP)))))))))))))));
        /* epilogue */
        _(~0U);
        return buf;
index 9cacb923d5b7085511b3937c3abf44aad228671a..1bf21c7a748ca45e1b6ad9eb4bcd3bdb078120ab 100644 (file)
@@ -514,13 +514,13 @@ static inline int channel_may_recv(const struct channel *chn)
 /* Returns true if the channel's input is already closed */
 static inline int channel_input_closed(struct channel *chn)
 {
-       return ((chn->flags & CF_SHUTR) != 0);
+       return ((chn_prod(chn)->flags & SC_FL_SHUTR) != 0);
 }
 
 /* Returns true if the channel's output is already closed */
 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. */
@@ -551,19 +551,20 @@ static inline void channel_htx_erase(struct channel *chn, struct htx *htx)
 /* marks the channel as "shutdown" ASAP for reads */
 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 */
 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 */
 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;
 }
 
@@ -986,8 +987,8 @@ static inline int ci_putstr(struct channel *chn, const char *str)
 static inline int co_getchr(struct channel *chn)
 {
        /* closed or empty + imminent close = -2; empty = -1 */
-       if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
-               if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
+       if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
+               if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
                        return -2;
                return -1;
        }
index 199e8d221efc84458413d7b1c2487744c8a5e356..fbe0968ee48f10a4f0225cdb89270bd6e02149e5 100644 (file)
@@ -288,7 +288,7 @@ static inline int sc_is_recv_allowed(const struct stconn *sc)
 {
        struct channel *ic = sc_ic(sc);
 
-       if (ic->flags & CF_SHUTR)
+       if (chn_prod(ic)->flags & SC_FL_SHUTR)
                return 0;
 
        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);
 
-       if (oc->flags & CF_SHUTW)
+       if (chn_cons(oc)->flags & SC_FL_SHUTW)
                return 0;
 
        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)
 {
-       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;
        if (sc->flags & (SC_FL_EOI|SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM))
                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)
 {
-       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;
        if (sc_ep_test(sc, SE_FL_WONT_CONSUME))
                return 0;
index e97bf83ffc8a299aba3bdc11d07f0d2392b0e4e9..63b882a6c26c2eca5123885c487d428550e3472c 100644 (file)
@@ -109,6 +109,33 @@ static forceinline char *se_show_flags(char *buf, size_t len, const char *delim,
 
 /* stconn flags.
  * 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 {
        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_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_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
@@ -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_DONT_WAKE, _(SC_FL_INDEP_STR, _(SC_FL_WONT_READ,
        _(SC_FL_NEED_BUFF, _(SC_FL_NEED_ROOM,
-       _(SC_FL_RCV_ONCE, _(SC_FL_SND_ASAP, _(SC_FL_SND_NEVERWAIT, _(SC_FL_SND_EXP_MORE)))))))))))));
+        _(SC_FL_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 */
        _(~0U);
        return buf;
index 010fd313ad6bb4a4198457a771cee2fd5c81e859..bfdd6f3e59f0d39b077adb9a693f9f20c84b6fca 100644 (file)
@@ -624,7 +624,8 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
        int max_lines;
        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;
 
        chunk_reset(&trash);
@@ -887,7 +888,8 @@ static int cli_io_handler_show_tasks(struct appctx *appctx)
        int thr, queue;
        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;
 
        /* 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;
        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;
 
        chunk_reset(&trash);
index 3ed3c7a1de0d1b634d71f0ca030c506cd3866968..0c5b40de142e021f1b440978c228eac0809c9939 100644 (file)
@@ -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_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 ...
-             (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);
                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));
index af39fefde1651e01a27aff5cfcdbdaed4d846c1a..4fa5f245e967cf1b2a7ba8ea821dfcb4e49439df 100644 (file)
@@ -1956,7 +1956,7 @@ int srv_redispatch_connect(struct stream *s)
 static int back_may_abort_req(struct channel *req, struct stream *s)
 {
        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))));
 }
 
@@ -2246,8 +2246,8 @@ void back_handle_st_con(struct stream *s)
        DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 
        /* the client might want to abort */
-       if ((rep->flags & CF_SHUTW) ||
-           ((req->flags & CF_SHUTW_NOW) &&
+       if ((chn_cons(rep)->flags & SC_FL_SHUTW) ||
+           ((chn_cons(req)->flags & SC_FL_SHUTW_NOW) &&
             (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
                sc->flags |= SC_FL_NOLINGER;
                sc_shutw(sc);
@@ -2470,8 +2470,8 @@ void back_handle_st_rdy(struct stream *s)
         */
        if (!(req->flags & CF_WROTE_DATA)) {
                /* client abort ? */
-               if ((rep->flags & CF_SHUTW) ||
-                   ((req->flags & CF_SHUTW_NOW) &&
+               if ((chn_cons(rep)->flags & SC_FL_SHUTW) ||
+                   ((chn_cons(req)->flags & SC_FL_SHUTW_NOW) &&
                     (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE)))) {
                        /* give up */
                        sc->flags |= SC_FL_NOLINGER;
index 68360d99d28e17d280938c9e1b9c721164c039e7..70c79311ad6b573947432b8f777bd41dca9578d1 100644 (file)
@@ -206,8 +206,8 @@ int co_getdelim(const struct channel *chn, char *str, int len, const char *delim
        max = len;
 
        /* closed or empty + imminent close = -1; empty = 0 */
-       if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
-               if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
+       if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
+               if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
                        ret = -1;
                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 &&
            (ret < co_data(chn) || channel_may_recv(chn)) &&
            !found &&
-           !(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
+           !(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
                ret = 0;
  out:
        if (max)
@@ -279,8 +279,8 @@ int co_getword(const struct channel *chn, char *str, int len, char sep)
        max = len;
 
        /* closed or empty + imminent close = -1; empty = 0 */
-       if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
-               if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
+       if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
+               if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
                        ret = -1;
                goto out;
        }
@@ -303,7 +303,7 @@ int co_getword(const struct channel *chn, char *str, int len, char sep)
        if (ret > 0 && ret < len &&
            (ret < co_data(chn) || channel_may_recv(chn)) &&
            *(str-1) != sep &&
-           !(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
+           !(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
                ret = 0;
  out:
        if (max)
@@ -330,8 +330,8 @@ int co_getline(const struct channel *chn, char *str, int len)
        max = len;
 
        /* closed or empty + imminent close = -1; empty = 0 */
-       if (unlikely((chn->flags & CF_SHUTW) || channel_is_empty(chn))) {
-               if (chn->flags & (CF_SHUTW|CF_SHUTW_NOW))
+       if (unlikely((chn_cons(chn)->flags & SC_FL_SHUTW) || channel_is_empty(chn))) {
+               if (chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW))
                        ret = -1;
                goto out;
        }
@@ -354,7 +354,7 @@ int co_getline(const struct channel *chn, char *str, int len)
        if (ret > 0 && ret < len &&
            (ret < co_data(chn) || channel_may_recv(chn)) &&
            *(str-1) != '\n' &&
-           !(chn->flags & (CF_SHUTW|CF_SHUTW_NOW)))
+           !(chn_cons(chn)->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))
                ret = 0;
  out:
        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)
 {
-       if (chn->flags & CF_SHUTW)
+       if (chn_cons(chn)->flags & SC_FL_SHUTW)
                return -1;
 
        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 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)
 {
-       if (chn->flags & CF_SHUTW)
+       if (chn_cons(chn)->flags & SC_FL_SHUTW)
                return -1;
 
        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 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)
 {
        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 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
                 * the resulting string is made of the concatenation of
                 * the pending blocks (1 or 2).
@@ -484,7 +484,7 @@ int ci_getblk_nc(const struct channel *chn,
                  char **blk2, size_t *len2)
 {
        if (unlikely(ci_data(chn) == 0)) {
-               if (chn->flags & CF_SHUTR)
+               if (chn_prod(chn)->flags & SC_FL_SHUTR)
                        return -1;
                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
                 * the resulting string is made of the concatenation of
                 * the pending blocks (1 or 2).
index 1c942e1b2fc0a5e3c1a07ef96306044832ad6f03..21d662055b0adda76958340c1b3ae7af7c4a185c 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -1213,7 +1213,8 @@ static int cli_io_handler_show_env(struct appctx *appctx)
        struct stconn *sc = appctx_sc(appctx);
        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;
 
        chunk_reset(&trash);
@@ -1251,7 +1252,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
        int fd = fdctx->fd;
        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;
 
        chunk_reset(&trash);
@@ -2685,7 +2687,7 @@ send_status:
        goto read_again;
 
 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
                  * receive a close from the client, we can leave */
                 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;
 
        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");
                s->req.analysers &= ~AN_REQ_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;
        }
 
-       if (rep->flags & CF_SHUTR) {
+       if (chn_prod(rep)->flags & SC_FL_SHUTR) {
                /* stream cleanup */
 
                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);
 
                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->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_CURR_SESS|SF_REDIRECTABLE|SF_SRV_REUSED);
                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->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_RCV_ONCE; /* one read is usually enough */
 
index 3d159fd3fd7eb1b3307297fe6ca6f18349f7c3ae..5209166ed83ee8fe1bb34b7f352fe0dacb0bc707 100644 (file)
@@ -313,7 +313,8 @@ static int cli_io_handler_show_threads(struct appctx *appctx)
        struct stconn *sc = appctx_sc(appctx);
        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;
 
        if (appctx->st0)
@@ -1160,7 +1161,8 @@ static int debug_iohandler_fd(struct appctx *appctx)
        int ret = 1;
        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;
 
        chunk_reset(&trash);
@@ -1367,7 +1369,8 @@ static int debug_iohandler_memstats(struct appctx *appctx)
        const char *pfx = ctx->match;
        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;
 
        if (!ctx->width) {
index 92aeb3a73509ea6cb2a3a9c8e612f55f485e7e62..7bd52ee43370bcf27f1ee20f2ca82a06d3f21989 100644 (file)
@@ -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
         *  - There is a READ/WRITE timeout
         */
-       if (chn->flags & CF_SHUTW) {
+       if (chn_cons(chn)->flags & SC_FL_SHUTW) {
                ret = 1;
                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)) {
                        ret = 1;
                        goto end;
index e14b774912b17865e3690ed20fe97543ec3a54bd..52fffd5010a02f97a94bdf9fa0932338114b8a46 100644 (file)
@@ -151,7 +151,7 @@ static int bwlim_apply_limit(struct filter *filter, struct channel *chn, unsigne
                 */
                ret = tokens;
                if (tokens < conf->min_size) {
-                       ret = ((chn_prod(chn)->flags & SC_FL_EOI) || (chn->flags & CF_SHUTR))
+                       ret = (chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_SHUTR))
                                ? MIN(len, conf->min_size)
                                : conf->min_size;
 
index 6a309c77c83829a0ef23ba257c3f2b8d33795aae..e319a287d0332b3b906e34d307119f4066ee036e 100644 (file)
@@ -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"
                 * 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.level = 0;
                        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.
         */
        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)) {
                /* Be sure to drain all data from the request channel */
                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))
                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
                 * transfer. */
                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. */
        if (s->be->options & PR_O_ABRT_CLOSE) {
                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;
                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:
        /* 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;
 
  waiting:
        /* 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;
 
        /* 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;
        res = &s->res;
+
        /* Remove any write error from the request, and read error from the response */
-       req->flags &= ~(CF_WRITE_TIMEOUT | CF_SHUTW | CF_SHUTW_NOW);
-       res->flags &= ~(CF_READ_TIMEOUT | CF_SHUTR | CF_READ_EVENT | CF_SHUTR_NOW);
+       s->scf->flags &= ~(SC_FL_SHUTR|SC_FL_SHUTR_NOW);
+       req->flags &= ~CF_WRITE_TIMEOUT;
+       res->flags &= ~(CF_READ_TIMEOUT | CF_READ_EVENT);
        res->analysers &= AN_RES_FLT_END;
        s->conn_err_type = STRM_ET_NONE;
        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->total = 0;
 
+       s->scb->flags &= ~(SC_FL_SHUTW|SC_FL_SHUTW_NOW);
        if (sc_reset_endp(s->scb) < 0) {
                if (!(s->flags & SF_ERR_MASK))
                        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 */
-               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(&s->be->be_counters.cli_aborts);
                        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 */
-               else if (rep->flags & CF_SHUTR) {
+               else if (chn_prod(rep)->flags & SC_FL_SHUTR) {
                        if ((txn->flags & TX_L7_RETRY) &&
                            (s->be->retry_type & PR_RE_DISCONNECTED)) {
                                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))
                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;
                goto ending;
        }
@@ -2101,7 +2106,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
 
        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
                 * the transfer. */
                goto return_cli_abort;
@@ -2117,7 +2122,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
        return 0;
 
   missing_data_or_waiting:
-       if (res->flags & CF_SHUTW)
+       if (chn_cons(res)->flags & SC_FL_SHUTW)
                goto return_cli_abort;
 
        /* 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
         * server abort.
         */
-       if (msg->msg_state < HTTP_MSG_ENDING && res->flags & CF_SHUTR) {
-               if ((s->req.flags & (CF_SHUTR|CF_SHUTW)) == (CF_SHUTR|CF_SHUTW))
+       if (msg->msg_state < HTTP_MSG_ENDING && (chn_prod(res)->flags & SC_FL_SHUTR)) {
+               if ((chn_prod(&s->req)->flags & SC_FL_SHUTR) &&
+                   (chn_cons(&s->req)->flags & SC_FL_SHUTW))
                        goto return_cli_abort;
                /* If we have some pending data, we continue the processing */
                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 */
                if (rule->action_ptr) {
                        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)))
                                act_opts |= ACT_OPT_FINAL;
 
@@ -2833,7 +2839,7 @@ resume_execution:
                /* Always call the action function if defined */
                if (rule->action_ptr) {
                        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)))
                                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 */
-       if (!(chn->flags & CF_SHUTR)) {
+       if (!(chn_prod(chn)->flags & SC_FL_SHUTR)) {
                if (!tick_isset(chn->analyse_exp))
                        chn->analyse_exp = tick_add_ifset(now_ms, time);
                ret = HTTP_RULE_RES_YIELD;
@@ -4270,7 +4276,7 @@ static void http_end_request(struct stream *s)
                            txn->rsp.msg_state != HTTP_MSG_CLOSED)
                                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_shutw_now(chn);
                        }
@@ -4304,7 +4310,7 @@ static void http_end_request(struct stream *s)
 
   check_channel_flags:
        /* 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 */
                txn->req.msg_state = 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
                         * 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_shutw_now(chn);
                        }
@@ -4400,7 +4406,7 @@ static void http_end_response(struct stream *s)
 
   check_channel_flags:
        /* 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 */
                txn->rsp.msg_state = HTTP_MSG_CLOSING;
                goto http_msg_closing;
index 2485eb3449eabb77092811f61211377699865b1a..d75541d8e4e26fc40bba76f024df6ca73e308f31 100644 (file)
@@ -615,7 +615,7 @@ static int smp_fetch_body(const struct arg *args, struct sample *smp, const char
        smp->flags = SMP_F_VOL_TEST;
 
        if (!finished && (check || (chn && !channel_full(chn, global.tune.maxrewrite) &&
-                                   !(chn_prod(chn)->flags & SC_FL_EOI) && !(chn->flags & CF_SHUTR))))
+                                   !(chn_prod(chn)->flags & (SC_FL_EOI|SC_FL_SHUTR)))))
                smp->flags |= SMP_F_MAY_CHANGE;
 
        return 1;
index 971304157292a90f26fdd7cc88ca0cdf44183ba5..ff6bbf59ad80f774f0f3c4450e35d02359d9e0cd 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -348,7 +348,8 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
        struct stconn *sc = appctx_sc(appctx);
        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
                 * reference to the last ref_elt being dumped.
                 */
index d71bf615648d6c963106ccad9ba23a882e6b2b65..17609f6ce004180c48b1253187e837dd84f3de30 100644 (file)
@@ -567,7 +567,8 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
        char *uptime = 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;
 
        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))
                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;
 
-
        env = getenv("HAPROXY_LOAD_SUCCESS");
        if (!env)
                return 1;
index f08ec93d83c04f83709e8d6a0d9640d8bbcacf37..276228c345b1a691f50ecfec94f3ebb4bb587af8 100644 (file)
@@ -3208,7 +3208,8 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
        struct stconn *sc = appctx_sc(appctx);
        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;
 
        chunk_reset(&trash);
index 42abe0712bcaf41b432bd43d3d1ca71873affbe5..a09216e4636057e62891662d4913521f528e67df 100644 (file)
@@ -8261,7 +8261,8 @@ static int cli_io_handler_dump_quic(struct appctx *appctx)
        if (ctx->thr >= global.nbthread)
                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
                 * reference to the last stream being dumped.
                 */
index c3baf88af8899a2d520c884597828edce3708758..6d75f0510d98271d0af473efb3892a2abf2fb6df 100644 (file)
@@ -349,7 +349,8 @@ int cli_io_handler_show_ring(struct appctx *appctx)
        size_t len, cnt;
        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;
 
        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
                 * 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 */
                        HA_RWLOCK_WRLOCK(LOGSRV_LOCK, &ring->lock);
                        LIST_APPEND(&ring->waiters, &appctx->wait_entry);
index 6342787a95973dd1c78155cf66575afd573d1907..bfb4235e4ed8f02cab18df3cac9209b05a8ebe51 100644 (file)
@@ -2148,7 +2148,8 @@ static int cli_io_handler_commit_cert(struct appctx *appctx)
        struct ckch_store *old_ckchs, *new_ckchs = NULL;
        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;
 
        while (1) {
@@ -2824,7 +2825,8 @@ static int cli_io_handler_commit_cafile_crlfile(struct appctx *appctx)
        struct ckch_inst_link *ckchi_link;
        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;
 
        /* The ctx was already validated by the ca-file/crl-file parsing
index c31714d4e22ed9d368d6ad4f0122c79f5079d82b..7b410e9ce2b380e327b73dfa53a2d0e937779365 100644 (file)
@@ -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
         * 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;
 
        switch (ctx->state) {
index 5ce61ee664e6e984e8ae4f29af8d914212c45136..1f805098788943de3b1ea2e37c383ce9fe346228 100644 (file)
@@ -4473,7 +4473,7 @@ static void http_stats_io_handler(struct appctx *appctx)
        if (appctx->st0 == STAT_HTTP_POST) {
                if (stats_process_http_post(sc))
                        appctx->st0 = STAT_HTTP_LAST;
-               else if (req->flags & CF_SHUTR)
+               else if (chn_prod(req)->flags & SC_FL_SHUTR)
                        appctx->st0 = STAT_HTTP_DONE;
        }
 
index d1aa1b5c62363591fca33613b35a1e8de1942428..5d94646584ed0c8b3a95e7a838d4aec4bf53670f 100644 (file)
@@ -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
  * 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
- * the channel if we are only waiting for the outgoing data to be flushed.
+ * side. Otherwise, 0 is returned. In this case, SC_FL_SHUTW_NOW flag may be set on
+ * 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)
 {
        /* 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;
 
        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);
 
-       if (ic->flags & CF_SHUTR)
+       if (chn_prod(ic)->flags & SC_FL_SHUTR)
                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);
 
        if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
                return;
 
-       if (sc_oc(sc)->flags & CF_SHUTW) {
+       if (chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW) {
                sc->state = SC_ST_DIS;
                if (sc->flags & SC_FL_ISBACK)
                        __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 *oc = sc_oc(sc);
 
-       oc->flags &= ~CF_SHUTW_NOW;
-       if (oc->flags & CF_SHUTW)
+       chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
+       if (chn_cons(oc)->flags & SC_FL_SHUTW)
                return;
-       oc->flags |= CF_SHUTW|CF_WRITE_EVENT;
+       chn_cons(oc)->flags |= SC_FL_SHUTW;
+       oc->flags |= CF_WRITE_EVENT;
        sc_set_hcto(sc);
 
        switch (sc->state) {
@@ -583,7 +586,7 @@ static void sc_app_shutw(struct stconn *sc)
                 * no risk so we close both sides immediately.
                 */
                if (!sc_ep_test(sc, SE_FL_ERROR) && !(sc->flags & SC_FL_NOLINGER) &&
-                   !(ic->flags & (CF_SHUTR|CF_DONT_READ)))
+                   !(chn_prod(ic)->flags & SC_FL_SHUTR) && !(ic->flags & CF_DONT_READ))
                        return;
 
                __fallthrough;
@@ -596,7 +599,7 @@ static void sc_app_shutw(struct stconn *sc)
                __fallthrough;
        default:
                sc->flags &= ~SC_FL_NOLINGER;
-               ic->flags |= CF_SHUTR;
+               chn_prod(ic)->flags |= SC_FL_SHUTR;
                if (sc->flags & SC_FL_ISBACK)
                        __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);
 
-       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;
 
        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));
 
-       if (ic->flags & CF_SHUTR)
+       if (chn_prod(ic)->flags & SC_FL_SHUTR)
                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))
                return;
 
-       if (sc_oc(sc)->flags & CF_SHUTW) {
+       if (chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW) {
                sc_conn_shut(sc);
                sc->state = SC_ST_DIS;
                if (sc->flags & SC_FL_ISBACK)
@@ -690,10 +694,11 @@ static void sc_app_shutw_conn(struct stconn *sc)
 
        BUG_ON(!sc_conn(sc));
 
-       oc->flags &= ~CF_SHUTW_NOW;
-       if (oc->flags & CF_SHUTW)
+       chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
+       if (chn_cons(oc)->flags & SC_FL_SHUTW)
                return;
-       oc->flags |= CF_SHUTW|CF_WRITE_EVENT;
+       chn_cons(oc)->flags |= SC_FL_SHUTW;
+       oc->flags |= CF_WRITE_EVENT;
        sc_set_hcto(sc);
 
        switch (sc->state) {
@@ -726,7 +731,7 @@ static void sc_app_shutw_conn(struct stconn *sc)
                         */
                        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;
                }
 
@@ -744,7 +749,7 @@ static void sc_app_shutw_conn(struct stconn *sc)
                __fallthrough;
        default:
                sc->flags &= ~SC_FL_NOLINGER;
-               ic->flags |= CF_SHUTR;
+               chn_prod(ic)->flags |= SC_FL_SHUTR;
                if (sc->flags & SC_FL_ISBACK)
                        __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));
 
        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;
 
        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
                 * chunk and need to close.
                 */
-               if (((oc->flags & (CF_SHUTW|CF_AUTO_CLOSE|CF_SHUTW_NOW)) ==
-                    (CF_AUTO_CLOSE|CF_SHUTW_NOW)) &&
+               if ((oc->flags & CF_AUTO_CLOSE) &&
+                   ((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_shutw(sc);
                        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);
        }
        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
         * 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_WAKE_WRITE) &&
                    ((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));
 
-       if (ic->flags & CF_SHUTR)
+       if (chn_prod(ic)->flags & SC_FL_SHUTR)
                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 */
 
        if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
                return;
 
-       if (sc_oc(sc)->flags & CF_SHUTW) {
+       if (chn_cons(sc_oc(sc))->flags & SC_FL_SHUTW) {
                appctx_shut(__sc_appctx(sc));
                sc->state = SC_ST_DIS;
                if (sc->flags & SC_FL_ISBACK)
@@ -885,10 +891,11 @@ static void sc_app_shutw_applet(struct stconn *sc)
 
        BUG_ON(!sc_appctx(sc));
 
-       oc->flags &= ~CF_SHUTW_NOW;
-       if (oc->flags & CF_SHUTW)
+       chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
+       if (chn_cons(oc)->flags & SC_FL_SHUTW)
                return;
-       oc->flags |= CF_SHUTW|CF_WRITE_EVENT;
+       chn_cons(oc)->flags |= SC_FL_SHUTW;
+       oc->flags |= CF_WRITE_EVENT;
        sc_set_hcto(sc);
 
        /* 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.
                 */
                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;
 
                __fallthrough;
@@ -918,7 +926,7 @@ static void sc_app_shutw_applet(struct stconn *sc)
                __fallthrough;
        default:
                sc->flags &= ~SC_FL_NOLINGER;
-               ic->flags |= CF_SHUTR;
+               chn_prod(ic)->flags |= SC_FL_SHUTR;
                if (sc->flags & SC_FL_ISBACK)
                        __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));
 
-       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;
 
        /* 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);
 
-       if (ic->flags & CF_SHUTR)
+       if (chn_prod(ic)->flags & SC_FL_SHUTR)
                return;
 
        /* 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);
 
-       if (oc->flags & CF_SHUTW)
+       if (chn_cons(oc)->flags & SC_FL_SHUTW)
                return;
 
        /* Write not closed, update FD status and timeout for writes */
        if (channel_is_empty(oc)) {
                /* stop writing */
                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);
                }
                return;
@@ -1034,17 +1042,17 @@ static void sc_notify(struct stconn *sc)
        if (channel_is_empty(oc)) {
                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_shutw(sc);
        }
 
        /* 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);
-       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);
 
        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)
             *                  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) ||
 
            /* changes on the consumption side */
            sc_ep_test(sc, SE_FL_ERR_PENDING) ||
            ((oc->flags & CF_WRITE_EVENT) &&
             ((sc->state < SC_ST_EST) ||
-             (oc->flags & CF_SHUTW) ||
+             (chn_cons(oc)->flags & SC_FL_SHUTW) ||
              (((oc->flags & CF_WAKE_WRITE) ||
-              !(oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW|CF_SHUTW))) &&
-             (sco->state != SC_ST_EST ||
-              (channel_is_empty(oc) && !oc->to_forward)))))) {
+               (!(oc->flags & CF_AUTO_CLOSE) &&
+                !(chn_cons(oc)->flags & (SC_FL_SHUTW_NOW|SC_FL_SHUTW)))) &&
+              (sco->state != SC_ST_EST ||
+               (channel_is_empty(oc) && !oc->to_forward)))))) {
                task_wakeup(task, TASK_WOKEN_IO);
        }
 
@@ -1131,15 +1140,16 @@ static void sc_conn_read0(struct stconn *sc)
 
        BUG_ON(!sc_conn(sc));
 
-       if (ic->flags & CF_SHUTR)
+       if (chn_prod(ic)->flags & SC_FL_SHUTR)
                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);
 
        if (!sc_state_in(sc->state, SC_SB_CON|SC_SB_RDY|SC_SB_EST))
                return;
 
-       if (oc->flags & CF_SHUTW)
+       if (chn_cons(oc)->flags & SC_FL_SHUTW)
                goto do_close;
 
        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]() */
        sc_conn_shut(sc);
 
-       oc->flags &= ~CF_SHUTW_NOW;
-       oc->flags |= CF_SHUTW;
+       chn_cons(oc)->flags &= ~SC_FL_SHUTW_NOW;
+       chn_cons(oc)->flags |= SC_FL_SHUTW;
 
        sc->state = SC_ST_DIS;
        if (sc->flags & SC_FL_ISBACK)
@@ -1189,7 +1199,7 @@ static int sc_conn_recv(struct stconn *sc)
                return 0;
 
        /* maybe we were called immediately after an asynchronous shutr */
-       if (ic->flags & CF_SHUTR)
+       if (chn_prod(ic)->flags & SC_FL_SHUTR)
                return 1;
 
        /* 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) ||
               (!(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;
 
                /* Compute transient CO_RFL_* flags */
@@ -1361,7 +1371,7 @@ static int sc_conn_recv(struct stconn *sc)
                cur_read += ret;
 
                /* 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;
                        if (ic->to_forward != CHN_INFINITE_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))
                ret = 1;
        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 */
                conn->mux->subscribe(sc, SUB_RETRY_RECV, &sc->wait_event);
                se_have_no_more_data(sc->sedesc);
@@ -1554,7 +1564,7 @@ static int sc_conn_send(struct stconn *sc)
                return 0;
 
        /* 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;
 
        /* 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) ||
                      (sc->flags & SC_FL_SND_EXP_MORE) ||
                      (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_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;
 
                if (oc->flags & CF_STREAMER)
@@ -1685,7 +1696,7 @@ void sc_conn_sync_send(struct stconn *sc)
 
        oc->flags &= ~CF_WRITE_EVENT;
 
-       if (oc->flags & CF_SHUTW)
+       if (chn_cons(oc)->flags & SC_FL_SHUTW)
                return;
 
        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
         *       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 */
                if (ic->flags & CF_AUTO_CLOSE)
                        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
         * 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);
 
        /* automatically mark the applet having data available if it reported
index d7487050231a50be4eb1e94a779df64a03dfd8f3..bb4dd5abc029d6480743d9e3fbae36e72c0ecfc1 100644 (file)
@@ -5043,8 +5043,8 @@ static int cli_io_handler_table(struct appctx *appctx)
         *   - STATE_DONE : nothing left to dump, the buffer may contain some
         *     data though.
         */
-
-       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)) {
                /* in case of abort, remove any refcount we might have set on an entry */
                if (ctx->state == STATE_DUMP) {
                        stksess_kill_if_expired(ctx->t, ctx->entry, 1);
index 5794fd913f2b9604f9c577550b33fbffa5458a0e..b53a6033907c8ae3120da5c6bf92304fdcfe5662 100644 (file)
@@ -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_INI or SC_ST_RDY) to SC_ST_EST, but only when a ->proto is defined.
  * Note that it will switch the interface to SC_ST_DIS if we already have
- * the 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
  * 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.
@@ -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
         * 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;
                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);
        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;
                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)
                        s->scf->flags |= SC_FL_NOLINGER;
                sc_shutr(s->scf);
@@ -1591,16 +1591,16 @@ static void stream_handle_timeouts(struct stream *s)
 
        sc_check_timeouts(s->scb);
        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;
                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)
                        s->scb->flags |= SC_FL_NOLINGER;
                sc_shutr(s->scb);
-               }
+       }
 
        if (HAS_FILTERS(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 stream *s = context;
        struct session *sess = s->sess;
+       unsigned int scf_flags, scb_flags;
        unsigned int rqf_last, rpf_last;
        unsigned int rq_prod_last, rq_cons_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;
        scb->flags |= SC_FL_DONT_WAKE;
 
+       /* Keep a copy of SC flags */
+       scf_flags = scf->flags;
+       scb_flags = scb->flags;
+
        /* update pending events */
        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
                 * timeout needs to be refreshed.
                 */
-               if (!((req->flags | res->flags) &
-                     (CF_SHUTR|CF_READ_EVENT|CF_READ_TIMEOUT|CF_SHUTW|
-                      CF_WRITE_EVENT|CF_WRITE_TIMEOUT)) &&
+               if (!((scf->flags | scb->flags) & (SC_FL_SHUTR|SC_FL_SHUTW)) &&
+                   !((req->flags | res->flags) & (CF_READ_EVENT|CF_READ_TIMEOUT|CF_WRITE_EVENT|CF_WRITE_TIMEOUT)) &&
                    !(s->flags & SF_CONN_EXP) &&
                    !((sc_ep_get(scf) | scb->flags) & SE_FL_ERROR) &&
                    ((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:
        /* Analyse request */
        if (((req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
-           ((req->flags ^ rqf_last) & CF_MASK_STATIC) ||
-           (req->analysers && (req->flags & CF_SHUTW)) ||
+           ((scf->flags ^ scf_flags) & (SC_FL_SHUTR|SC_FL_SHUTR_NOW)) ||
+           ((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 ||
            scb->state != rq_cons_last ||
            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)) {
                        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;
                req->flags &= ~CF_WAKE_ONCE;
                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;
        }
 
@@ -2047,12 +2055,14 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
        /* Analyse response */
 
        if (((res->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
-                (res->flags ^ rpf_last) & CF_MASK_STATIC ||
-                (res->analysers && (res->flags & CF_SHUTW)) ||
-                scf->state != rp_cons_last ||
-                scb->state != rp_prod_last ||
-                s->pending_events & TASK_WOKEN_MSG) {
-               unsigned int flags = res->flags;
+           ((scb->flags ^ scb_flags) & (SC_FL_SHUTR|SC_FL_SHUTR_NOW)) ||
+           ((scf->flags ^ scf_flags) & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) ||
+           (res->analysers && (chn_cons(res)->flags & SC_FL_SHUTW)) ||
+           scf->state != rp_cons_last ||
+           scb->state != rp_prod_last ||
+           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)) {
                        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;
                res->flags &= ~CF_WAKE_ONCE;
                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;
        }
 
@@ -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
         * 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().
         */
        if (unlikely((!req->analysers || (req->analysers == AN_REQ_FLT_END && !(req->flags & CF_FLT_ANALYZE))) &&
-           !(req->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
-           (sc_state_in(scf->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO)) &&
-           (req->to_forward != CHN_INFINITE_FORWARD))) {
+                    !(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)) &&
+                    (req->to_forward != CHN_INFINITE_FORWARD))) {
                /* This buffer is freewheeling, there's no analyser
                 * attached to it. If any data are left in, we'll permit them to
                 * move.
@@ -2234,7 +2246,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                         * to the consumer.
                         */
                        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);
                }
                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).
                         */
                        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);
                }
        }
 
        /* 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 &&
            (global.tune.options & GTUNE_USE_SPLICE) &&
            (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 */
        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.
         * 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)
         */
        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 we have an appctx, there is no connect method, so 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
         * connection setup unless the backend has abortonclose set.
         */
-       if (unlikely((req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
-                    (CF_AUTO_CLOSE|CF_SHUTR) &&
+       if (unlikely((req->flags & CF_AUTO_CLOSE) && (scf->flags & SC_FL_SHUTR) &&
+                    !(scb->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)) &&
                     (scb->state != SC_ST_CON || (s->be->options & PR_O_ABRT_CLOSE)))) {
                channel_shutw_now(req);
        }
 
        /* 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))) {
                if (sc_ep_test(s->scf, SE_FL_ERROR))
                        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 */
-       if (unlikely((req->flags & (CF_SHUTW|CF_SHUTR|CF_SHUTR_NOW)) == CF_SHUTW &&
-                    !req->analysers))
+       if (unlikely((scb->flags & SC_FL_SHUTW) && !(scf->flags & (SC_FL_SHUTR|SC_FL_SHUTR_NOW))) &&
+           !req->analysers)
                channel_shutr_now(req);
 
        /* 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)
                        scf->flags |= SC_FL_NOLINGER;
                sc_shutr(scf);
@@ -2377,20 +2394,20 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                goto resync_stconns;
 
        /* otherwise we want to check if we need to resync the req buffer or not */
-       if ((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;
 
        /* perform output updates to the response buffer */
 
        /* If no one is interested in analysing data, it's time to forward
         * 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().
         */
        if (unlikely((!res->analysers || (res->analysers == AN_RES_FLT_END && !(res->flags & CF_FLT_ANALYZE))) &&
-           !(res->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
-           sc_state_in(scb->state, SC_SB_EST|SC_SB_DIS|SC_SB_CLO) &&
-           (res->to_forward != CHN_INFINITE_FORWARD))) {
+                    !(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) &&
+                    (res->to_forward != CHN_INFINITE_FORWARD))) {
                /* This buffer is freewheeling, there's no analyser
                 * attached to it. If any data are left in, we'll permit them to
                 * move.
@@ -2405,7 +2422,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                         * to the consumer.
                         */
                        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);
                }
                else {
@@ -2413,7 +2431,8 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                         * to the consumer.
                         */
                        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);
                }
 
@@ -2424,15 +2443,16 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                if (!req->analysers && s->tunnel_timeout) {
                        scf->ioto = scb->ioto = s->tunnel_timeout;
 
-                       if (((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;
-                       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;
                }
        }
 
        /* 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 &&
            (global.tune.options & GTUNE_USE_SPLICE) &&
            (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 */
        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 */
        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) */
-       if (unlikely((res->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CLOSE|CF_SHUTR)) ==
-                    (CF_AUTO_CLOSE|CF_SHUTR))) {
+       if (unlikely((res->flags & CF_AUTO_CLOSE) && (scb->flags & SC_FL_SHUTR) &&
+                    !(scf->flags & (SC_FL_SHUTW|SC_FL_SHUTW_NOW)))) {
                channel_shutw_now(res);
        }
 
        /* 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))) {
                sc_shutw(scf);
        }
 
        /* 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)
                channel_shutr_now(res);
 
        /* 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)
                        scb->flags |= SC_FL_NOLINGER;
                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)
                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;
 
        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_*) */
 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;
 
        channel_shutw_now(&stream->req);
@@ -3576,7 +3599,7 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
                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
                 * reference to the last stream being dumped.
                 */
index bb4e51f3da023f4e17ade8e00b65968972b18e2f..10a45ddf9f9ccde44b3dddfecb39e41da475ceb5 100644 (file)
@@ -116,7 +116,7 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit)
         * - if one rule returns KO, then return KO
         */
 
-       if ((s->scf->flags & SC_FL_EOI) || (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)) ||
            !s->be->tcp_req.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
                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 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)) ||
            !s->be->tcp_rep.inspect_delay || tick_is_expired(s->rules_exp, now_ms)) {
                partial = SMP_OPT_FINAL;