MEDIUM: connection: start to introduce a mux layer between xprt and data

For HTTP/2 and QUIC, we'll need to deal with multiplexed streams inside
a connection. After quite a long brainstorming, it appears that the
connection interface to the existing streams is appropriate just like
the connection interface to the lower layers. In fact we need to have
the mux layer in the middle of the connection, between the transport
and the data layer.

A mux can exist on two directions/sides. On the inbound direction, it
instanciates new streams from incoming connections, while on the outbound
direction it muxes streams into outgoing connections. The difference is
visible on the mux->init() call : in one case, an upper context is already
known (outgoing connection), and in the other case, the upper context is
not yet known (incoming connection) and will have to be allocated by the
mux. The session doesn't have to create the new streams anymore, as this
is performed by the mux itself.

This patch introduces this and creates a pass-through mux called
"mux_pt" which is used for all new connections and which only
calls the data layer's recv,send,wake() calls. One incoming stream
is immediately created when init() is called on the inbound direction.
There should not be any visible impact.

Note that the connection's mux is purposely not set until the session
is completed so that we don't accidently run with the wrong mux. This
must not cause any issue as the xprt_done_cb function is always called
prior to using mux's recv/send functions.
diff --git a/include/proto/connection.h b/include/proto/connection.h
index ecba6dd..72f793a 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -474,14 +474,17 @@
 }
 
 /* prepares a connection to work with protocol <proto> and transport <xprt>.
- * The transport's context is initialized as well.
+ * The transport's is initialized as well, and the mux and its context are
+ * cleared.
  */
 static inline void conn_prepare(struct connection *conn, const struct protocol *proto, const struct xprt_ops *xprt)
 {
 	conn->ctrl = proto;
 	conn->xprt = xprt;
+	conn->mux  = NULL;
 	conn->xprt_st = 0;
 	conn->xprt_ctx = NULL;
+	conn->mux_ctx = NULL;
 }
 
 /* Initializes all required fields for a new connection. Note that it does the
@@ -495,6 +498,8 @@
 	conn->flags = CO_FL_NONE;
 	conn->data = NULL;
 	conn->tmp_early_data = -1;
+	conn->mux = NULL;
+	conn->mux_ctx = NULL;
 	conn->owner = NULL;
 	conn->send_proxy_ofs = 0;
 	conn->handle.fd = DEAD_FD_MAGIC;
@@ -540,6 +545,8 @@
 /* Releases a connection previously allocated by conn_new() */
 static inline void conn_free(struct connection *conn)
 {
+	if (conn->mux && conn->mux->release)
+		conn->mux->release(conn);
 	pool_free2(pool2_connection, conn);
 }
 
@@ -583,6 +590,16 @@
 	conn->owner = owner;
 }
 
+/* Installs the connection's mux layer for upper context <ctx>.
+ * Returns < 0 on error.
+ */
+static inline int conn_install_mux(struct connection *conn, const struct mux_ops *mux, void *ctx)
+{
+	conn->mux = mux;
+	conn->mux_ctx = ctx;
+	return mux->init ? mux->init(conn) : 0;
+}
+
 /* returns a human-readable error code for conn->err_code, or NULL if the code
  * is unknown.
  */
@@ -648,6 +665,13 @@
 	return conn->xprt->name;
 }
 
+static inline const char *conn_get_mux_name(const struct connection *conn)
+{
+	if (!conn->mux)
+		return "NONE";
+	return conn->mux->name;
+}
+
 static inline const char *conn_get_data_name(const struct connection *conn)
 {
 	if (!conn->data)
diff --git a/include/proto/mux_pt.h b/include/proto/mux_pt.h
new file mode 100644
index 0000000..33c4e32
--- /dev/null
+++ b/include/proto/mux_pt.h
@@ -0,0 +1,37 @@
+/*
+ * include/proto/mux_pt.h
+ * This file contains the pass-though mux function prototypes
+ *
+ * Copyright (C) 2017 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _PROTO_MUX_PT_H
+#define _PROTO_MUX_PT_H
+
+#include <common/config.h>
+#include <types/connection.h>
+
+extern const struct mux_ops mux_pt_ops;
+
+#endif /* _PROTO_MUX_PT_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */