MEDIUM: stream-int/conn-stream: Move stream-interface state in the conn-stream

The stream-interface state (SI_ST_*) is now in the conn-stream. It is a
mechanical replacement for now. Nothing special. SI_ST_* and SI_SB_* were
renamed accordingly. Utils functions to manipulate these infos were moved
under the conn-stream scope.

But it could be good to keep in mind that this part should be
reworked. Indeed, at the CS level, we only need to know if it is ready to
receive or to send. The state of conn-stream from INI to EST is only used on
the server side. The client CS is immediately set to EST. Thus current
SI_ST_* states should probably be moved to the stream to reflect the server
connection state during the establishment stage.
diff --git a/addons/promex/service-prometheus.c b/addons/promex/service-prometheus.c
index b241922..514d16d 100644
--- a/addons/promex/service-prometheus.c
+++ b/addons/promex/service-prometheus.c
@@ -1473,7 +1473,7 @@
 	int ret;
 
 	res_htx = htx_from_buf(&res->buf);
-	if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+	if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
 		goto out;
 
 	/* Check if the input buffer is available. */
diff --git a/include/haproxy/channel.h b/include/haproxy/channel.h
index fd78002..76323cf 100644
--- a/include/haproxy/channel.h
+++ b/include/haproxy/channel.h
@@ -433,7 +433,7 @@
  */
 static inline int channel_may_send(const struct channel *chn)
 {
-	return chn_cons(chn)->si->state == SI_ST_EST;
+	return chn_cons(chn)->state == CS_ST_EST;
 }
 
 /* HTX version of channel_may_recv(). Returns non-zero if the channel can still
diff --git a/include/haproxy/conn_stream-t.h b/include/haproxy/conn_stream-t.h
index b8f72b8..fb0aa50 100644
--- a/include/haproxy/conn_stream-t.h
+++ b/include/haproxy/conn_stream-t.h
@@ -101,6 +101,42 @@
 	CS_SHW_SILENT       = 1,           /* imminent close, don't notify peer */
 };
 
+/* A conn stream must have its own errors independently of the buffer's, so that
+ * applications can rely on what the buffer reports while the conn stream is
+ * performing some retries (eg: connection error). Some states are transient and
+ * do not last beyond process_session().
+ */
+enum cs_state {
+	CS_ST_INI = 0,           /* CS not sollicitated yet */
+	CS_ST_REQ,               /* [transient] connection initiation desired and not started yet */
+	CS_ST_QUE,               /* CS waiting in queue */
+	CS_ST_TAR,               /* CS in turn-around state after failed connect attempt */
+	CS_ST_ASS,               /* server just assigned to this CS */
+	CS_ST_CON,               /* initiated connection request (resource exists) */
+	CS_ST_CER,               /* [transient] previous connection attempt failed (resource released) */
+	CS_ST_RDY,               /* [transient] ready proven after I/O success during CS_ST_CON */
+	CS_ST_EST,               /* connection established (resource exists) */
+	CS_ST_DIS,               /* [transient] disconnected from other side, but cleanup not done yet */
+	CS_ST_CLO,               /* CS closed, might not existing anymore. Buffers shut. */
+} __attribute__((packed));
+
+/* state bits for use with lists of states */
+enum cs_state_bit {
+	CS_SB_NONE = 0,
+	CS_SB_INI = 1U << CS_ST_INI,
+	CS_SB_REQ = 1U << CS_ST_REQ,
+	CS_SB_QUE = 1U << CS_ST_QUE,
+	CS_SB_TAR = 1U << CS_ST_TAR,
+	CS_SB_ASS = 1U << CS_ST_ASS,
+	CS_SB_CON = 1U << CS_ST_CON,
+	CS_SB_CER = 1U << CS_ST_CER,
+	CS_SB_RDY = 1U << CS_ST_RDY,
+	CS_SB_EST = 1U << CS_ST_EST,
+	CS_SB_DIS = 1U << CS_ST_DIS,
+	CS_SB_CLO = 1U << CS_ST_CLO,
+	CS_SB_ALL = CS_SB_INI|CS_SB_REQ|CS_SB_QUE|CS_SB_TAR|CS_SB_ASS|CS_SB_CON|CS_SB_CER|CS_SB_RDY|CS_SB_EST|CS_SB_DIS|CS_SB_CLO,
+};
+
 struct conn_stream;
 
 /* data_cb describes the data layer's recv and send callbacks which are called
@@ -127,7 +163,9 @@
  */
 struct conn_stream {
 	enum obj_type obj_type;              /* differentiates connection from applet context */
-	/* 3 bytes hole here */
+	enum cs_state state;                 /* CS_ST* */
+	/* 2 bytes hole here */
+
 	unsigned int flags;                  /* CS_FL_* */
 	unsigned int hcto;                   /* half-closed timeout (0 = unset) */
 	struct cs_endpoint *endp;            /* points to the end point (MUX stream or appctx) */
diff --git a/include/haproxy/cs_utils.h b/include/haproxy/cs_utils.h
index ae2480b..bfee8fd 100644
--- a/include/haproxy/cs_utils.h
+++ b/include/haproxy/cs_utils.h
@@ -76,7 +76,7 @@
 }
 
 
-/* to be called only when in SI_ST_DIS with SI_FL_ERR */
+/* to be called only when in CS_ST_DIS with CS_FL_ERR */
 static inline void cs_report_error(struct conn_stream *cs)
 {
 	if (!__cs_strm(cs)->conn_err_type)
@@ -86,6 +86,28 @@
 	cs_ic(cs)->flags |= CF_READ_ERROR;
 }
 
+/* sets the current and previous state of a conn-stream to <state>. This is
+ * mainly used to create one in the established state on incoming conncetions.
+ */
+static inline void cs_set_state(struct conn_stream *cs, int state)
+{
+	cs->state = __cs_strm(cs)->prev_conn_state = state;
+}
+
+/* returns a bit for a conn-stream state, to match against CS_SB_* */
+static inline enum cs_state_bit cs_state_bit(enum cs_state state)
+{
+	BUG_ON(state > CS_ST_CLO);
+	return 1U << state;
+}
+
+/* returns true if <state> matches one of the CS_SB_* bits in <mask> */
+static inline int cs_state_in(enum cs_state state, enum cs_state_bit mask)
+{
+	BUG_ON(mask & ~CS_SB_ALL);
+	return !!(cs_state_bit(state) & mask);
+}
+
 /* Returns the source address of the conn-stream and, if not set, fallbacks on
  * the session for frontend CS and the server connection for the backend CS. It
  * returns a const address on success or NULL on failure.
@@ -194,4 +216,23 @@
 	cs->endp->flags |= CS_EP_KILL_CONN;
 }
 
+/* for debugging, reports the stream interface state name */
+static inline const char *cs_state_str(int state)
+{
+	switch (state) {
+	case CS_ST_INI: return "INI";
+	case CS_ST_REQ: return "REQ";
+	case CS_ST_QUE: return "QUE";
+	case CS_ST_TAR: return "TAR";
+	case CS_ST_ASS: return "ASS";
+	case CS_ST_CON: return "CON";
+	case CS_ST_CER: return "CER";
+	case CS_ST_RDY: return "RDY";
+	case CS_ST_EST: return "EST";
+	case CS_ST_DIS: return "DIS";
+	case CS_ST_CLO: return "CLO";
+	default:        return "???";
+	}
+}
+
 #endif /* _HAPROXY_CS_UTILS_H */
diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h
index 530a575..0dbafcf 100644
--- a/include/haproxy/stream-t.h
+++ b/include/haproxy/stream-t.h
@@ -161,7 +161,7 @@
 	int conn_retries;               /* number of connect retries performed */
 	unsigned int conn_exp;          /* wake up time for connect, queue, turn-around, ... */
 	unsigned int conn_err_type;     /* first error detected, one of STRM_ET_* */
-	enum si_state prev_conn_state;  /* SI_ST*, copy of previous state of the server conn-stream */
+	enum cs_state prev_conn_state;  /* CS_ST*, copy of previous state of the server conn-stream */
 
 	struct list list;               /* position in the thread's streams list */
 	struct mt_list by_srv;          /* position in server stream list */
diff --git a/include/haproxy/stream.h b/include/haproxy/stream.h
index 57b2aed..6cf8d14 100644
--- a/include/haproxy/stream.h
+++ b/include/haproxy/stream.h
@@ -44,7 +44,7 @@
 #define  STRM_EV_STRM_ERR     (1ULL <<  2)
 #define  STRM_EV_STRM_ANA     (1ULL <<  3)
 #define  STRM_EV_STRM_PROC    (1ULL <<  4)
-#define  STRM_EV_SI_ST        (1ULL <<  5)
+#define  STRM_EV_CS_ST        (1ULL <<  5)
 #define  STRM_EV_HTTP_ANA     (1ULL <<  6)
 #define  STRM_EV_HTTP_ERR     (1ULL <<  7)
 #define  STRM_EV_TCP_ANA      (1ULL <<  8)
@@ -313,8 +313,6 @@
 
 static inline void stream_choose_redispatch(struct stream *s)
 {
-	struct stream_interface *si = cs_si(s->csb);
-
 	/* If the "redispatch" option is set on the backend, we are allowed to
 	 * retry on another server. By default this redispatch occurs on the
 	 * last retry, but if configured we allow redispatches to occur on
@@ -342,12 +340,12 @@
 
 		sockaddr_free(&s->csb->dst);
 		s->flags &= ~(SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET);
-		si->state = SI_ST_REQ;
+		s->csb->state = CS_ST_REQ;
 	} else {
 		if (objt_server(s->target))
 			_HA_ATOMIC_INC(&__objt_server(s->target)->counters.retries);
 		_HA_ATOMIC_INC(&s->be->be_counters.retries);
-		si->state = SI_ST_ASS;
+		s->csb->state = CS_ST_ASS;
 	}
 
 }
diff --git a/include/haproxy/stream_interface-t.h b/include/haproxy/stream_interface-t.h
index 0f2f6ad..c435b31 100644
--- a/include/haproxy/stream_interface-t.h
+++ b/include/haproxy/stream_interface-t.h
@@ -28,42 +28,6 @@
 
 struct conn_stream;
 
-/* A stream interface must have its own errors independently of the buffer's,
- * so that applications can rely on what the buffer reports while the stream
- * interface is performing some retries (eg: connection error). Some states are
- * transient and do not last beyond process_session().
- */
-enum si_state {
-	SI_ST_INI = 0,           /* interface not sollicitated yet */
-	SI_ST_REQ,               /* [transient] connection initiation desired and not started yet */
-	SI_ST_QUE,               /* interface waiting in queue */
-	SI_ST_TAR,               /* interface in turn-around state after failed connect attempt */
-	SI_ST_ASS,               /* server just assigned to this interface */
-	SI_ST_CON,               /* initiated connection request (resource exists) */
-	SI_ST_CER,               /* [transient] previous connection attempt failed (resource released) */
-	SI_ST_RDY,               /* [transient] ready proven after I/O success during SI_ST_CON */
-	SI_ST_EST,               /* connection established (resource exists) */
-	SI_ST_DIS,               /* [transient] disconnected from other side, but cleanup not done yet */
-	SI_ST_CLO,               /* stream intf closed, might not existing anymore. Buffers shut. */
-} __attribute__((packed));
-
-/* state bits for use with lists of states */
-enum si_state_bit {
-	SI_SB_NONE = 0,
-	SI_SB_INI = 1U << SI_ST_INI,
-	SI_SB_REQ = 1U << SI_ST_REQ,
-	SI_SB_QUE = 1U << SI_ST_QUE,
-	SI_SB_TAR = 1U << SI_ST_TAR,
-	SI_SB_ASS = 1U << SI_ST_ASS,
-	SI_SB_CON = 1U << SI_ST_CON,
-	SI_SB_CER = 1U << SI_ST_CER,
-	SI_SB_RDY = 1U << SI_ST_RDY,
-	SI_SB_EST = 1U << SI_ST_EST,
-	SI_SB_DIS = 1U << SI_ST_DIS,
-	SI_SB_CLO = 1U << SI_ST_CLO,
-	SI_SB_ALL = SI_SB_INI|SI_SB_REQ|SI_SB_QUE|SI_SB_TAR|SI_SB_ASS|SI_SB_CON|SI_SB_CER|SI_SB_RDY|SI_SB_EST|SI_SB_DIS|SI_SB_CLO,
-};
-
 /* flags set after I/O (32 bit) */
 enum {
 	SI_FL_NONE       = 0x00000000,  /* nothing */
@@ -95,7 +59,6 @@
  */
 struct stream_interface {
 	/* struct members used by the "buffer" side */
-	enum si_state state;     /* SI_ST* */
 	/* 16-bit hole here */
 	unsigned int flags;     /* SI_FL_* */
 	struct conn_stream *cs; /* points to the conn-streams that owns the endpoint (connection or applet) */
diff --git a/include/haproxy/stream_interface.h b/include/haproxy/stream_interface.h
index 3576ac4..9747d2c 100644
--- a/include/haproxy/stream_interface.h
+++ b/include/haproxy/stream_interface.h
@@ -27,6 +27,7 @@
 #include <haproxy/channel.h>
 #include <haproxy/connection.h>
 #include <haproxy/conn_stream.h>
+#include <haproxy/cs_utils.h>
 #include <haproxy/obj_type.h>
 
 extern struct si_ops si_embedded_ops;
@@ -101,14 +102,13 @@
 	return ((si->flags & SI_FL_ISBACK) ? strm->csf->si : strm->csb->si);
 }
 
-/* initializes a stream interface in the SI_ST_INI state and create the event
+/* initializes a stream interface and create the event
  * tasklet.
  */
 static inline int si_init(struct stream_interface *si)
 {
 	si->flags         &= SI_FL_ISBACK;
 	si->cs             = NULL;
-	si->state          = SI_ST_INI;
 	si->ops            = &si_embedded_ops;
 	si->wait_event.tasklet = tasklet_new();
 	if (!si->wait_event.tasklet)
@@ -119,36 +119,13 @@
 	return 0;
 }
 
-/* sets the current and previous state of a stream interface to <state>. This
- * is mainly used to create one in the established state on incoming
- * conncetions.
- */
-static inline void si_set_state(struct stream_interface *si, int state)
-{
-	si->state = si_strm(si)->prev_conn_state = state;
-}
-
-/* returns a bit for a stream-int state, to match against SI_SB_* */
-static inline enum si_state_bit si_state_bit(enum si_state state)
-{
-	BUG_ON(state > SI_ST_CLO);
-	return 1U << state;
-}
-
-/* returns true if <state> matches one of the SI_SB_* bits in <mask> */
-static inline int si_state_in(enum si_state state, enum si_state_bit mask)
-{
-	BUG_ON(mask & ~SI_SB_ALL);
-	return !!(si_state_bit(state) & mask);
-}
-
 /* call the applet's release function if any. Needs to be called upon close() */
 static inline void si_applet_release(struct stream_interface *si)
 {
 	struct appctx *appctx;
 
 	appctx = __cs_appctx(si->cs);
-	if (appctx->applet->release && !si_state_in(si->state, SI_SB_DIS|SI_SB_CLO))
+	if (appctx->applet->release && !cs_state_in(si->cs->state, CS_SB_DIS|CS_SB_CLO))
 		appctx->applet->release(appctx);
 }
 
@@ -334,13 +311,13 @@
  */
 static inline void si_chk_rcv(struct stream_interface *si)
 {
-	if (si->flags & SI_FL_RXBLK_CONN && si_state_in(si_opposite(si)->state, SI_SB_RDY|SI_SB_EST|SI_SB_DIS|SI_SB_CLO))
+	if (si->flags & SI_FL_RXBLK_CONN && cs_state_in(si_opposite(si)->cs->state, CS_SB_RDY|CS_SB_EST|CS_SB_DIS|CS_SB_CLO))
 		si_rx_conn_rdy(si);
 
 	if (si_rx_blocked(si) || !si_rx_endp_ready(si))
 		return;
 
-	if (!si_state_in(si->state, SI_SB_RDY|SI_SB_EST))
+	if (!cs_state_in(si->cs->state, CS_SB_RDY|CS_SB_EST))
 		return;
 
 	si->flags |= SI_FL_RX_WAIT_EP;
@@ -372,7 +349,7 @@
 			return ret;
 
 		/* we're in the process of establishing a connection */
-		si->state = SI_ST_CON;
+		si->cs->state = CS_ST_CON;
 	}
 	else {
 		/* try to reuse the existing connection, it will be
@@ -380,9 +357,9 @@
 		 */
 		/* Is the connection really ready ? */
 		if (conn->mux->ctl(conn, MUX_STATUS, NULL) & MUX_STATUS_READY)
-			si->state = SI_ST_RDY;
+			si->cs->state = CS_ST_RDY;
 		else
-			si->state = SI_ST_CON;
+			si->cs->state = CS_ST_CON;
 	}
 
 	/* needs src ip/port for logging */
@@ -399,25 +376,6 @@
 	si_update_tx(si);
 }
 
-/* for debugging, reports the stream interface state name */
-static inline const char *si_state_str(int state)
-{
-	switch (state) {
-	case SI_ST_INI: return "INI";
-	case SI_ST_REQ: return "REQ";
-	case SI_ST_QUE: return "QUE";
-	case SI_ST_TAR: return "TAR";
-	case SI_ST_ASS: return "ASS";
-	case SI_ST_CON: return "CON";
-	case SI_ST_CER: return "CER";
-	case SI_ST_RDY: return "RDY";
-	case SI_ST_EST: return "EST";
-	case SI_ST_DIS: return "DIS";
-	case SI_ST_CLO: return "CLO";
-	default:        return "???";
-	}
-}
-
 #endif /* _HAPROXY_STREAM_INTERFACE_H */
 
 /*
diff --git a/src/backend.c b/src/backend.c
index 00e0bdb..928c213 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1292,7 +1292,7 @@
 
 	/* do not reuse if mode is not http */
 	if (!IS_HTX_STRM(s)) {
-		DBG_TRACE_STATE("skip idle connections reuse: no htx", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+		DBG_TRACE_STATE("skip idle connections reuse: no htx", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 		goto skip_reuse;
 	}
 
@@ -1301,7 +1301,7 @@
 	 */
 	if (unlikely(s->flags & SF_WEBSOCKET) && srv) {
 		if (!srv_check_reuse_ws(srv)) {
-			DBG_TRACE_STATE("skip idle connections reuse: websocket stream", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+			DBG_TRACE_STATE("skip idle connections reuse: websocket stream", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 			goto skip_reuse;
 		}
 	}
@@ -1345,7 +1345,7 @@
 	/* first, search for a matching connection in the session's idle conns */
 	srv_conn = session_get_conn(s->sess, s->target, hash);
 	if (srv_conn) {
-		DBG_TRACE_STATE("reuse connection from session", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+		DBG_TRACE_STATE("reuse connection from session", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 		reuse = 1;
 	}
 
@@ -1371,7 +1371,7 @@
 		if (!eb_is_empty(&srv->per_thr[tid].avail_conns)) {
 			srv_conn = srv_lookup_conn(&srv->per_thr[tid].avail_conns, hash);
 			if (srv_conn) {
-				DBG_TRACE_STATE("reuse connection from avail", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+				DBG_TRACE_STATE("reuse connection from avail", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 				reuse = 1;
 			}
 		}
@@ -1405,7 +1405,7 @@
 			}
 
 			if (srv_conn) {
-				DBG_TRACE_STATE("reuse connection from idle/safe", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+				DBG_TRACE_STATE("reuse connection from idle/safe", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 				reuse = 1;
 			}
 		}
@@ -1516,7 +1516,7 @@
 	if (!srv_conn) {
 		srv_conn = conn_new(s->target);
 		if (srv_conn) {
-			DBG_TRACE_STATE("alloc new be connection", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+			DBG_TRACE_STATE("alloc new be connection", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 			srv_conn->owner = s->sess;
 
 			/* connection will be attached to the session if
@@ -1619,7 +1619,7 @@
 			}
 
 			if (!conn_update_alpn(srv_conn, ist(alpn), force))
-				DBG_TRACE_STATE("update alpn for websocket", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+				DBG_TRACE_STATE("update alpn for websocket", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 		}
 #endif
 	}
@@ -1740,7 +1740,7 @@
 	}
 
 	/* Now handle synchronously connected sockets. We know the stream-int
-	 * is at least in state SI_ST_CON. These ones typically are UNIX
+	 * is at least in state CS_ST_CON. These ones typically are UNIX
 	 * sockets, socket pairs, andoccasionally TCP connections on the
 	 * loopback on a heavily loaded system.
 	 */
@@ -1755,12 +1755,12 @@
 	if (!(srv_conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS)))
 		s->csb->endp->flags &= ~CS_EP_WAIT_FOR_HS;
 
-	if (!si_state_in(cs_si(s->csb)->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) &&
+	if (!cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO) &&
 	    (srv_conn->flags & CO_FL_WAIT_XPRT) == 0) {
 		s->conn_exp = TICK_ETERNITY;
 		cs_oc(s->csb)->flags |= CF_WRITE_NULL;
-		if (cs_si(s->csb)->state == SI_ST_CON)
-			cs_si(s->csb)->state = SI_ST_RDY;
+		if (s->csb->state == CS_ST_CON)
+			s->csb->state = CS_ST_RDY;
 	}
 
 	/* Report EOI on the channel if it was reached from the mux point of
@@ -1843,7 +1843,7 @@
 
 	case SRV_STATUS_QUEUED:
 		s->conn_exp = tick_add_ifset(now_ms, s->be->timeout.queue);
-		cs_si(s->csb)->state = SI_ST_QUE;
+		s->csb->state = CS_ST_QUE;
 		/* do nothing else and do not wake any other stream up */
 		return 1;
 
@@ -1880,10 +1880,10 @@
 	         (channel_is_empty(req) || (s->be->options & PR_O_ABRT_CLOSE))));
 }
 
-/* Update back stream interface status for input states SI_ST_ASS, SI_ST_QUE,
- * SI_ST_TAR. Other input states are simply ignored.
- * Possible output states are SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ, SI_ST_CON
- * and SI_ST_EST. Flags must have previously been updated for timeouts and other
+/* Update back stream interface status for input states CS_ST_ASS, CS_ST_QUE,
+ * CS_ST_TAR. Other input states are simply ignored.
+ * Possible output states are CS_ST_CLO, CS_ST_TAR, CS_ST_ASS, CS_ST_REQ, CS_ST_CON
+ * and CS_ST_EST. Flags must have previously been updated for timeouts and other
  * conditions.
  */
 void back_try_conn_req(struct stream *s)
@@ -1892,9 +1892,9 @@
 	struct conn_stream *cs = s->csb;
 	struct channel *req = &s->req;
 
-	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 
-	if (cs->si->state == SI_ST_ASS) {
+	if (cs->state == CS_ST_ASS) {
 		/* Server assigned to connection request, we have to try to connect now */
 		int conn_err;
 
@@ -1903,7 +1903,7 @@
 		 */
 		if (back_may_abort_req(req, s)) {
 			s->conn_err_type |= STRM_ET_CONN_ABRT;
-			DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 			goto abort_connection;
 		}
 
@@ -1911,12 +1911,12 @@
 		srv = objt_server(s->target);
 
 		if (conn_err == SF_ERR_NONE) {
-			/* state = SI_ST_CON or SI_ST_EST now */
+			/* state = CS_ST_CON or CS_ST_EST now */
 			if (srv)
 				srv_inc_sess_ctr(srv);
 			if (srv)
 				srv_set_sess_last(srv);
-			DBG_TRACE_STATE("connection attempt", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+			DBG_TRACE_STATE("connection attempt", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 			goto end;
 		}
 
@@ -1952,10 +1952,10 @@
 			pendconn_cond_unlink(s->pend_pos);
 
 			/* no stream was ever accounted for this server */
-			cs->si->state = SI_ST_CLO;
+			cs->state = CS_ST_CLO;
 			if (s->srv_error)
 				s->srv_error(s, cs->si);
-			DBG_TRACE_STATE("internal error during connection", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			DBG_TRACE_STATE("internal error during connection", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 			goto end;
 		}
 
@@ -1963,14 +1963,14 @@
 		 * turn-around now, as the problem is likely a source port
 		 * allocation problem, so we want to retry now.
 		 */
-		cs->si->state = SI_ST_CER;
+		cs->state = CS_ST_CER;
 		cs->endp->flags &= ~CS_EP_ERROR;
 		back_handle_st_cer(s);
 
-		DBG_TRACE_STATE("connection error, retry", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
-		/* now si->state is one of SI_ST_CLO, SI_ST_TAR, SI_ST_ASS, SI_ST_REQ */
+		DBG_TRACE_STATE("connection error, retry", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
+		/* now cs->state is one of CS_ST_CLO, CS_ST_TAR, CS_ST_ASS, CS_ST_REQ */
 	}
-	else if (cs->si->state == SI_ST_QUE) {
+	else if (cs->state == CS_ST_QUE) {
 		/* connection request was queued, check for any update */
 		if (!pendconn_dequeue(s)) {
 			/* The connection is not in the queue anymore. Either
@@ -1980,12 +1980,12 @@
 			 */
 			s->conn_exp = TICK_ETERNITY;
 			if (unlikely(!(s->flags & SF_ASSIGNED)))
-				cs->si->state = SI_ST_REQ;
+				cs->state = CS_ST_REQ;
 			else {
 				s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
-				cs->si->state = SI_ST_ASS;
+				cs->state = CS_ST_ASS;
 			}
-			DBG_TRACE_STATE("dequeue connection request", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+			DBG_TRACE_STATE("dequeue connection request", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 			goto end;
 		}
 
@@ -2007,10 +2007,10 @@
 			req->flags |= CF_WRITE_TIMEOUT;
 			if (!s->conn_err_type)
 				s->conn_err_type = STRM_ET_QUEUE_TO;
-			cs->si->state = SI_ST_CLO;
+			cs->state = CS_ST_CLO;
 			if (s->srv_error)
 				s->srv_error(s, cs->si);
-			DBG_TRACE_STATE("connection request still queued", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+			DBG_TRACE_STATE("connection request still queued", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 			goto end;
 		}
 
@@ -2022,17 +2022,17 @@
 			pendconn_cond_unlink(s->pend_pos);
 
 			s->conn_err_type |= STRM_ET_QUEUE_ABRT;
-			DBG_TRACE_STATE("abort queued connection request", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			DBG_TRACE_STATE("abort queued connection request", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 			goto abort_connection;
 		}
 
 		/* Nothing changed */
 	}
-	else if (cs->si->state == SI_ST_TAR) {
+	else if (cs->state == CS_ST_TAR) {
 		/* Connection request might be aborted */
 		if (back_may_abort_req(req, s)) {
 			s->conn_err_type |= STRM_ET_CONN_ABRT;
-			DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			DBG_TRACE_STATE("connection aborted", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 			goto abort_connection;
 		}
 
@@ -2047,15 +2047,15 @@
 		 * FIXME: Should we force a redispatch attempt when the server is down ?
 		 */
 		if (s->flags & SF_ASSIGNED)
-			cs->si->state = SI_ST_ASS;
+			cs->state = CS_ST_ASS;
 		else
-			cs->si->state = SI_ST_REQ;
+			cs->state = CS_ST_REQ;
 
-		DBG_TRACE_STATE("retry connection now", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+		DBG_TRACE_STATE("retry connection now", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 	}
 
   end:
-	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 	return;
 
 abort_connection:
@@ -2064,27 +2064,27 @@
 	s->flags &= ~SF_CONN_EXP;
 	si_shutr(cs->si);
 	si_shutw(cs->si);
-	cs->si->state = SI_ST_CLO;
+	cs->state = CS_ST_CLO;
 	if (s->srv_error)
 		s->srv_error(s, cs->si);
-	DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+	DBG_TRACE_DEVEL("leaving on error", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 	return;
 }
 
 /* This function initiates a server connection request on a stream interface
- * already in SI_ST_REQ state. Upon success, the state goes to SI_ST_ASS for
+ * already in CS_ST_REQ state. Upon success, the state goes to CS_ST_ASS for
  * a real connection to a server, indicating that a server has been assigned,
- * or SI_ST_EST for a successful connection to an applet. It may also return
- * SI_ST_QUE, or SI_ST_CLO upon error.
+ * or CS_ST_EST for a successful connection to an applet. It may also return
+ * CS_ST_QUE, or CS_ST_CLO upon error.
  */
 void back_handle_st_req(struct stream *s)
 {
 	struct conn_stream *cs = s->csb;
 
-	if (cs->si->state != SI_ST_REQ)
+	if (cs->state != CS_ST_REQ)
 		return;
 
-	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 
 	if (unlikely(obj_type(s->target) == OBJ_TYPE_APPLET)) {
 		/* the applet directly goes to the EST state */
@@ -2104,21 +2104,21 @@
 			si_shutw(cs->si);
 			s->req.flags |= CF_WRITE_ERROR;
 			s->conn_err_type = STRM_ET_CONN_RES;
-			cs->si->state = SI_ST_CLO;
+			cs->state = CS_ST_CLO;
 			if (s->srv_error)
 				s->srv_error(s, cs->si);
-			DBG_TRACE_STATE("failed to register applet", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			DBG_TRACE_STATE("failed to register applet", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 			goto end;
 		}
 
 		if (tv_iszero(&s->logs.tv_request))
 			s->logs.tv_request = now;
 		s->logs.t_queue   = tv_ms_elapsed(&s->logs.tv_accept, &now);
-		cs->si->state     = SI_ST_EST;
+		cs->state     = CS_ST_EST;
 		s->conn_err_type  = STRM_ET_NONE;
 		be_set_sess_last(s->be);
 
-		DBG_TRACE_STATE("applet registered", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+		DBG_TRACE_STATE("applet registered", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 		/* let back_establish() finish the job */
 		goto end;
 	}
@@ -2128,8 +2128,8 @@
 		/* We did not get a server. Either we queued the
 		 * connection request, or we encountered an error.
 		 */
-		if (cs->si->state == SI_ST_QUE) {
-			DBG_TRACE_STATE("connection request queued", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+		if (cs->state == CS_ST_QUE) {
+			DBG_TRACE_STATE("connection request queued", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 			goto end;
 		}
 
@@ -2139,27 +2139,27 @@
 		s->req.flags |= CF_WRITE_ERROR;
 		if (!s->conn_err_type)
 			s->conn_err_type = STRM_ET_CONN_OTHER;
-		cs->si->state = SI_ST_CLO;
+		cs->state = CS_ST_CLO;
 		if (s->srv_error)
 			s->srv_error(s, cs->si);
-		DBG_TRACE_STATE("connection request failed", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+		DBG_TRACE_STATE("connection request failed", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 		goto end;
 	}
 
 	/* The server is assigned */
 	s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);
-	cs->si->state = SI_ST_ASS;
+	cs->state = CS_ST_ASS;
 	be_set_sess_last(s->be);
-	DBG_TRACE_STATE("connection request assigned to a server", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_STATE("connection request assigned to a server", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 
   end:
-	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 }
 
-/* This function is called with (si->state == SI_ST_CON) meaning that a
+/* This function is called with (cs->state == CS_ST_CON) meaning that a
  * connection was attempted and that the file descriptor is already allocated.
  * We must check for timeout, error and abort. Possible output states are
- * SI_ST_CER (error), SI_ST_DIS (abort), and SI_ST_CON (no change). This only
+ * CS_ST_CER (error), CS_ST_DIS (abort), and CS_ST_CON (no change). This only
  * works with connection-based streams. We know that there were no I/O event
  * when reaching this function. Timeouts and errors are *not* cleared.
  */
@@ -2169,7 +2169,7 @@
 	struct channel *req = &s->req;
 	struct channel *rep = &s->res;
 
-	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 
 	/* the client might want to abort */
 	if ((rep->flags & CF_SHUTW) ||
@@ -2180,8 +2180,8 @@
 		s->conn_err_type |= STRM_ET_CONN_ABRT;
 		if (s->srv_error)
 			s->srv_error(s, cs->si);
-		/* Note: state = SI_ST_DIS now */
-		DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+		/* Note: state = CS_ST_DIS now */
+		DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 		goto end;
 	}
 
@@ -2195,21 +2195,21 @@
 				s->conn_err_type = STRM_ET_CONN_TO;
 		}
 
-		cs->si->state  = SI_ST_CER;
-		DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+		cs->state  = CS_ST_CER;
+		DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 	}
 
  end:
-	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 }
 
-/* This function is called with (si->state == SI_ST_CER) meaning that a
+/* This function is called with (cs->state == CS_ST_CER) meaning that a
  * previous connection attempt has failed and that the file descriptor
  * has already been released. Possible causes include asynchronous error
- * notification and time out. Possible output states are SI_ST_CLO when
- * retries are exhausted, SI_ST_TAR when a delay is wanted before a new
- * connection attempt, SI_ST_ASS when it's wise to retry on the same server,
- * and SI_ST_REQ when an immediate redispatch is wanted. The buffers are
+ * notification and time out. Possible output states are CS_ST_CLO when
+ * retries are exhausted, CS_ST_TAR when a delay is wanted before a new
+ * connection attempt, CS_ST_ASS when it's wise to retry on the same server,
+ * and CS_ST_REQ when an immediate redispatch is wanted. The buffers are
  * marked as in error state. Timeouts and errors are cleared before retrying.
  */
 void back_handle_st_cer(struct stream *s)
@@ -2217,7 +2217,7 @@
 	struct conn_stream *cs = s->csb;
 	int must_tar = (cs->endp->flags & CS_EP_ERROR);
 
-	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 
 	s->conn_exp = TICK_ETERNITY;
 	s->flags &= ~SF_CONN_EXP;
@@ -2254,7 +2254,7 @@
 			 * client provoke retries.
 			 */
 			s->conn_retries = s->be->conn_retries;
-			DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 		}
 	}
 
@@ -2276,11 +2276,11 @@
 		s->req.flags |= CF_WRITE_ERROR;
 		s->res.flags |= CF_READ_ERROR;
 
-		cs->si->state = SI_ST_CLO;
+		cs->state = CS_ST_CLO;
 		if (s->srv_error)
 			s->srv_error(s, cs->si);
 
-		DBG_TRACE_STATE("connection failed", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+		DBG_TRACE_STATE("connection failed", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 		goto end;
 	}
 
@@ -2310,11 +2310,11 @@
 		s->req.flags |= CF_WRITE_ERROR;
 		s->res.flags |= CF_READ_ERROR;
 
-		cs->si->state = SI_ST_CLO;
+		cs->state = CS_ST_CLO;
 		if (s->srv_error)
 			s->srv_error(s, cs->si);
 
-		DBG_TRACE_STATE("error resetting endpoint", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+		DBG_TRACE_STATE("error resetting endpoint", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 		goto end;
 	}
 
@@ -2340,24 +2340,24 @@
 			s->conn_err_type = STRM_ET_CONN_ERR;
 
 		/* only wait when we're retrying on the same server */
-		if ((cs->si->state == SI_ST_ASS ||
+		if ((cs->state == CS_ST_ASS ||
 		     (s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_RR ||
 		     (s->be->srv_act <= 1)) && !reused) {
-			cs->si->state = SI_ST_TAR;
+			cs->state = CS_ST_TAR;
 			s->conn_exp = tick_add(now_ms, MS_TO_TICKS(delay));
 		}
-		DBG_TRACE_STATE("retry a new connection", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+		DBG_TRACE_STATE("retry a new connection", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 	}
 
   end:
-	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 }
 
-/* This function is called with (si->state == SI_ST_RDY) meaning that a
+/* This function is called with (cs->state == CS_ST_RDY) meaning that a
  * connection was attempted, that the file descriptor is already allocated,
  * and that it has succeeded. We must still check for errors and aborts.
- * Possible output states are SI_ST_EST (established), SI_ST_CER (error),
- * and SI_ST_DIS (abort). This only works with connection-based streams.
+ * Possible output states are CS_ST_EST (established), CS_ST_CER (error),
+ * and CS_ST_DIS (abort). This only works with connection-based streams.
  * Timeouts and errors are *not* cleared.
  */
 void back_handle_st_rdy(struct stream *s)
@@ -2366,7 +2366,7 @@
 	struct channel *req = &s->req;
 	struct channel *rep = &s->res;
 
-	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 	/* We know the connection at least succeeded, though it could have
 	 * since met an error for any other reason. At least it didn't time out
 	 * even though the timeout might have been reported right after success.
@@ -2375,7 +2375,7 @@
 	 *   - an I/O error might have been reported after a successful transfer,
 	 *     which is not retryable and needs to be logged correctly, and needs
 	 *     established as well
-	 *   - SI_ST_CON implies !CF_WROTE_DATA but not conversely as we could
+	 *   - CS_ST_CON implies !CF_WROTE_DATA but not conversely as we could
 	 *     have validated a connection with incoming data (e.g. TCP with a
 	 *     banner protocol), or just a successful connect() probe.
 	 *   - the client might have requested a connection abort, this needs to
@@ -2396,7 +2396,7 @@
 			s->conn_err_type |= STRM_ET_CONN_ABRT;
 			if (s->srv_error)
 				s->srv_error(s, cs->si);
-			DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			DBG_TRACE_STATE("client abort during connection attempt", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 			goto end;
 		}
 
@@ -2404,8 +2404,8 @@
 		if (cs->endp->flags & CS_EP_ERROR) {
 			if (!s->conn_err_type)
 				s->conn_err_type = STRM_ET_CONN_ERR;
-			cs->si->state = SI_ST_CER;
-			DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+			cs->state = CS_ST_CER;
+			DBG_TRACE_STATE("connection failed, retry", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 			goto end;
 		}
 	}
@@ -2413,12 +2413,12 @@
 	/* data were sent and/or we had no error, back_establish() will
 	 * now take over.
 	 */
-	DBG_TRACE_STATE("connection established", STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_STATE("connection established", STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 	s->conn_err_type = STRM_ET_NONE;
-	cs->si->state = SI_ST_EST;
+	cs->state = CS_ST_EST;
 
   end:
-	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 }
 
 /* sends a log message when a backend goes down, and also sets last
diff --git a/src/cache.c b/src/cache.c
index 5358b8b..8157631 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -1442,7 +1442,7 @@
 	res_htx = htx_from_buf(&res->buf);
 	total = res_htx->data;
 
-	if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+	if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
 		goto out;
 
 	/* Check if the input buffer is available. */
diff --git a/src/cli.c b/src/cli.c
index 38a7f35..5ed96f5 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -883,7 +883,7 @@
 	int reql;
 	int len;
 
-	if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+	if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
 		goto out;
 
 	/* Check if the input buffer is available. */
@@ -1146,9 +1146,9 @@
 		}
 	}
 
-	if ((res->flags & CF_SHUTR) && (cs->si->state == SI_ST_EST)) {
+	if ((res->flags & CF_SHUTR) && (cs->state == CS_ST_EST)) {
 		DPRINTF(stderr, "%s@%d: si to buf closed. req=%08x, res=%08x, st=%d\n",
-			__FUNCTION__, __LINE__, req->flags, res->flags, cs->si->state);
+			__FUNCTION__, __LINE__, req->flags, res->flags, cs->state);
 		/* Other side has closed, let's abort if we have no more processing to do
 		 * and nothing more to consume. This is comparable to a broken pipe, so
 		 * we forward the close to the request side so that it flows upstream to
@@ -1157,9 +1157,9 @@
 		si_shutw(cs->si);
 	}
 
-	if ((req->flags & CF_SHUTW) && (cs->si->state == SI_ST_EST) && (appctx->st0 < CLI_ST_OUTPUT)) {
+	if ((req->flags & CF_SHUTW) && (cs->state == CS_ST_EST) && (appctx->st0 < CLI_ST_OUTPUT)) {
 		DPRINTF(stderr, "%s@%d: buf to si closed. req=%08x, res=%08x, st=%d\n",
-			__FUNCTION__, __LINE__, req->flags, res->flags, cs->si->state);
+			__FUNCTION__, __LINE__, req->flags, res->flags, cs->state);
 		/* We have no more processing to do, and nothing more to send, and
 		 * the client side has closed. So we'll forward this state downstream
 		 * on the response buffer.
@@ -1171,7 +1171,7 @@
  out:
 	DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%lu, rqs=%lu, rh=%lu, rs=%lu\n",
 		__FUNCTION__, __LINE__,
-		cs->si->state, req->flags, res->flags, ci_data(req), co_data(req), ci_data(res), co_data(res));
+		cs->state, req->flags, res->flags, ci_data(req), co_data(req), ci_data(res), co_data(res));
 }
 
 /* This is called when the stream interface is closed. For instance, upon an
@@ -2766,7 +2766,7 @@
 
 		sockaddr_free(&s->csb->dst);
 
-		si_set_state(cs_si(s->csb), SI_ST_INI);
+		cs_set_state(s->csb, CS_ST_INI);
 		cs_si(s->csb)->flags &= SI_FL_ISBACK; /* we're in the context of process_stream */
 		s->csb->flags &= CS_FL_ISBACK | CS_FL_DONT_WAKE; /* we're in the context of process_stream */
 		s->req.flags &= ~(CF_SHUTW|CF_SHUTW_NOW|CF_AUTO_CONNECT|CF_WRITE_ERROR|CF_STREAMER|CF_STREAMER_FAST|CF_NEVER_WAIT|CF_WROTE_DATA);
diff --git a/src/conn_stream.c b/src/conn_stream.c
index e5a3ad7..31979d8 100644
--- a/src/conn_stream.c
+++ b/src/conn_stream.c
@@ -57,6 +57,7 @@
 
 	cs->obj_type = OBJ_TYPE_CS;
 	cs->flags = CS_FL_NONE;
+	cs->state = CS_ST_INI;
 	cs->hcto = TICK_ETERNITY;
 	cs->app = NULL;
 	cs->si = NULL;
diff --git a/src/debug.c b/src/debug.c
index 0861de1..6f482d2 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -694,7 +694,7 @@
 	if (!*args[3]) {
 		return cli_err(appctx,
 			       "Usage: debug dev stream { <obj> <op> <value> | wake }*\n"
-			       "     <obj>   = {strm | strm.f | strm.x | sif.f | sif.s | sib.f | sib.s |\n"
+			       "     <obj>   = {strm | strm.f | strm.x | sif.f | csf.s | sib.f | csb.s |\n"
 			       "                txn.f | req.f | req.r | req.w | res.f | res.r | res.w}\n"
 			       "     <op>    = {'' (show) | '=' (assign) | '^' (xor) | '+' (or) | '-' (andnot)}\n"
 			       "     <value> = 'now' | 64-bit dec/hex integer (0x prefix supported)\n"
@@ -733,10 +733,10 @@
 			ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csf)->flags; size = sizeof(cs_si(s->csf)->flags);
 		} else if (isteq(name, ist("sib.f"))) {
 			ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csb)->flags; size = sizeof(cs_si(s->csb)->flags);
-		} else if (isteq(name, ist("sif.s"))) {
-			ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csf)->state; size = sizeof(cs_si(s->csf)->state);
-		} else if (isteq(name, ist("sib.s"))) {
-			ptr = (!s || !may_access(s)) ? NULL : &cs_si(s->csf)->state; size = sizeof(cs_si(s->csb)->state);
+		} else if (isteq(name, ist("csf.s"))) {
+			ptr = (!s || !may_access(s)) ? NULL : &s->csf->state; size = sizeof(s->csf->state);
+		} else if (isteq(name, ist("csb.s"))) {
+			ptr = (!s || !may_access(s)) ? NULL : &s->csf->state; size = sizeof(s->csb->state);
 		} else if (isteq(name, ist("wake"))) {
 			if (s && may_access(s) && may_access((void *)s + sizeof(*s) - 1))
 				task_wakeup(s->task, TASK_WOKEN_TIMER|TASK_WOKEN_IO|TASK_WOKEN_MSG);
diff --git a/src/dns.c b/src/dns.c
index f60639a..a4adbf8 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -442,7 +442,7 @@
 	/* if the connection is not established, inform the stream that we want
 	 * to be notified whenever the connection completes.
 	 */
-	if (cs_opposite(cs)->si->state < SI_ST_EST) {
+	if (cs_opposite(cs)->state < CS_ST_EST) {
 		si_cant_get(cs->si);
 		si_rx_conn_blk(cs->si);
 		si_rx_endp_more(cs->si);
@@ -477,7 +477,7 @@
 	 * the message so that we can take our reference there if we have to
 	 * stop before the end (ret=0).
 	 */
-	if (cs_opposite(cs)->si->state == SI_ST_EST) {
+	if (cs_opposite(cs)->state == CS_ST_EST) {
 		/* we were already there, adjust the offset to be relative to
 		 * the buffer's head and remove us from the counter.
 		 */
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
index 619043b..b082c4b 100644
--- a/src/flt_spoe.c
+++ b/src/flt_spoe.c
@@ -1344,13 +1344,13 @@
 	char *frame, *buf;
 	int   ret;
 
-	if (si_state_in(cs->si->state, SI_SB_CER|SI_SB_DIS|SI_SB_CLO)) {
+	if (cs_state_in(cs->state, CS_SB_CER|CS_SB_DIS|CS_SB_CLO)) {
 		/* closed */
 		SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
 		goto exit;
 	}
 
-	if (!si_state_in(cs->si->state, SI_SB_RDY|SI_SB_EST)) {
+	if (!cs_state_in(cs->state, CS_SB_RDY|CS_SB_EST)) {
 		/* not connected yet */
 		si_rx_endp_more(cs->si);
 		task_wakeup(__cs_strm(cs)->task, TASK_WOKEN_MSG);
@@ -1411,7 +1411,7 @@
 	int    ret;
 
 
-	if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO) {
+	if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO) {
 		SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
 		goto exit;
 	}
@@ -1663,7 +1663,7 @@
 	struct spoe_agent       *agent = SPOE_APPCTX(appctx)->agent;
 	int ret, skip_sending = 0, skip_receiving = 0, active_s = 0, active_r = 0, close_asap = 0;
 
-	if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO) {
+	if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO) {
 		SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
 		goto exit;
 	}
@@ -1786,7 +1786,7 @@
 	char *frame, *buf;
 	int   ret;
 
-	if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO)
+	if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO)
 		goto exit;
 
 	if (appctx->st1 == SPOE_APPCTX_ERR_TOUT)
@@ -1838,7 +1838,7 @@
 	char  *frame;
 	int    ret;
 
-	if (cs->si->state == SI_ST_CLO || cs_opposite(cs)->si->state == SI_ST_CLO) {
+	if (cs->state == CS_ST_CLO || cs_opposite(cs)->state == CS_ST_CLO) {
 		SPOE_APPCTX(appctx)->status_code = SPOE_FRM_ERR_IO;
 		goto exit;
 	}
diff --git a/src/hlua.c b/src/hlua.c
index 60b9923..c16dbf5 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -1931,7 +1931,7 @@
 	/* if the connection is not established, inform the stream that we want
 	 * to be notified whenever the connection completes.
 	 */
-	if (cs_opposite(cs)->si->state < SI_ST_EST) {
+	if (cs_opposite(cs)->state < CS_ST_EST) {
 		si_cant_get(cs->si);
 		si_rx_conn_blk(cs->si);
 		si_rx_endp_more(cs->si);
@@ -2970,7 +2970,7 @@
 	 * and retrieve data from the server. The connection is initialized
 	 * with the "struct server".
 	 */
-	si_set_state(cs_si(s->csb), SI_ST_ASS);
+	cs_set_state(s->csb, CS_ST_ASS);
 
 	/* Force destination server. */
 	s->flags |= SF_DIRECT | SF_ASSIGNED | SF_BE_ASSIGNED;
@@ -9284,7 +9284,7 @@
 	}
 
 	/* If the stream is disconnect or closed, ldo nothing. */
-	if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+	if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
 		return;
 
 	/* Execute the function. */
@@ -9474,7 +9474,7 @@
 	res_htx = htx_from_buf(&res->buf);
 
 	/* If the stream is disconnect or closed, ldo nothing. */
-	if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+	if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
 		goto out;
 
 	/* Check if the input buffer is available. */
@@ -10099,7 +10099,7 @@
 	fcn = appctx->ctx.hlua_cli.fcn;
 
 	/* If the stream is disconnect or closed, ldo nothing. */
-	if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+	if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
 		return 1;
 
 	/* Execute the function. */
diff --git a/src/http_ana.c b/src/http_ana.c
index ba64b17..6051c7b 100644
--- a/src/http_ana.c
+++ b/src/http_ana.c
@@ -4263,7 +4263,7 @@
 	si_shutr(si);
 	si_shutw(si);
 	s->conn_err_type = STRM_ET_NONE;
-	si->state = SI_ST_CLO;
+	si->cs->state = CS_ST_CLO;
 
 	if (!(s->flags & SF_ERR_MASK))
 		s->flags |= SF_ERR_LOCAL;
diff --git a/src/peers.c b/src/peers.c
index 7c40e45..d77010d 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -3817,7 +3817,7 @@
 	peer_cs = peer->appctx->owner;
 	peer_s = __cs_strm(peer_cs);
 
-	chunk_appendf(&trash, " state=%s", si_state_str(cs_opposite(peer_cs)->si->state));
+	chunk_appendf(&trash, " state=%s", cs_state_str(cs_opposite(peer_cs)->state));
 
 	conn = objt_conn(strm_orig(peer_s));
 	if (conn)
diff --git a/src/sink.c b/src/sink.c
index 8dfe33e..f739b37 100644
--- a/src/sink.c
+++ b/src/sink.c
@@ -329,7 +329,7 @@
 	/* if the connection is not established, inform the stream that we want
 	 * to be notified whenever the connection completes.
 	 */
-	if (cs_opposite(cs)->si->state < SI_ST_EST) {
+	if (cs_opposite(cs)->state < CS_ST_EST) {
 		si_cant_get(cs->si);
 		si_rx_conn_blk(cs->si);
 		si_rx_endp_more(cs->si);
@@ -368,7 +368,7 @@
 	 * the message so that we can take our reference there if we have to
 	 * stop before the end (ret=0).
 	 */
-	if (cs_opposite(cs)->si->state == SI_ST_EST) {
+	if (cs_opposite(cs)->state == CS_ST_EST) {
 		/* we were already there, adjust the offset to be relative to
 		 * the buffer's head and remove us from the counter.
 		 */
@@ -469,7 +469,7 @@
 	/* if the connection is not established, inform the stream that we want
 	 * to be notified whenever the connection completes.
 	 */
-	if (cs_opposite(cs)->si->state < SI_ST_EST) {
+	if (cs_opposite(cs)->state < CS_ST_EST) {
 		si_cant_get(cs->si);
 		si_rx_conn_blk(cs->si);
 		si_rx_endp_more(cs->si);
@@ -508,7 +508,7 @@
 	 * the message so that we can take our reference there if we have to
 	 * stop before the end (ret=0).
 	 */
-	if (cs_opposite(cs)->si->state == SI_ST_EST) {
+	if (cs_opposite(cs)->state == CS_ST_EST) {
 		/* we were already there, adjust the offset to be relative to
 		 * the buffer's head and remove us from the counter.
 		 */
diff --git a/src/stats.c b/src/stats.c
index a613a12..a8a8238 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -4278,7 +4278,7 @@
 
 	res_htx = htx_from_buf(&res->buf);
 
-	if (unlikely(cs->si->state == SI_ST_DIS || cs->si->state == SI_ST_CLO))
+	if (unlikely(cs->state == CS_ST_DIS || cs->state == CS_ST_CLO))
 		goto out;
 
 	/* Check if the input buffer is available. */
diff --git a/src/stream.c b/src/stream.c
index 5ee4a88..d865125 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -94,7 +94,7 @@
 	{ .mask = STRM_EV_STRM_ANA,     .name = "strm_ana",     .desc = "stream analyzers" },
 	{ .mask = STRM_EV_STRM_PROC,    .name = "strm_proc",    .desc = "stream processing" },
 
-	{ .mask = STRM_EV_SI_ST,        .name = "si_state",     .desc = "processing stream-interface states" },
+	{ .mask = STRM_EV_CS_ST,        .name = "cs_state",     .desc = "processing conn-stream states" },
 
 	{ .mask = STRM_EV_HTTP_ANA,     .name = "http_ana",     .desc = "HTTP analyzers" },
 	{ .mask = STRM_EV_HTTP_ERR,     .name = "http_err",     .desc = "error during HTTP analyzis" },
@@ -177,8 +177,8 @@
 	}
 
 	/* Front and back stream-int state */
-	chunk_appendf(&trace_buf, " SI=(%s,%s)",
-		      si_state_str(si_f->state), si_state_str(si_b->state));
+	chunk_appendf(&trace_buf, " CS=(%s,%s)",
+		      cs_state_str(s->csf->state), cs_state_str(s->csb->state));
 
 	/* If txn is defined, HTTP req/rep states */
 	if (txn)
@@ -422,7 +422,7 @@
 	s->conn_retries = 0;
 	s->conn_exp = TICK_ETERNITY;
 	s->conn_err_type = STRM_ET_NONE;
-	s->prev_conn_state = SI_ST_INI;
+	s->prev_conn_state = CS_ST_INI;
 	t->process = process_stream;
 	t->context = s;
 	t->expire = TICK_ETERNITY;
@@ -455,7 +455,7 @@
 	if (!s->csb)
 		goto out_fail_alloc_csb;
 
-	si_set_state(cs_si(s->csf), SI_ST_EST);
+	cs_set_state(s->csf, CS_ST_EST);
 	s->csf->hcto = sess->fe->timeout.clientfin;
 
 	if (likely(sess->fe->options2 & PR_O2_INDEPSTR))
@@ -850,13 +850,13 @@
 }
 
 /*
- * This function handles the transition between the SI_ST_CON state and the
- * SI_ST_EST state. It must only be called after switching from SI_ST_CON (or
- * SI_ST_INI or SI_ST_RDY) to SI_ST_EST, but only when a ->proto is defined.
- * Note that it will switch the interface to SI_ST_DIS if we already have
+ * This function handles the transition between the CS_ST_CON state and the
+ * CS_ST_EST state. It must only be called after switching from CS_ST_CON (or
+ * CS_ST_INI or CS_ST_RDY) to CS_ST_EST, but only when a ->proto is defined.
+ * Note that it will switch the interface to CS_ST_DIS if we already have
  * the CF_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 SI_ST_CON to SI_ST_EST. When that happens, we want
+ * make the switch from CS_ST_CON to CS_ST_EST. When that happens, we want
  * to go through back_establish() anyway, to make sure the analysers run.
  * Timeouts are cleared. Error are reported on the channel so that analysers
  * can handle them.
@@ -868,7 +868,7 @@
 	struct channel *req = &s->req;
 	struct channel *rep = &s->res;
 
-	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_ENTER(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 	/* First, centralize the timers information, and clear any irrelevant
 	 * timeout.
 	 */
@@ -887,7 +887,7 @@
 			req->flags |= CF_WRITE_ERROR;
 		rep->flags |= CF_READ_ERROR;
 		s->conn_err_type = STRM_ET_DATA_ERR;
-		DBG_TRACE_STATE("read/write error", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+		DBG_TRACE_STATE("read/write error", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
 	}
 
 	if (objt_server(s->target))
@@ -931,13 +931,13 @@
 	}
 	req->wex = TICK_ETERNITY;
 	/* If we managed to get the whole response, and we don't have anything
-	 * left to send, or can't, switch to SI_ST_DIS now. */
+	 * left to send, or can't, switch to CS_ST_DIS now. */
 	if (rep->flags & (CF_SHUTR | CF_SHUTW)) {
-		si->state = SI_ST_DIS;
-		DBG_TRACE_STATE("response channel shutdwn for read/write", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
+		s->csb->state = CS_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_LEAVE(STRM_EV_STRM_PROC|STRM_EV_SI_ST, s);
+	DBG_TRACE_LEAVE(STRM_EV_STRM_PROC|STRM_EV_CS_ST, s);
 }
 
 /* Set correct stream termination flags in case no analyser has done it. It
@@ -947,7 +947,7 @@
 static void sess_set_term_flags(struct stream *s)
 {
 	if (!(s->flags & SF_FINST_MASK)) {
-		if (cs_si(s->csb)->state == SI_ST_INI) {
+		if (s->csb->state == CS_ST_INI) {
 			/* anything before REQ in fact */
 			_HA_ATOMIC_INC(&strm_fe(s)->fe_counters.failed_req);
 			if (strm_li(s) && strm_li(s)->counters)
@@ -955,11 +955,11 @@
 
 			s->flags |= SF_FINST_R;
 		}
-		else if (cs_si(s->csb)->state == SI_ST_QUE)
+		else if (s->csb->state == CS_ST_QUE)
 			s->flags |= SF_FINST_Q;
-		else if (si_state_in(cs_si(s->csb)->state, SI_SB_REQ|SI_SB_TAR|SI_SB_ASS|SI_SB_CON|SI_SB_CER|SI_SB_RDY))
+		else if (cs_state_in(s->csb->state, CS_SB_REQ|CS_SB_TAR|CS_SB_ASS|CS_SB_CON|CS_SB_CER|CS_SB_RDY))
 			s->flags |= SF_FINST_C;
-		else if (cs_si(s->csb)->state == SI_ST_EST || s->prev_conn_state == SI_ST_EST)
+		else if (s->csb->state == CS_ST_EST || s->prev_conn_state == CS_ST_EST)
 			s->flags |= SF_FINST_D;
 		else
 			s->flags |= SF_FINST_L;
@@ -1709,7 +1709,7 @@
 	 */
 	srv = objt_server(s->target);
 	if (unlikely(s->csf->endp->flags & CS_EP_ERROR)) {
-		if (si_state_in(si_f->state, SI_SB_EST|SI_SB_DIS)) {
+		if (cs_state_in(s->csf->state, CS_SB_EST|CS_SB_DIS)) {
 			si_shutr(si_f);
 			si_shutw(si_f);
 			cs_report_error(si_f->cs);
@@ -1729,7 +1729,7 @@
 	}
 
 	if (unlikely(s->csb->endp->flags & CS_EP_ERROR)) {
-		if (si_state_in(si_b->state, SI_SB_EST|SI_SB_DIS)) {
+		if (cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS)) {
 			si_shutr(si_b);
 			si_shutw(si_b);
 			cs_report_error(si_b->cs);
@@ -1752,37 +1752,37 @@
 		/* note: maybe we should process connection errors here ? */
 	}
 
-	if (si_state_in(si_b->state, SI_SB_CON|SI_SB_RDY)) {
+	if (cs_state_in(s->csb->state, CS_SB_CON|CS_SB_RDY)) {
 		/* we were trying to establish a connection on the server side,
 		 * maybe it succeeded, maybe it failed, maybe we timed out, ...
 		 */
-		if (si_b->state == SI_ST_RDY)
+		if (s->csb->state == CS_ST_RDY)
 			back_handle_st_rdy(s);
-		else if (si_b->state == SI_ST_CON)
+		else if (s->csb->state == CS_ST_CON)
 			back_handle_st_con(s);
 
-		if (si_b->state == SI_ST_CER)
+		if (s->csb->state == CS_ST_CER)
 			back_handle_st_cer(s);
-		else if (si_b->state == SI_ST_EST)
+		else if (s->csb->state == CS_ST_EST)
 			back_establish(s);
 
-		/* state is now one of SI_ST_CON (still in progress), SI_ST_EST
-		 * (established), SI_ST_DIS (abort), SI_ST_CLO (last error),
-		 * SI_ST_ASS/SI_ST_TAR/SI_ST_REQ for retryable errors.
+		/* state is now one of CS_ST_CON (still in progress), CS_ST_EST
+		 * (established), CS_ST_DIS (abort), CS_ST_CLO (last error),
+		 * CS_ST_ASS/CS_ST_TAR/CS_ST_REQ for retryable errors.
 		 */
 	}
 
-	rq_prod_last = si_f->state;
-	rq_cons_last = si_b->state;
-	rp_cons_last = si_f->state;
-	rp_prod_last = si_b->state;
+	rq_prod_last = s->csf->state;
+	rq_cons_last = s->csb->state;
+	rp_cons_last = s->csf->state;
+	rp_prod_last = s->csb->state;
 
 	/* Check for connection closure */
 	DBG_TRACE_POINT(STRM_EV_STRM_PROC, s);
 
 	/* nothing special to be done on client side */
-	if (unlikely(si_f->state == SI_ST_DIS)) {
-		si_f->state = SI_ST_CLO;
+	if (unlikely(s->csf->state == CS_ST_DIS)) {
+		s->csf->state = CS_ST_CLO;
 
 		/* This is needed only when debugging is enabled, to indicate
 		 * client-side close.
@@ -1801,8 +1801,8 @@
 	/* When a server-side connection is released, we have to count it and
 	 * check for pending connections on this server.
 	 */
-	if (unlikely(si_b->state == SI_ST_DIS)) {
-		si_b->state = SI_ST_CLO;
+	if (unlikely(s->csb->state == CS_ST_DIS)) {
+		s->csb->state = CS_ST_CLO;
 		srv = objt_server(s->target);
 		if (srv) {
 			if (s->flags & SF_CURR_SESS) {
@@ -1820,7 +1820,7 @@
 		if (unlikely((global.mode & MODE_DEBUG) &&
 			     (!(global.mode & MODE_QUIET) ||
 			      (global.mode & MODE_VERBOSE)))) {
-			if (s->prev_conn_state == SI_ST_EST) {
+			if (s->prev_conn_state == CS_ST_EST) {
 				chunk_printf(&trash, "%08x:%s.srvcls[%04x:%04x]\n",
 					     s->uniq_id, s->be->id,
 					     (unsigned short)conn_fd(__cs_conn(si_f->cs)),
@@ -1840,12 +1840,12 @@
 	if (((req->flags & ~rqf_last) & CF_MASK_ANALYSER) ||
 	    ((req->flags ^ rqf_last) & CF_MASK_STATIC) ||
 	    (req->analysers && (req->flags & CF_SHUTW)) ||
-	    si_f->state != rq_prod_last ||
-	    si_b->state != rq_cons_last ||
+	    s->csf->state != rq_prod_last ||
+	    s->csb->state != rq_cons_last ||
 	    s->pending_events & TASK_WOKEN_MSG) {
 		unsigned int flags = req->flags;
 
-		if (si_state_in(si_f->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO)) {
+		if (cs_state_in(s->csf->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO)) {
 			int max_loops = global.tune.maxpollevents;
 			unsigned int ana_list;
 			unsigned int ana_back;
@@ -1920,8 +1920,8 @@
 			}
 		}
 
-		rq_prod_last = si_f->state;
-		rq_cons_last = si_b->state;
+		rq_prod_last = s->csf->state;
+		rq_cons_last = s->csb->state;
 		req->flags &= ~CF_WAKE_ONCE;
 		rqf_last = req->flags;
 
@@ -1941,12 +1941,12 @@
 	if (((res->flags & ~rpf_last) & CF_MASK_ANALYSER) ||
 		 (res->flags ^ rpf_last) & CF_MASK_STATIC ||
 		 (res->analysers && (res->flags & CF_SHUTW)) ||
-		 si_f->state != rp_cons_last ||
-		 si_b->state != rp_prod_last ||
+		 s->csf->state != rp_cons_last ||
+		 s->csb->state != rp_prod_last ||
 		 s->pending_events & TASK_WOKEN_MSG) {
 		unsigned int flags = res->flags;
 
-		if (si_state_in(si_b->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO)) {
+		if (cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO)) {
 			int max_loops = global.tune.maxpollevents;
 			unsigned int ana_list;
 			unsigned int ana_back;
@@ -1989,8 +1989,8 @@
 			}
 		}
 
-		rp_cons_last = si_f->state;
-		rp_prod_last = si_b->state;
+		rp_cons_last = s->csf->state;
+		rp_prod_last = s->csb->state;
 		res->flags &= ~CF_WAKE_ONCE;
 		rpf_last = res->flags;
 
@@ -2059,11 +2059,11 @@
 			sess_set_term_flags(s);
 
 			/* Abort the request if a client error occurred while
-			 * the backend stream-interface is in the SI_ST_INI
-			 * state. It is switched into the SI_ST_CLO state and
+			 * the backend stream-interface is in the CS_ST_INI
+			 * state. It is switched into the CS_ST_CLO state and
 			 * the request channel is erased. */
-			if (si_b->state == SI_ST_INI) {
-				si_b->state = SI_ST_CLO;
+			if (s->csb->state == CS_ST_INI) {
+				s->csb->state = CS_ST_CLO;
 				channel_abort(req);
 				if (IS_HTX_STRM(s))
 					channel_htx_erase(req, htxbuf(&req->buf));
@@ -2127,7 +2127,7 @@
 	 */
 	if (unlikely((!req->analysers || (req->analysers == AN_REQ_FLT_END && !(req->flags & CF_FLT_ANALYZE))) &&
 	    !(req->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
-	    (si_state_in(si_f->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO)) &&
+	    (cs_state_in(s->csf->state, CS_SB_EST|CS_SB_DIS|CS_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
@@ -2180,14 +2180,14 @@
 	 *  - there are data scheduled for emission in the buffer
 	 *  - the CF_AUTO_CONNECT flag is set (active connection)
 	 */
-	if (si_b->state == SI_ST_INI) {
+	if (s->csb->state == CS_ST_INI) {
 		if (!(req->flags & CF_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
 				 * perform a connection request.
 				 */
-				si_b->state = SI_ST_REQ; /* new connection requested */
+				s->csb->state = CS_ST_REQ; /* new connection requested */
 				s->conn_retries = 0;
 				if ((s->be->retry_type &~ PR_RE_CONN_FAILED) &&
 				    (s->be->mode == PR_MODE_HTTP) &&
@@ -2197,7 +2197,7 @@
 		}
 		else {
 			cs_detach_endp(s->csb);
-			si_b->state = SI_ST_CLO; /* shutw+ini = abort */
+			s->csb->state = CS_ST_CLO; /* shutw+ini = abort */
 			channel_shutw_now(req);        /* fix buffer flags upon abort */
 			channel_shutr_now(res);
 		}
@@ -2207,7 +2207,7 @@
 	/* we may have a pending connection request, or a connection waiting
 	 * for completion.
 	 */
-	if (si_state_in(si_b->state, SI_SB_REQ|SI_SB_QUE|SI_SB_TAR|SI_SB_ASS)) {
+	if (cs_state_in(s->csb->state, CS_SB_REQ|CS_SB_QUE|CS_SB_TAR|CS_SB_ASS)) {
 		/* prune the request variables and swap to the response variables. */
 		if (s->vars_reqres.scope != SCOPE_RES) {
 			if (!LIST_ISEMPTY(&s->vars_reqres.head))
@@ -2219,26 +2219,26 @@
 			/* nb: step 1 might switch from QUE to ASS, but we first want
 			 * to give a chance to step 2 to perform a redirect if needed.
 			 */
-			if (si_b->state != SI_ST_REQ)
+			if (s->csb->state != CS_ST_REQ)
 				back_try_conn_req(s);
-			if (si_b->state == SI_ST_REQ)
+			if (s->csb->state == CS_ST_REQ)
 				back_handle_st_req(s);
 
 			/* get a chance to complete an immediate connection setup */
-			if (si_b->state == SI_ST_RDY)
+			if (s->csb->state == CS_ST_RDY)
 				goto resync_stream_interface;
 
 			/* applets directly go to the ESTABLISHED state. Similarly,
 			 * servers experience the same fate when their connection
 			 * is reused.
 			 */
-			if (unlikely(si_b->state == SI_ST_EST))
+			if (unlikely(s->csb->state == CS_ST_EST))
 				back_establish(s);
 
 			srv = objt_server(s->target);
-			if (si_b->state == SI_ST_ASS && srv && srv->rdr_len && (s->flags & SF_REDIRECTABLE))
+			if (s->csb->state == CS_ST_ASS && srv && srv->rdr_len && (s->flags & SF_REDIRECTABLE))
 				http_perform_server_redirect(s, si_b);
-		} while (si_b->state == SI_ST_ASS);
+		} while (s->csb->state == CS_ST_ASS);
 	}
 
 	/* Let's see if we can send the pending request now */
@@ -2279,10 +2279,10 @@
 	}
 
 	/* Benchmarks have shown that it's optimal to do a full resync now */
-	if (si_f->state == SI_ST_DIS ||
-	    si_state_in(si_b->state, SI_SB_RDY|SI_SB_DIS) ||
-	    (s->csf->endp->flags & CS_EP_ERROR && si_f->state != SI_ST_CLO) ||
-	    (s->csb->endp->flags & CS_EP_ERROR && si_b->state != SI_ST_CLO))
+	if (s->csf->state == CS_ST_DIS ||
+	    cs_state_in(s->csb->state, CS_SB_RDY|CS_SB_DIS) ||
+	    (s->csf->endp->flags & CS_EP_ERROR && s->csf->state != CS_ST_CLO) ||
+	    (s->csb->endp->flags & CS_EP_ERROR && s->csb->state != CS_ST_CLO))
 		goto resync_stream_interface;
 
 	/* otherwise we want to check if we need to resync the req buffer or not */
@@ -2298,7 +2298,7 @@
 	 */
 	if (unlikely((!res->analysers || (res->analysers == AN_RES_FLT_END && !(res->flags & CF_FLT_ANALYZE))) &&
 	    !(res->flags & (CF_SHUTW|CF_SHUTR_NOW)) &&
-	    si_state_in(si_b->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) &&
+	    cs_state_in(s->csb->state, CS_SB_EST|CS_SB_DIS|CS_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
@@ -2403,10 +2403,10 @@
 		si_shutr(si_b);
 	}
 
-	if (si_f->state == SI_ST_DIS ||
-	    si_state_in(si_b->state, SI_SB_RDY|SI_SB_DIS) ||
-	    (s->csf->endp->flags & CS_EP_ERROR && si_f->state != SI_ST_CLO) ||
-	    (s->csb->endp->flags & CS_EP_ERROR && si_b->state != SI_ST_CLO))
+	if (s->csf->state == CS_ST_DIS ||
+	    cs_state_in(s->csb->state, CS_SB_RDY|CS_SB_DIS) ||
+	    (s->csf->endp->flags & CS_EP_ERROR && s->csf->state != CS_ST_CLO) ||
+	    (s->csb->endp->flags & CS_EP_ERROR && s->csb->state != CS_ST_CLO))
 		goto resync_stream_interface;
 
 	if ((req->flags & ~rqf_last) & CF_MASK_ANALYSER)
@@ -2422,7 +2422,7 @@
 	s->csf->flags &= ~CS_FL_DONT_WAKE;
 	s->csb->flags &= ~CS_FL_DONT_WAKE;
 
-	if (likely((si_f->state != SI_ST_CLO) || !si_state_in(si_b->state, SI_SB_INI|SI_SB_CLO) ||
+	if (likely((s->csf->state != CS_ST_CLO) || !cs_state_in(s->csb->state, CS_SB_INI|CS_SB_CLO) ||
 		   (req->analysers & AN_REQ_FLT_END) || (res->analysers & AN_RES_FLT_END))) {
 		if ((sess->fe->options & PR_O_CONTSTATS) && (s->flags & SF_BE_ASSIGNED) && !(s->flags & SF_IGNORE))
 			stream_process_counters(s);
@@ -2729,8 +2729,8 @@
 	chunk_appendf(buf,
 	              "%sstrm=%p,%x src=%s fe=%s be=%s dst=%s%c"
 		      "%stxn=%p,%x txn.req=%s,%x txn.rsp=%s,%x%c"
-	              "%srqf=%x rqa=%x rpf=%x rpa=%x sif=%s,%x sib=%s,%x%c"
-		      "%scsf=%p,%x csb=%p,%x%c"
+	              "%srqf=%x rqa=%x rpf=%x rpa=%x sif=%x sib=%x%c"
+		      "%scsf=%p,%s,%x csb=%p,%s,%x%c"
 	              "%saf=%p,%u sab=%p,%u%c"
 	              "%scof=%p,%x:%s(%p)/%s(%p)/%s(%d)%c"
 	              "%scob=%p,%x:%s(%p)/%s(%p)/%s(%d)%c"
@@ -2739,10 +2739,8 @@
 		      pfx, s->txn, (s->txn ? s->txn->flags : 0),
 		           (s->txn ? h1_msg_state_str(s->txn->req.msg_state): "-"), (s->txn ? s->txn->req.flags : 0),
 		           (s->txn ? h1_msg_state_str(s->txn->rsp.msg_state): "-"), (s->txn ? s->txn->rsp.flags : 0), eol,
-	              pfx, req->flags, req->analysers, res->flags, res->analysers,
-	                   si_state_str(si_f->state), si_f->flags,
-	                   si_state_str(si_b->state), si_b->flags, eol,
-		      pfx, csf, csf->flags, csb, csb->flags, eol,
+	              pfx, req->flags, req->analysers, res->flags, res->analysers, si_f->flags, si_b->flags, eol,
+		      pfx, csf, cs_state_str(csf->state), csf->flags, csb, cs_state_str(csb->state), csb->flags, eol,
 	              pfx, acf, acf ? acf->st0   : 0, acb, acb ? acb->st0   : 0, eol,
 	              pfx, cof, cof ? cof->flags : 0, conn_get_mux_name(cof), cof?cof->ctx:0, conn_get_xprt_name(cof),
 		           cof ? cof->xprt_ctx : 0, conn_get_ctrl_name(cof), conn_fd(cof), eol,
@@ -3251,23 +3249,22 @@
 			      strm->txn->req.flags, strm->txn->rsp.flags);
 
 		chunk_appendf(&trash,
-			     "  si[0]=%p (state=%s flags=0x%02x endp0=%s:%p sub=%d)\n",
+			     "  si[0]=%p (flags=0x%02x endp0=%s:%p sub=%d)\n",
 			     strm->csf->si,
-			     si_state_str(strm->csf->si->state),
 			     strm->csf->si->flags,
 			     (strm->csf->endp->flags & CS_EP_T_MUX ? "CONN" : "APPCTX"),
 			      __cs_endp_target(strm->csf), strm->csf->si->wait_event.events);
 
 		chunk_appendf(&trash,
-			     "  si[1]=%p (state=%s flags=0x%02x endp1=%s:%p sub=%d)\n",
+			     "  si[1]=%p (flags=0x%02x endp1=%s:%p sub=%d)\n",
 			     strm->csb->si,
-			     si_state_str(strm->csb->si->state),
 			     strm->csb->si->flags,
 			     (strm->csb->endp->flags & CS_EP_T_MUX ? "CONN" : "APPCTX"),
 			      __cs_endp_target(strm->csb), strm->csb->si->wait_event.events);
 
 		csf = strm->csf;
-		chunk_appendf(&trash, "  cs=%p csf=0x%08x endp=%p,0x%08x\n", csf, csf->flags, csf->endp->target, csf->endp->flags);
+		chunk_appendf(&trash, "  cs=%p csf=0x%08x state=%s endp=%p,0x%08x\n", csf, csf->flags,
+			      cs_state_str(csf->state), csf->endp->target, csf->endp->flags);
 
 		if ((conn = cs_conn(csf)) != NULL) {
 			chunk_appendf(&trash,
@@ -3303,7 +3300,8 @@
 		}
 
 		csb = strm->csb;
-		chunk_appendf(&trash, "  cs=%p csb=0x%08x endp=%p,0x%08x\n", csb, csb->flags, csb->endp->target, csb->endp->flags);
+		chunk_appendf(&trash, "  cs=%p csb=0x%08x state=%s endp=%p,0x%08x\n", csb, csb->flags,
+			      cs_state_str(csb->state), csb->endp->target, csb->endp->flags);
 		if ((conn = cs_conn(csb)) != NULL) {
 			chunk_appendf(&trash,
 			              "      co1=%p ctrl=%s xprt=%s mux=%s data=%s target=%s:%p\n",
@@ -3638,15 +3636,15 @@
 
 			conn = cs_conn(curr_strm->csf);
 			chunk_appendf(&trash,
-				     " s0=[%d,%1xh,fd=%d]",
-				     curr_strm->csf->si->state,
+				     " s0=[%1xh,fd=%d]",
+				      //curr_strm->csf->si->state,
 				     curr_strm->csf->si->flags,
 				     conn_fd(conn));
 
 			conn = cs_conn(curr_strm->csb);
 			chunk_appendf(&trash,
-				     " s1=[%d,%1xh,fd=%d]",
-				     curr_strm->csb->si->state,
+				     " s1=[%1xh,fd=%d]",
+				      //curr_strm->csb->si->state,
 				     curr_strm->csb->si->flags,
 				     conn_fd(conn));
 
diff --git a/src/stream_interface.c b/src/stream_interface.c
index 3f38fb7..9bcfb2c 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -175,11 +175,11 @@
 	ic->flags |= CF_SHUTR;
 	ic->rex = TICK_ETERNITY;
 
-	if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+	if (!cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
 		return;
 
 	if (si_oc(si)->flags & CF_SHUTW) {
-		si->state = SI_ST_DIS;
+		si->cs->state = CS_ST_DIS;
 		__cs_strm(si->cs)->conn_exp = TICK_ETERNITY;
 	}
 	else if (si->cs->flags & CS_FL_NOHALF) {
@@ -216,9 +216,9 @@
 		ic->rex = tick_add(now_ms, ic->rto);
 	}
 
-	switch (si->state) {
-	case SI_ST_RDY:
-	case SI_ST_EST:
+	switch (si->cs->state) {
+	case CS_ST_RDY:
+	case CS_ST_EST:
 		/* we have to shut before closing, otherwise some short messages
 		 * may never leave the system, especially when there are remaining
 		 * unread data in the socket input buffer, or when nolinger is set.
@@ -230,12 +230,12 @@
 			return;
 
 		/* fall through */
-	case SI_ST_CON:
-	case SI_ST_CER:
-	case SI_ST_QUE:
-	case SI_ST_TAR:
+	case CS_ST_CON:
+	case CS_ST_CER:
+	case CS_ST_QUE:
+	case CS_ST_TAR:
 		/* Note that none of these states may happen with applets */
-		si->state = SI_ST_DIS;
+		si->cs->state = CS_ST_DIS;
 		/* fall through */
 	default:
 		si->cs->flags &= ~CS_FL_NOLINGER;
@@ -255,9 +255,9 @@
 {
 	struct channel *ic = si_ic(si);
 
-	DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+	DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
 		__FUNCTION__,
-		si, si->state, ic->flags, si_oc(si)->flags);
+		si, si->cs->state, ic->flags, si_oc(si)->flags);
 
 	if (ic->pipe) {
 		/* stop reading */
@@ -276,11 +276,11 @@
 {
 	struct channel *oc = si_oc(si);
 
-	DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+	DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
 		__FUNCTION__,
-		si, si->state, si_ic(si)->flags, oc->flags);
+		si, si->cs->state, si_ic(si)->flags, oc->flags);
 
-	if (unlikely(si->state != SI_ST_EST || (oc->flags & CF_SHUTW)))
+	if (unlikely(si->cs->state != CS_ST_EST || (oc->flags & CF_SHUTW)))
 		return;
 
 	if (!(si->flags & SI_FL_WAIT_DATA) ||        /* not waiting for data */
@@ -439,7 +439,7 @@
 		struct connection *conn = cs_conn(si->cs);
 
 		if (((oc->flags & (CF_SHUTW|CF_SHUTW_NOW)) == CF_SHUTW_NOW) &&
-		    (si->state == SI_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS))))
+		    (si->cs->state == CS_ST_EST) && (!conn || !(conn->flags & (CO_FL_WAIT_XPRT | CO_FL_EARLY_SSL_HS))))
 			si_shutw(si);
 		oc->wex = TICK_ETERNITY;
 	}
@@ -520,10 +520,10 @@
 	/* wake the task up only when needed */
 	if (/* changes on the production side */
 	    (ic->flags & (CF_READ_NULL|CF_READ_ERROR)) ||
-	    !si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST) ||
+	    !cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST) ||
 	    (si->cs->endp->flags & CS_EP_ERROR) ||
 	    ((ic->flags & CF_READ_PARTIAL) &&
-	     ((ic->flags & CF_EOI) || !ic->to_forward || sio->state != SI_ST_EST)) ||
+	     ((ic->flags & CF_EOI) || !ic->to_forward || sio->cs->state != CS_ST_EST)) ||
 
 	    /* changes on the consumption side */
 	    (oc->flags & (CF_WRITE_NULL|CF_WRITE_ERROR)) ||
@@ -531,7 +531,7 @@
 	     ((oc->flags & CF_SHUTW) ||
 	      (((oc->flags & CF_WAKE_WRITE) ||
 		!(oc->flags & (CF_AUTO_CLOSE|CF_SHUTW_NOW|CF_SHUTW))) &&
-	       (sio->state != SI_ST_EST ||
+	       (sio->cs->state != CS_ST_EST ||
 	        (channel_is_empty(oc) && !oc->to_forward)))))) {
 		task_wakeup(task, TASK_WOKEN_IO);
 	}
@@ -553,7 +553,7 @@
 
 /* The stream interface is only responsible for the connection during the early
  * states, before plugging a mux. Thus it should only care about CO_FL_ERROR
- * before SI_ST_EST, and after that it must absolutely ignore it since the mux
+ * before CS_ST_EST, and after that it must absolutely ignore it since the mux
  * may hold pending data. This function returns true if such an error was
  * reported. Both the CS and the CONN must be valid.
  */
@@ -561,7 +561,7 @@
 {
 	struct connection *conn;
 
-	if (si->state >= SI_ST_EST)
+	if (si->cs->state >= CS_ST_EST)
 		return 0;
 
 	conn = __cs_conn(si->cs);
@@ -601,7 +601,7 @@
 	 *       care of it.
 	 */
 
-	if (si->state >= SI_ST_CON) {
+	if (si->cs->state >= CS_ST_CON) {
 		if (si_is_conn_error(si))
 			cs->endp->flags |= CS_EP_ERROR;
 	}
@@ -617,12 +617,12 @@
 		task_wakeup(si_task(si), TASK_WOKEN_MSG);
 	}
 
-	if (!si_state_in(si->state, SI_SB_EST|SI_SB_DIS|SI_SB_CLO) &&
+	if (!cs_state_in(si->cs->state, CS_SB_EST|CS_SB_DIS|CS_SB_CLO) &&
 	    (conn->flags & CO_FL_WAIT_XPRT) == 0) {
 		__cs_strm(cs)->conn_exp = TICK_ETERNITY;
 		oc->flags |= CF_WRITE_NULL;
-		if (si->state == SI_ST_CON)
-			si->state = SI_ST_RDY;
+		if (si->cs->state == CS_ST_CON)
+			si->cs->state = CS_ST_RDY;
 	}
 
 	/* Report EOS on the channel if it was reached from the mux point of
@@ -677,11 +677,11 @@
 	if (cs->endp->flags & (CS_EP_ERROR|CS_EP_ERR_PENDING) || si_is_conn_error(si)) {
 		/* We're probably there because the tasklet was woken up,
 		 * but process_stream() ran before, detected there were an
-		 * error and put the si back to SI_ST_TAR. There's still
+		 * error and put the si back to CS_ST_TAR. There's still
 		 * CO_FL_ERROR on the connection but we don't want to add
 		 * CS_EP_ERROR back, so give up
 		 */
-		if (si->state < SI_ST_CON)
+		if (si->cs->state < CS_ST_CON)
 			return 0;
 		cs->endp->flags |= CS_EP_ERROR;
 		return 1;
@@ -790,8 +790,8 @@
  end:
 	if (did_send) {
 		oc->flags |= CF_WRITE_PARTIAL | CF_WROTE_DATA;
-		if (si->state == SI_ST_CON)
-			si->state = SI_ST_RDY;
+		if (si->cs->state == CS_ST_CON)
+			si->cs->state = CS_ST_RDY;
 
 		si_rx_room_rdy(si_opposite(si));
 	}
@@ -933,7 +933,7 @@
  */
 int si_sync_recv(struct stream_interface *si)
 {
-	if (!si_state_in(si->state, SI_SB_RDY|SI_SB_EST))
+	if (!cs_state_in(si->cs->state, CS_SB_RDY|CS_SB_EST))
 		return 0;
 
 	if (!cs_conn_mux(si->cs))
@@ -964,7 +964,7 @@
 	if (channel_is_empty(oc))
 		return;
 
-	if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+	if (!cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
 		return;
 
 	if (!cs_conn_mux(si->cs))
@@ -988,13 +988,13 @@
 	req->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
 	res->flags &= ~(CF_READ_NULL|CF_READ_PARTIAL|CF_READ_ATTACHED|CF_WRITE_NULL|CF_WRITE_PARTIAL);
 
-	si_strm(si_b)->prev_conn_state = si_b->state;
+	si_strm(si_b)->prev_conn_state = si_b->cs->state;
 
 	/* let's recompute both sides states */
-	if (si_state_in(si_f->state, SI_SB_RDY|SI_SB_EST))
+	if (cs_state_in(si_f->cs->state, CS_SB_RDY|CS_SB_EST))
 		si_update(si_f);
 
-	if (si_state_in(si_b->state, SI_SB_RDY|SI_SB_EST))
+	if (cs_state_in(si_b->cs->state, CS_SB_RDY|CS_SB_EST))
 		si_update(si_b);
 
 	/* stream ints are processed outside of process_stream() and must be
@@ -1034,12 +1034,12 @@
 	ic->flags |= CF_SHUTR;
 	ic->rex = TICK_ETERNITY;
 
-	if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+	if (!cs_state_in(cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
 		return;
 
 	if (si_oc(si)->flags & CF_SHUTW) {
 		cs_close(cs);
-		si->state = SI_ST_DIS;
+		cs->state = CS_ST_DIS;
 		__cs_strm(cs)->conn_exp = TICK_ETERNITY;
 	}
 	else if (si->cs->flags & CS_FL_NOHALF) {
@@ -1076,9 +1076,9 @@
 		ic->rex = tick_add(now_ms, ic->rto);
 	}
 
-	switch (si->state) {
-	case SI_ST_RDY:
-	case SI_ST_EST:
+	switch (cs->state) {
+	case CS_ST_RDY:
+	case CS_ST_EST:
 		/* we have to shut before closing, otherwise some short messages
 		 * may never leave the system, especially when there are remaining
 		 * unread data in the socket input buffer, or when nolinger is set.
@@ -1111,16 +1111,16 @@
 		}
 
 		/* fall through */
-	case SI_ST_CON:
+	case CS_ST_CON:
 		/* we may have to close a pending connection, and mark the
 		 * response buffer as shutr
 		 */
 		cs_close(cs);
 		/* fall through */
-	case SI_ST_CER:
-	case SI_ST_QUE:
-	case SI_ST_TAR:
-		si->state = SI_ST_DIS;
+	case CS_ST_CER:
+	case CS_ST_QUE:
+	case CS_ST_TAR:
+		cs->state = CS_ST_DIS;
 		/* fall through */
 	default:
 		cs->flags &= ~CS_FL_NOLINGER;
@@ -1140,7 +1140,7 @@
 static void stream_int_chk_rcv_conn(struct stream_interface *si)
 {
 	/* (re)start reading */
-	if (si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+	if (cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
 		tasklet_wakeup(si->wait_event.tasklet);
 }
 
@@ -1157,7 +1157,7 @@
 
 	BUG_ON(!cs_conn(cs));
 
-	if (unlikely(!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST) ||
+	if (unlikely(!cs_state_in(cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST) ||
 	    (oc->flags & CF_SHUTW)))
 		return;
 
@@ -1173,7 +1173,7 @@
 
 	if (cs->endp->flags & (CS_EP_ERROR|CS_EP_ERR_PENDING) || si_is_conn_error(si)) {
 		/* Write error on the file descriptor */
-		if (si->state >= SI_ST_CON)
+		if (cs->state >= CS_ST_CON)
 			cs->endp->flags |= CS_EP_ERROR;
 		goto out_wakeup;
 	}
@@ -1189,7 +1189,7 @@
 		 */
 		if (((oc->flags & (CF_SHUTW|CF_AUTO_CLOSE|CF_SHUTW_NOW)) ==
 		     (CF_AUTO_CLOSE|CF_SHUTW_NOW)) &&
-		    si_state_in(si->state, SI_SB_RDY|SI_SB_EST)) {
+		    cs_state_in(cs->state, CS_SB_RDY|CS_SB_EST)) {
 			si_shutw(si);
 			goto out_wakeup;
 		}
@@ -1234,7 +1234,7 @@
 	if (likely((oc->flags & (CF_WRITE_NULL|CF_WRITE_ERROR|CF_SHUTW)) ||
 	          ((oc->flags & CF_WAKE_WRITE) &&
 	           ((channel_is_empty(oc) && !oc->to_forward) ||
-	            !si_state_in(si->state, SI_SB_EST))))) {
+	            !cs_state_in(cs->state, CS_SB_EST))))) {
 	out_wakeup:
 		if (!(si->cs->flags & CS_FL_DONT_WAKE))
 			task_wakeup(si_task(si), TASK_WOKEN_IO);
@@ -1256,7 +1256,7 @@
 	int flags = 0;
 
 	/* If not established yet, do nothing. */
-	if (si->state != SI_ST_EST)
+	if (cs->state != CS_ST_EST)
 		return 0;
 
 	/* If another call to si_cs_recv() failed, and we subscribed to
@@ -1590,7 +1590,7 @@
 	ic->flags |= CF_SHUTR;
 	ic->rex = TICK_ETERNITY;
 
-	if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+	if (!cs_state_in(cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
 		return;
 
 	if (oc->flags & CF_SHUTW)
@@ -1616,7 +1616,7 @@
 
 	si_done_get(si);
 
-	si->state = SI_ST_DIS;
+	cs->state = CS_ST_DIS;
 	__cs_strm(cs)->conn_exp = TICK_ETERNITY;
 	return;
 }
@@ -1680,12 +1680,12 @@
 
 	/* Note: on shutr, we don't call the applet */
 
-	if (!si_state_in(si->state, SI_SB_CON|SI_SB_RDY|SI_SB_EST))
+	if (!cs_state_in(si->cs->state, CS_SB_CON|CS_SB_RDY|CS_SB_EST))
 		return;
 
 	if (si_oc(si)->flags & CF_SHUTW) {
 		si_applet_release(si);
-		si->state = SI_ST_DIS;
+		si->cs->state = CS_ST_DIS;
 		__cs_strm(si->cs)->conn_exp = TICK_ETERNITY;
 	}
 	else if (si->cs->flags & CS_FL_NOHALF) {
@@ -1723,9 +1723,9 @@
 	/* on shutw we always wake the applet up */
 	appctx_wakeup(__cs_appctx(si->cs));
 
-	switch (si->state) {
-	case SI_ST_RDY:
-	case SI_ST_EST:
+	switch (si->cs->state) {
+	case CS_ST_RDY:
+	case CS_ST_EST:
 		/* we have to shut before closing, otherwise some short messages
 		 * may never leave the system, especially when there are remaining
 		 * unread data in the socket input buffer, or when nolinger is set.
@@ -1737,13 +1737,13 @@
 			return;
 
 		/* fall through */
-	case SI_ST_CON:
-	case SI_ST_CER:
-	case SI_ST_QUE:
-	case SI_ST_TAR:
+	case CS_ST_CON:
+	case CS_ST_CER:
+	case CS_ST_QUE:
+	case CS_ST_TAR:
 		/* Note that none of these states may happen with applets */
 		si_applet_release(si);
-		si->state = SI_ST_DIS;
+		si->cs->state = CS_ST_DIS;
 		/* fall through */
 	default:
 		si->cs->flags &= ~CS_FL_NOLINGER;
@@ -1761,9 +1761,9 @@
 
 	BUG_ON(!cs_appctx(si->cs));
 
-	DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+	DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
 		__FUNCTION__,
-		si, si->state, ic->flags, si_oc(si)->flags);
+		si, si->cs->state, ic->flags, si_oc(si)->flags);
 
 	if (!ic->pipe) {
 		/* (re)start reading */
@@ -1778,11 +1778,11 @@
 
 	BUG_ON(!cs_appctx(si->cs));
 
-	DPRINTF(stderr, "%s: si=%p, si->state=%d ic->flags=%08x oc->flags=%08x\n",
+	DPRINTF(stderr, "%s: si=%p, cs->state=%d ic->flags=%08x oc->flags=%08x\n",
 		__FUNCTION__,
-		si, si->state, si_ic(si)->flags, oc->flags);
+		si, si->cs->state, si_ic(si)->flags, oc->flags);
 
-	if (unlikely(si->state != SI_ST_EST || (oc->flags & CF_SHUTW)))
+	if (unlikely(si->cs->state != CS_ST_EST || (oc->flags & CF_SHUTW)))
 		return;
 
 	/* we only wake the applet up if it was waiting for some data */