MINOR: muxes: Pass the context of the mux to destroy() instead of the connection

It is mandatory to handle mux upgrades, because during a mux upgrade, the
connection will be reassigned to another multiplexer. So when the old one is
destroyed, it does not own the connection anymore. Or in other words, conn->ctx
does not point to the old mux's context when its destroy() callback is
called. So we now rely on the multiplexer context do destroy it instead of the
connection.

In addition, h1_release() and h2_release() have also been updated in the same
way.
diff --git a/include/proto/session.h b/include/proto/session.h
index f1e33fa..2ff8e38 100644
--- a/include/proto/session.h
+++ b/include/proto/session.h
@@ -126,7 +126,7 @@
 		conn->owner = NULL;
 		if (!srv_add_to_idle_list(objt_server(conn->target), conn)) {
 			/* The server doesn't want it, let's kill the connection right away */
-			conn->mux->destroy(conn);
+			conn->mux->destroy(conn->ctx);
 			return -1;
 		} else
 			conn->flags &= ~CO_FL_SESS_IDLE;
diff --git a/include/types/connection.h b/include/types/connection.h
index af27d0c..ab1f8be 100644
--- a/include/types/connection.h
+++ b/include/types/connection.h
@@ -346,7 +346,7 @@
 	int (*unsubscribe)(struct conn_stream *cs, int event_type, void *param); /* Unsubscribe to events */
 	int (*avail_streams)(struct connection *conn); /* Returns the number of streams still available for a connection */
 	int (*used_streams)(struct connection *conn);  /* Returns the number of streams in use on a connection. */
-	void (*destroy)(struct connection *conn); /* Let the mux know one of its users left, so it may have to disappear */
+	void (*destroy)(void *ctx); /* Let the mux know one of its users left, so it may have to disappear */
 	void (*reset)(struct connection *conn); /* Reset the mux, because we're re-trying to connect */
 	const struct cs_info *(*get_cs_info)(struct conn_stream *cs); /* Return info on the specified conn_stream or NULL if not defined */
 	unsigned int flags;                           /* some flags characterizing the mux's capabilities (MX_FL_*) */
diff --git a/src/backend.c b/src/backend.c
index 5e82bf4..abe7308 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1371,7 +1371,7 @@
 				old_conn->owner = sess;
 				if (!session_add_conn(sess, old_conn, old_conn->target)) {
 					old_conn->owner = NULL;
-					old_conn->mux->destroy(old_conn);
+					old_conn->mux->destroy(old_conn->ctx);
 				} else
 					session_check_idle_conn(sess, old_conn);
 			}
@@ -1427,7 +1427,7 @@
 			srv_conn->owner = NULL;
 			if (srv_conn->mux && !srv_add_to_idle_list(objt_server(srv_conn->target), srv_conn))
 			/* The server doesn't want it, let's kill the connection right away */
-				srv_conn->mux->destroy(srv_conn);
+				srv_conn->mux->destroy(srv_conn->ctx);
 			srv_conn = NULL;
 
 		}
diff --git a/src/mux_h1.c b/src/mux_h1.c
index 50afbc2..43b062b 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -438,13 +438,12 @@
 	return -1;
 }
 
-
-/* release function for a connection. This one should be called to free all
- * resources allocated to the mux.
+/* release function. This one should be called to free all resources allocated
+ * to the mux.
  */
-static void h1_release(struct connection *conn)
+static void h1_release(struct h1c *h1c)
 {
-	struct h1c *h1c = conn->ctx;
+	struct connection *conn = h1c->conn;
 
 	if (h1c) {
 		if (!LIST_ISEMPTY(&h1c->buf_wait.list)) {
@@ -1867,7 +1866,7 @@
 	return 0;
 
   release:
-	h1_release(conn);
+	h1_release(h1c);
 	return -1;
 }
 
@@ -1936,13 +1935,14 @@
 	if (h1c->h1s && h1c->h1s->cs)
 		h1c->flags |= H1C_F_CS_ERROR;
 	else
-		h1_release(h1c->conn);
+		h1_release(h1c);
 	return NULL;
 }
 
 /*******************************************/
 /* functions below are used by the streams */
 /*******************************************/
+
 /*
  * Attach a new stream to a connection
  * (Used for outgoing connections)
@@ -1984,12 +1984,12 @@
 	return NULL;
 }
 
-static void h1_destroy(struct connection *conn)
+static void h1_destroy(void *ctx)
 {
-	struct h1c *h1c = conn->ctx;
+	struct h1c *h1c = ctx;
 
 	if (!h1c->h1s)
-		h1_release(conn);
+		h1_release(h1c);
 }
 
 /*
@@ -2065,7 +2065,7 @@
 	/* We don't want to close right now unless the connection is in error */
 	if ((h1c->flags & (H1C_F_CS_ERROR|H1C_F_CS_SHUTDOWN)) ||
 	    (h1c->conn->flags & CO_FL_ERROR) || !h1c->conn->owner)
-		h1_release(h1c->conn);
+		h1_release(h1c);
 	else {
 		tasklet_wakeup(h1c->wait_event.task);
 		if (h1c->task) {
diff --git a/src/mux_h2.c b/src/mux_h2.c
index e440424..32e1fc1 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -614,12 +614,12 @@
 	return container_of(node, struct h2s, by_id);
 }
 
-/* release function for a connection. This one should be called to free all
- * resources allocated to the mux.
+/* release function. This one should be called to free all resources allocated
+ * to the mux.
  */
-static void h2_release(struct connection *conn)
+static void h2_release(struct h2c *h2c)
 {
-	struct h2c *h2c = conn->ctx;
+	struct connection *conn = h2c->conn;
 
 	if (h2c) {
 		hpack_dht_free(h2c->ddht);
@@ -2845,7 +2845,7 @@
 
 		if (eb_is_empty(&h2c->streams_by_id)) {
 			/* no more stream, kill the connection now */
-			h2_release(conn);
+			h2_release(h2c);
 			return -1;
 		}
 	}
@@ -2930,7 +2930,7 @@
 	 * the last stream closes.
 	 */
 	if (eb_is_empty(&h2c->streams_by_id))
-		h2_release(h2c->conn);
+		h2_release(h2c);
 
 	return NULL;
 }
@@ -2985,12 +2985,12 @@
 /*
  * Destroy the mux and the associated connection, if it is no longer used
  */
-static void h2_destroy(struct connection *conn)
+static void h2_destroy(void *ctx)
 {
-	struct h2c *h2c = conn->ctx;
+	struct h2c *h2c = ctx;
 
 	if (eb_is_empty(&h2c->streams_by_id))
-		h2_release(h2c->conn);
+		h2_release(h2c);
 }
 
 /*
@@ -3082,7 +3082,7 @@
 	 */
 	if (h2c_is_dead(h2c)) {
 		/* no more stream will come, kill it now */
-		h2_release(h2c->conn);
+		h2_release(h2c);
 	}
 	else if (h2c->task) {
 		if (eb_is_empty(&h2c->streams_by_id) || b_data(&h2c->mbuf)) {
@@ -3248,7 +3248,7 @@
 		h2s_destroy(h2s);
 
 		if (h2c_is_dead(h2c))
-			h2_release(h2c->conn);
+			h2_release(h2c);
 	}
 
 	return NULL;
diff --git a/src/mux_pt.c b/src/mux_pt.c
index 2086d5f..6fb9f2f 100644
--- a/src/mux_pt.c
+++ b/src/mux_pt.c
@@ -166,13 +166,14 @@
 	return cs;
 }
 
-/* Destroy the mux and the associated connection, if no longer used */
-static void mux_pt_destroy_meth(struct connection *conn)
+/* Destroy the mux and the associated connection if still attached to this mux
+ * and no longer used */
+static void mux_pt_destroy_meth(void *ctx)
 {
-	struct mux_pt_ctx *ctx = conn->ctx;
+	struct mux_pt_ctx *pt = ctx;
 
-	if (!(ctx->cs))
-		mux_pt_destroy(ctx);
+	if (!(pt->cs))
+		mux_pt_destroy(pt);
 }
 
 /*
diff --git a/src/server.c b/src/server.c
index bffc2ee..25a9189 100644
--- a/src/server.c
+++ b/src/server.c
@@ -5317,7 +5317,7 @@
 
 	while ((conn = LIST_POP_LOCKED(&toremove_connections[tid],
 	                               struct connection *, list)) != NULL) {
-		conn->mux->destroy(conn);
+		conn->mux->destroy(conn->ctx);
 	}
 
 	return task;
diff --git a/src/session.c b/src/session.c
index ab49fb6..9b0db46 100644
--- a/src/session.c
+++ b/src/session.c
@@ -74,7 +74,7 @@
 	vars_prune_per_sess(&sess->vars);
 	conn = objt_conn(sess->origin);
 	if (conn != NULL && conn->mux)
-		conn->mux->destroy(conn);
+		conn->mux->destroy(conn->ctx);
 	list_for_each_entry_safe(srv_list, srv_list_back, &sess->srv_list, srv_list) {
 		list_for_each_entry_safe(conn, conn_back, &srv_list->conn_list, session_list) {
 			if (conn->mux) {
@@ -84,7 +84,7 @@
 				conn->owner = NULL;
 				conn->flags &= ~CO_FL_SESS_IDLE;
 				if (!srv_add_to_idle_list(objt_server(conn->target), conn))
-					conn->mux->destroy(conn);
+					conn->mux->destroy(conn->ctx);
 			} else {
 				/* We have a connection, but not yet an associated mux.
 				 * So destroy it now.