MAJOR: conn-stream: Invert conn-stream endpoint and its context

This change is only significant for the multiplexer part. For the applets,
the context and the endpoint are the same. Thus, there is no much change. For
the multiplexer part, the connection was used to set the conn-stream
endpoint and the mux's stream was the context. But it is a bit strange
because once a mux is installed, it takes over the connection. In a
wonderful world, the connection should be totally hidden behind the mux. The
stream-interface and, in a lesser extent, the stream, still access the
connection because that was inherited from the pre-multiplexer era.

Now, the conn-stream endpoint is the mux's stream (an opaque entity for the
conn-stream) and the connection is the context. Dedicated functions have
been added to attached an applet or a mux to a conn-stream.
diff --git a/src/backend.c b/src/backend.c
index 83c4d52..3e16653 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1495,7 +1495,6 @@
 			}
 
 			if (avail >= 1) {
-				cs_attach_endp(s->csb, &srv_conn->obj_type, srv_conn);
 				if (srv_conn->mux->attach(srv_conn, s->csb, s->sess) == -1) {
 					cs_detach_endp(s->csb);
 					srv_conn = NULL;
@@ -1571,7 +1570,7 @@
 			return SF_ERR_INTERNAL;  /* how did we get there ? */
 		}
 
-		cs_attach_endp(s->csb, &srv_conn->obj_type, srv_conn);
+		cs_attach_endp_mux(s->csb, NULL, srv_conn);
 #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
 		if (!srv ||
 		    (srv->use_ssl != 1 || (!(srv->ssl_ctx.alpn_str) && !(srv->ssl_ctx.npn_str)) ||
diff --git a/src/conn_stream.c b/src/conn_stream.c
index d2fd729..01541a5 100644
--- a/src/conn_stream.c
+++ b/src/conn_stream.c
@@ -43,33 +43,37 @@
 }
 
 
-/* Attaches a conn_stream to an endpoint and sets the endpoint ctx */
-void cs_attach_endp(struct conn_stream *cs, enum obj_type *endp, void *ctx)
+/* Attaches a conn_stream to an mux endpoint and sets the endpoint ctx */
+void cs_attach_endp_mux(struct conn_stream *cs, void *endp, void *ctx)
 {
-	struct connection *conn;
-	struct appctx *appctx;
+	struct connection *conn = ctx;
 
 	cs->end = endp;
 	cs->ctx = ctx;
-	if ((conn = objt_conn(endp)) != NULL) {
-		if (!conn->ctx)
-			conn->ctx = cs;
-		if (cs_strm(cs)) {
-			cs->si->ops = &si_conn_ops;
-			cs->data_cb = &si_conn_cb;
-		}
-		else if (cs_check(cs))
-			cs->data_cb = &check_conn_cb;
-		cs->flags |= CS_FL_ENDP_MUX;
+	if (!conn->ctx)
+		conn->ctx = cs;
+	if (cs_strm(cs)) {
+		cs->si->ops = &si_conn_ops;
+		cs->data_cb = &si_conn_cb;
 	}
-	else if ((appctx = objt_appctx(endp)) != NULL) {
-		appctx->owner = cs;
-		if (cs->si) {
-			cs->si->ops = &si_applet_ops;
-			cs->data_cb = NULL;
-		}
-		cs->flags |= CS_FL_ENDP_APP;
+	else if (cs_check(cs))
+		cs->data_cb = &check_conn_cb;
+	cs->flags |= CS_FL_ENDP_MUX;
+}
+
+/* Attaches a conn_stream to an applet endpoint and sets the endpoint ctx */
+void cs_attach_endp_app(struct conn_stream *cs, void *endp, void *ctx)
+{
+	struct appctx *appctx = endp;
+
+	cs->end = endp;
+	cs->ctx = ctx;
+	appctx->owner = cs;
+	if (cs->si) {
+		cs->si->ops = &si_applet_ops;
+		cs->data_cb = NULL;
 	}
+	cs->flags |= CS_FL_ENDP_APP;
 }
 
 /* Attaches a conn_stream to a app layer and sets the relevant callbacks */
diff --git a/src/dns.c b/src/dns.c
index cd7780c..b13206d 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -917,7 +917,7 @@
 	if (!sockaddr_alloc(&cs_si(s->csb)->dst, &ds->dss->srv->addr, sizeof(ds->dss->srv->addr)))
 		goto out_free_strm;
 
-	cs_attach_endp(cs, &appctx->obj_type, appctx);
+	cs_attach_endp_app(cs, appctx, appctx);
 	s->flags = SF_ASSIGNED|SF_ADDR_SET;
 	cs_si(s->csb)->flags |= SI_FL_NOLINGER;
 
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
index 36b1f9a..a3713cf 100644
--- a/src/flt_spoe.c
+++ b/src/flt_spoe.c
@@ -2031,7 +2031,7 @@
 	if ((strm = stream_new(sess, cs, &BUF_NULL)) == NULL)
 		goto out_free_sess;
 
-	cs_attach_endp(cs, &appctx->obj_type, appctx);
+	cs_attach_endp_app(cs, appctx, appctx);
 	stream_set_backend(strm, conf->agent->b.be);
 
 	/* applet is waiting for data */
diff --git a/src/h3.c b/src/h3.c
index 2d450d8..4906f29 100644
--- a/src/h3.c
+++ b/src/h3.c
@@ -636,7 +636,7 @@
 size_t h3_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
 {
 	size_t total = 0;
-	struct qcs *qcs = cs->ctx;
+	struct qcs *qcs = cs->end;
 	struct htx *htx;
 	enum htx_blk_type btype;
 	struct htx_blk *blk;
diff --git a/src/hlua.c b/src/hlua.c
index 270e3f6..179b8f2 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -2975,7 +2975,7 @@
 		goto out_fail_sess;
 	}
 
-	cs_attach_endp(cs, &appctx->obj_type, appctx);
+	cs_attach_endp_app(cs, appctx, appctx);
 
 	/* Initialise cross reference between stream and Lua socket object. */
 	xref_create(&socket->xref, &appctx->ctx.hlua_cosocket.xref);
diff --git a/src/hq_interop.c b/src/hq_interop.c
index 71419d1..68022c6 100644
--- a/src/hq_interop.c
+++ b/src/hq_interop.c
@@ -75,6 +75,7 @@
 	if (!cs)
 		return -1;
 
+
 	b_del(rxbuf, b_data(rxbuf));
 	b_free(&htx_buf);
 
@@ -95,7 +96,7 @@
 static size_t hq_interop_snd_buf(struct conn_stream *cs, struct buffer *buf,
                                  size_t count, int flags)
 {
-	struct qcs *qcs = cs->ctx;
+	struct qcs *qcs = cs->end;
 	struct htx *htx;
 	enum htx_blk_type btype;
 	struct htx_blk *blk;
diff --git a/src/http_client.c b/src/http_client.c
index cf1165b..22a13b1 100644
--- a/src/http_client.c
+++ b/src/http_client.c
@@ -529,7 +529,7 @@
 			break;
 	}
 
-	cs_attach_endp(cs, &appctx->obj_type, appctx);
+	cs_attach_endp_app(cs, appctx, appctx);
 	s->flags |= SF_ASSIGNED|SF_ADDR_SET;
 	cs_si(s->csb)->flags |= SI_FL_NOLINGER;
 	s->res.flags |= CF_READ_DONTWAIT;
diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c
index e3192da..3228f8b 100644
--- a/src/mux_fcgi.c
+++ b/src/mux_fcgi.c
@@ -1130,10 +1130,10 @@
 		TRACE_ERROR("fstream allocation failure", FCGI_EV_FSTRM_NEW|FCGI_EV_FSTRM_END|FCGI_EV_FSTRM_ERR, fconn->conn);
 		goto out;
 	}
-
+	cs_attach_endp_mux(cs, fstrm, fconn->conn);
 	fstrm->cs = cs;
 	fstrm->sess = sess;
-	cs->ctx = fstrm;
+	cs->end = fstrm;
 	fconn->nb_cs++;
 
 	TRACE_LEAVE(FCGI_EV_FSTRM_NEW, fconn->conn, fstrm);
@@ -3579,12 +3579,13 @@
  */
 static void fcgi_detach(struct conn_stream *cs)
 {
-	struct fcgi_strm *fstrm = cs->ctx;
+	struct fcgi_strm *fstrm = cs->end;
 	struct fcgi_conn *fconn;
 	struct session *sess;
 
 	TRACE_ENTER(FCGI_EV_STRM_END, (fstrm ? fstrm->fconn->conn : NULL), fstrm);
 
+	cs->end = NULL;
 	cs->ctx = NULL;
 	if (!fstrm) {
 		TRACE_LEAVE(FCGI_EV_STRM_END);
@@ -3853,7 +3854,7 @@
 /* shutr() called by the conn_stream (mux_ops.shutr) */
 static void fcgi_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
 {
-	struct fcgi_strm *fstrm = cs->ctx;
+	struct fcgi_strm *fstrm = cs->end;
 
 	TRACE_POINT(FCGI_EV_STRM_SHUT, fstrm->fconn->conn, fstrm);
 	if (cs->flags & CS_FL_KILL_CONN)
@@ -3868,7 +3869,7 @@
 /* shutw() called by the conn_stream (mux_ops.shutw) */
 static void fcgi_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
 {
-	struct fcgi_strm *fstrm = cs->ctx;
+	struct fcgi_strm *fstrm = cs->end;
 
 	TRACE_POINT(FCGI_EV_STRM_SHUT, fstrm->fconn->conn, fstrm);
 	if (cs->flags & CS_FL_KILL_CONN)
@@ -3884,7 +3885,7 @@
  */
 static int fcgi_subscribe(struct conn_stream *cs, int event_type, struct wait_event *es)
 {
-	struct fcgi_strm *fstrm = cs->ctx;
+	struct fcgi_strm *fstrm = cs->end;
 	struct fcgi_conn *fconn = fstrm->fconn;
 
 	BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV));
@@ -3910,7 +3911,7 @@
  */
 static int fcgi_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es)
 {
-	struct fcgi_strm *fstrm = cs->ctx;
+	struct fcgi_strm *fstrm = cs->end;
 	struct fcgi_conn *fconn = fstrm->fconn;
 
 	BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV));
@@ -3946,7 +3947,7 @@
  */
 static size_t fcgi_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
 {
-	struct fcgi_strm *fstrm = cs->ctx;
+	struct fcgi_strm *fstrm = cs->end;
 	struct fcgi_conn *fconn = fstrm->fconn;
 	size_t ret = 0;
 
@@ -3990,7 +3991,7 @@
  */
 static size_t fcgi_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
 {
-	struct fcgi_strm *fstrm = cs->ctx;
+	struct fcgi_strm *fstrm = cs->end;
 	struct fcgi_conn *fconn = fstrm->fconn;
 	size_t total = 0;
 	size_t ret;
diff --git a/src/mux_h1.c b/src/mux_h1.c
index 29dee6f..4baaf43 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -724,7 +724,7 @@
 		TRACE_ERROR("CS allocation failure", H1_EV_STRM_NEW|H1_EV_STRM_END|H1_EV_STRM_ERR, h1c->conn, h1s);
 		goto err;
 	}
-	cs_attach_endp(cs, &h1c->conn->obj_type, h1s);
+	cs_attach_endp_mux(cs, h1s, h1c->conn);
 	h1s->cs = cs;
 
 	if (h1s->flags & H1S_F_NOT_FIRST)
@@ -848,10 +848,10 @@
 	if (!h1s)
 		goto fail;
 
+	cs_attach_endp_mux(cs, h1s, h1c->conn);
 	h1s->flags |= H1S_F_RX_BLK;
 	h1s->cs = cs;
 	h1s->sess = sess;
-	cs->ctx = h1s;
 
 	h1c->flags = (h1c->flags & ~H1C_F_ST_EMBRYONIC) | H1C_F_ST_ATTACHED | H1C_F_ST_READY;
 
@@ -995,9 +995,8 @@
 
 		if (!h1c_frt_stream_new(h1c))
 			goto fail;
-
 		h1c->h1s->cs = cs;
-		cs->ctx = h1c->h1s;
+		cs_attach_endp_mux(cs, h1c->h1s, conn);
 
 		/* Attach the CS but Not ready yet */
 		h1c->flags = (h1c->flags & ~H1C_F_ST_EMBRYONIC) | H1C_F_ST_ATTACHED;
@@ -3338,13 +3337,14 @@
  */
 static void h1_detach(struct conn_stream *cs)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c;
 	struct session *sess;
 	int is_not_first;
 
 	TRACE_ENTER(H1_EV_STRM_END, h1s ? h1s->h1c->conn : NULL, h1s);
 
+	cs->end = NULL;
 	cs->ctx = NULL;
 	if (!h1s) {
 		TRACE_LEAVE(H1_EV_STRM_END);
@@ -3447,7 +3447,7 @@
 
 static void h1_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c;
 
 	if (!h1s)
@@ -3490,7 +3490,7 @@
 
 static void h1_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c;
 
 	if (!h1s)
@@ -3550,7 +3550,7 @@
  */
 static int h1_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 
 	if (!h1s)
 		return 0;
@@ -3579,7 +3579,7 @@
  */
 static int h1_subscribe(struct conn_stream *cs, int event_type, struct wait_event *es)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c;
 
 	if (!h1s)
@@ -3627,7 +3627,7 @@
  */
 static size_t h1_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c = h1s->h1c;
 	struct h1m *h1m = (!(h1c->flags & H1C_F_IS_BACK) ? &h1s->req : &h1s->res);
 	size_t ret = 0;
@@ -3663,7 +3663,7 @@
 /* Called from the upper layer, to send data */
 static size_t h1_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c;
 	size_t total = 0;
 
@@ -3728,7 +3728,7 @@
 /* Send and get, using splicing */
 static int h1_rcv_pipe(struct conn_stream *cs, struct pipe *pipe, unsigned int count)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c = h1s->h1c;
 	struct h1m *h1m = (!(h1c->flags & H1C_F_IS_BACK) ? &h1s->req : &h1s->res);
 	int ret = 0;
@@ -3798,7 +3798,7 @@
 
 static int h1_snd_pipe(struct conn_stream *cs, struct pipe *pipe)
 {
-	struct h1s *h1s = cs->ctx;
+	struct h1s *h1s = cs->end;
 	struct h1c *h1c = h1s->h1c;
 	struct h1m *h1m = (!(h1c->flags & H1C_F_IS_BACK) ? &h1s->res : &h1s->req);
 	int ret = 0;
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 9949bbc..d06b093 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -1606,7 +1606,7 @@
 	if (!cs)
 		goto out_close;
 	cs->flags |= CS_FL_NOT_FIRST;
-	cs_attach_endp(cs, &h2c->conn->obj_type, h2s);
+	cs_attach_endp_mux(cs, h2s, h2c->conn);
 	h2s->cs = cs;
 	h2c->nb_cs++;
 
@@ -1676,9 +1676,9 @@
 	if (!h2s)
 		goto out;
 
+	cs_attach_endp_mux(cs, h2s, h2c->conn);
 	h2s->cs = cs;
 	h2s->sess = sess;
-	cs->ctx = h2s;
 	h2c->nb_cs++;
 
  out:
@@ -4349,12 +4349,13 @@
  */
 static void h2_detach(struct conn_stream *cs)
 {
-	struct h2s *h2s = cs->ctx;
+	struct h2s *h2s = cs->end;
 	struct h2c *h2c;
 	struct session *sess;
 
 	TRACE_ENTER(H2_EV_STRM_END, h2s ? h2s->h2c->conn : NULL, h2s);
 
+	cs->end = NULL;
 	cs->ctx = NULL;
 	if (!h2s) {
 		TRACE_LEAVE(H2_EV_STRM_END);
@@ -4669,7 +4670,7 @@
 /* shutr() called by the conn_stream (mux_ops.shutr) */
 static void h2_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
 {
-	struct h2s *h2s = cs->ctx;
+	struct h2s *h2s = cs->end;
 
 	TRACE_ENTER(H2_EV_STRM_SHUT, h2s->h2c->conn, h2s);
 	if (cs->flags & CS_FL_KILL_CONN)
@@ -4684,7 +4685,7 @@
 /* shutw() called by the conn_stream (mux_ops.shutw) */
 static void h2_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
 {
-	struct h2s *h2s = cs->ctx;
+	struct h2s *h2s = cs->end;
 
 	TRACE_ENTER(H2_EV_STRM_SHUT, h2s->h2c->conn, h2s);
 	if (cs->flags & CS_FL_KILL_CONN)
@@ -6361,7 +6362,7 @@
  */
 static int h2_subscribe(struct conn_stream *cs, int event_type, struct wait_event *es)
 {
-	struct h2s *h2s = cs->ctx;
+	struct h2s *h2s = cs->end;
 	struct h2c *h2c = h2s->h2c;
 
 	TRACE_ENTER(H2_EV_STRM_SEND|H2_EV_STRM_RECV, h2c->conn, h2s);
@@ -6395,7 +6396,7 @@
  */
 static int h2_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es)
 {
-	struct h2s *h2s = cs->ctx;
+	struct h2s *h2s = cs->end;
 
 	TRACE_ENTER(H2_EV_STRM_SEND|H2_EV_STRM_RECV, h2s->h2c->conn, h2s);
 
@@ -6435,7 +6436,7 @@
  */
 static size_t h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
 {
-	struct h2s *h2s = cs->ctx;
+	struct h2s *h2s = cs->end;
 	struct h2c *h2c = h2s->h2c;
 	struct htx *h2s_htx = NULL;
 	struct htx *buf_htx = NULL;
@@ -6518,7 +6519,7 @@
  */
 static size_t h2_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
 {
-	struct h2s *h2s = cs->ctx;
+	struct h2s *h2s = cs->end;
 	size_t total = 0;
 	size_t ret;
 	struct htx *htx;
diff --git a/src/mux_pt.c b/src/mux_pt.c
index 2fcd139..f22c3a1 100644
--- a/src/mux_pt.c
+++ b/src/mux_pt.c
@@ -296,7 +296,7 @@
 			TRACE_ERROR("CS allocation failure", PT_EV_STRM_NEW|PT_EV_STRM_END|PT_EV_STRM_ERR, conn);
 			goto fail_free_ctx;
 		}
-		cs_attach_endp(cs, &conn->obj_type, NULL);
+		cs_attach_endp_mux(cs, ctx, conn);
 
 		if (!stream_new(conn->owner, cs, &BUF_NULL)) {
 			TRACE_ERROR("stream creation failure", PT_EV_STRM_NEW|PT_EV_STRM_END|PT_EV_STRM_ERR, conn, cs);
@@ -372,6 +372,7 @@
 	TRACE_ENTER(PT_EV_STRM_NEW, conn);
 	if (ctx->wait_event.events)
 		conn->xprt->unsubscribe(ctx->conn, conn->xprt_ctx, SUB_RETRY_RECV, &ctx->wait_event);
+	cs_attach_endp_mux(cs, ctx, conn);
 	ctx->cs = cs;
 	cs->flags |= CS_FL_RCV_MORE;
 
@@ -414,6 +415,9 @@
 
 	TRACE_ENTER(PT_EV_STRM_END, conn, cs);
 
+	cs->end = NULL;
+	cs->ctx = NULL;
+
 	/* Subscribe, to know if we got disconnected */
 	if (!conn_is_back(conn) && conn->owner != NULL &&
 	    !(conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH))) {
diff --git a/src/mux_quic.c b/src/mux_quic.c
index 275b92a..08848ca 100644
--- a/src/mux_quic.c
+++ b/src/mux_quic.c
@@ -1056,7 +1056,7 @@
 
 static void qc_detach(struct conn_stream *cs)
 {
-	struct qcs *qcs = cs->ctx;
+	struct qcs *qcs = cs->end;
 	struct qcc *qcc = qcs->qcc;
 
 	TRACE_ENTER(QMUX_EV_STRM_END, qcc->conn, qcs);
@@ -1092,7 +1092,7 @@
 static size_t qc_rcv_buf(struct conn_stream *cs, struct buffer *buf,
                          size_t count, int flags)
 {
-	struct qcs *qcs = cs->ctx;
+	struct qcs *qcs = cs->end;
 	struct htx *qcs_htx = NULL;
 	struct htx *cs_htx = NULL;
 	size_t ret = 0;
@@ -1160,7 +1160,7 @@
 static size_t qc_snd_buf(struct conn_stream *cs, struct buffer *buf,
                          size_t count, int flags)
 {
-	struct qcs *qcs = cs->ctx;
+	struct qcs *qcs = cs->end;
 	size_t ret;
 
 	TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
@@ -1180,7 +1180,7 @@
 static int qc_subscribe(struct conn_stream *cs, int event_type,
                         struct wait_event *es)
 {
-	return qcs_subscribe(cs->ctx, event_type, es);
+	return qcs_subscribe(cs->end, event_type, es);
 }
 
 /* Called from the upper layer, to unsubscribe <es> from events <event_type>.
@@ -1189,7 +1189,7 @@
  */
 static int qc_unsubscribe(struct conn_stream *cs, int event_type, struct wait_event *es)
 {
-	struct qcs *qcs = cs->ctx;
+	struct qcs *qcs = cs->end;
 
 	BUG_ON(event_type & ~(SUB_RETRY_SEND|SUB_RETRY_RECV));
 	BUG_ON(qcs->subs && qcs->subs != es);
diff --git a/src/peers.c b/src/peers.c
index e2bcee7..d82e562 100644
--- a/src/peers.c
+++ b/src/peers.c
@@ -3224,7 +3224,7 @@
 	if (!sockaddr_alloc(&(cs_si(s->csb)->dst), &peer->addr, sizeof(peer->addr)))
 		goto out_free_strm;
 
-	cs_attach_endp(cs, &appctx->obj_type, appctx);
+	cs_attach_endp_app(cs, appctx, appctx);
 	s->flags = SF_ASSIGNED|SF_ADDR_SET;
 	cs_si(s->csb)->flags |= SI_FL_NOLINGER;
 
diff --git a/src/sink.c b/src/sink.c
index 16d3533..87f076b 100644
--- a/src/sink.c
+++ b/src/sink.c
@@ -671,7 +671,7 @@
 	if (!sockaddr_alloc(&cs_si(s->csb)->dst, &sft->srv->addr, sizeof(sft->srv->addr)))
 		goto out_free_strm;
 
-	cs_attach_endp(cs, &appctx->obj_type, appctx);
+	cs_attach_endp_app(cs, appctx, appctx);
 	s->flags = SF_ASSIGNED|SF_ADDR_SET;
 	cs_si(s->csb)->flags |= SI_FL_NOLINGER;
 
diff --git a/src/stream.c b/src/stream.c
index 3aeba18..778b4ae 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -988,7 +988,7 @@
 		if (unlikely(!appctx))
 			return ACT_RET_ERR;
 
-		/* Initialise the context. */
+		/* Finish initialisation of the context. */
 		memset(&appctx->ctx, 0, sizeof(appctx->ctx));
 		appctx->rule = rule;
 		if (appctx->applet->init && !appctx->applet->init(appctx))
@@ -3275,7 +3275,7 @@
 			     strm->csb->si->err_type, strm->csb->si->wait_event.events);
 
 		cs = strm->csf;
-		chunk_appendf(&trash, "  cs=%p csf=0x%08x ctx=%p\n", cs, cs->flags, cs->ctx);
+		chunk_appendf(&trash, "  cs=%p csf=0x%08x endp=%p\n", cs, cs->flags, cs->end);
 
 		if ((conn = cs_conn(cs)) != NULL) {
 			chunk_appendf(&trash,
@@ -3311,7 +3311,7 @@
 		}
 
 		cs = strm->csb;
-		chunk_appendf(&trash, "  cs=%p csf=0x%08x ctx=%p\n", cs, cs->flags, cs->ctx);
+		chunk_appendf(&trash, "  cs=%p csf=0x%08x end=%p\n", cs, cs->flags, cs->end);
 		if ((conn = cs_conn(cs)) != NULL) {
 			chunk_appendf(&trash,
 			              "      co1=%p ctrl=%s xprt=%s mux=%s data=%s target=%s:%p\n",
diff --git a/src/stream_interface.c b/src/stream_interface.c
index f8f7794..9396c90 100644
--- a/src/stream_interface.c
+++ b/src/stream_interface.c
@@ -342,7 +342,7 @@
 	appctx = appctx_new(app, si->cs);
 	if (!appctx)
 		return NULL;
-	cs_attach_endp(si->cs, &appctx->obj_type, appctx);
+	cs_attach_endp_app(si->cs, appctx, appctx);
 	appctx->t->nice = si_strm(si)->task->nice;
 	si_cant_get(si);
 	appctx_wakeup(appctx);
diff --git a/src/tcpcheck.c b/src/tcpcheck.c
index 6e995a0..ee439da 100644
--- a/src/tcpcheck.c
+++ b/src/tcpcheck.c
@@ -1101,7 +1101,7 @@
 		TRACE_ERROR("conn-stream allocation error", CHK_EV_TCPCHK_CONN|CHK_EV_TCPCHK_ERR, check);
 		goto out;
 	}
-	cs_attach_endp(check->cs, &conn->obj_type, conn);
+	cs_attach_endp_mux(check->cs, NULL, conn);
 	tasklet_set_tid(check->wait_list.tasklet, tid);
 	conn_set_owner(conn, check->sess, NULL);