MINOR: h2: create a very minimalistic h2 mux

This one currently does nothing and rejects every connection. It
registers ALPN token "h2".
diff --git a/src/mux_h2.c b/src/mux_h2.c
new file mode 100644
index 0000000..a15e4c7
--- /dev/null
+++ b/src/mux_h2.c
@@ -0,0 +1,166 @@
+/*
+ * HTTP/2 mux-demux for connections
+ *
+ * Copyright 2017 Willy Tarreau <w@1wt.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <common/cfgparse.h>
+#include <common/config.h>
+#include <proto/connection.h>
+#include <proto/stream.h>
+
+
+/*****************************************************************/
+/* functions below are dedicated to the mux setup and management */
+/*****************************************************************/
+
+/* Initialize the mux once it's attached. For outgoing connections, the context
+ * is already initialized before installing the mux, so we detect incoming
+ * connections from the fact that the context is still NULL. Returns < 0 on
+ * error.
+ */
+static int h2_init(struct connection *conn)
+{
+	if (conn->mux_ctx) {
+		/* we don't support outgoing connections for now */
+		return -1;
+	}
+
+	/* not implemented yet */
+	return -1;
+}
+
+/* release function for a connection. This one should be called to free all
+ * resources allocated to the mux.
+ */
+static void h2_release(struct connection *conn)
+{
+}
+
+
+/*********************************************************/
+/* functions below are I/O callbacks from the connection */
+/*********************************************************/
+
+/* callback called on recv event by the connection handler */
+static void h2_recv(struct connection *conn)
+{
+}
+
+/* callback called on send event by the connection handler */
+static void h2_send(struct connection *conn)
+{
+}
+
+/* callback called on any event by the connection handler.
+ * It applies changes and returns zero, or < 0 if it wants immediate
+ * destruction of the connection (which normally doesn not happen in h2).
+ */
+static int h2_wake(struct connection *conn)
+{
+	return 0;
+}
+
+/*******************************************/
+/* functions below are used by the streams */
+/*******************************************/
+
+/*
+ * Attach a new stream to a connection
+ * (Used for outgoing connections)
+ */
+static struct conn_stream *h2_attach(struct connection *conn)
+{
+	return NULL;
+}
+
+/* callback used to update the mux's polling flags after changing a cs' status.
+ * The caller (cs_update_mux_polling) will take care of propagating any changes
+ * to the transport layer.
+ */
+static void h2_update_poll(struct conn_stream *cs)
+{
+}
+
+/*
+ * Detach the stream from the connection and possibly release the connection.
+ */
+static void h2_detach(struct conn_stream *cs)
+{
+}
+
+static void h2_shutr(struct conn_stream *cs, enum cs_shr_mode mode)
+{
+}
+
+static void h2_shutw(struct conn_stream *cs, enum cs_shw_mode mode)
+{
+}
+
+/*
+ * Called from the upper layer, to get more data
+ */
+static int h2_rcv_buf(struct conn_stream *cs, struct buffer *buf, int count)
+{
+	/* FIXME: not handled for now */
+	cs->flags |= CS_FL_ERROR;
+	return 0;
+}
+
+/* Called from the upper layer, to send data */
+static int h2_snd_buf(struct conn_stream *cs, struct buffer *buf, int flags)
+{
+	/* FIXME: not handled for now */
+	cs->flags |= CS_FL_ERROR;
+	return 0;
+}
+
+
+/*******************************************************/
+/* functions below are dedicated to the config parsers */
+/*******************************************************/
+
+
+
+/****************************************/
+/* MUX initialization and instanciation */
+/***************************************/
+
+/* The mux operations */
+const struct mux_ops h2_ops = {
+	.init = h2_init,
+	.recv = h2_recv,
+	.send = h2_send,
+	.wake = h2_wake,
+	.update_poll = h2_update_poll,
+	.rcv_buf = h2_rcv_buf,
+	.snd_buf = h2_snd_buf,
+	.attach = h2_attach,
+	.detach = h2_detach,
+	.shutr = h2_shutr,
+	.shutw = h2_shutw,
+	.release = h2_release,
+	.name = "H2",
+};
+
+/* ALPN selection : this mux registers ALPN tolen "h2" */
+static struct alpn_mux_list alpn_mux_h2 =
+	{ .token = IST("h2"), .mode = ALPN_MODE_HTTP, .mux = &h2_ops };
+
+/* config keyword parsers */
+static struct cfg_kw_list cfg_kws = {ILH, {
+	{ 0, NULL, NULL }
+}};
+
+__attribute__((constructor))
+static void __h2_init(void)
+{
+	alpn_register_mux(&alpn_mux_h2);
+	cfg_register_keywords(&cfg_kws);
+}