From a717b99284d00abe65730394e3ed2d7c37e0eb1a Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 10 Apr 2018 14:43:00 +0200 Subject: [PATCH] MINOR: mux/frontend: Add 'proto' keyword to force the mux protocol For now, it is parsed but not used. Tests are done on it to check if the side and the mode are compatible with the proxy's definition. --- doc/configuration.txt | 10 ++++++++++ include/types/listener.h | 1 + src/cfgparse.c | 17 +++++++++++++++++ src/listener.c | 26 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index ff2771f27..181e5230a 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -10995,6 +10995,16 @@ process [/] smoother inter-process load balancing. Currently Linux 3.9 and above is known for supporting this. See also "bind-process" and "nbproc". +proto + Forces the multiplexer's protocol to use for the incoming connections. It + must be compatible with the mode of the frontend (TCP or HTTP). It must also + be usable on the frontend side. The list of available protocols is reported + in haproxy -vv. + Idea behind this optipon is to bypass the selection of the best multiplexer's + protocol for all connections instantiated from this listening socket. For + instance, it is possible to force the http/2 on clear TCP by specifing "proto + h2" on the bind line. + ssl This setting is only available when support for OpenSSL was built in. It enables SSL deciphering on connections instantiated from this listener. A diff --git a/include/types/listener.h b/include/types/listener.h index c55569cd3..09b11044a 100644 --- a/include/types/listener.h +++ b/include/types/listener.h @@ -156,6 +156,7 @@ struct bind_conf { EVP_PKEY *ca_sign_pkey; /* CA private key referenced by ca_key */ #endif struct proxy *frontend; /* the frontend all these listeners belong to, or NULL */ + struct mux_proto_list *mux_proto; /* the mux to use for all incoming connections (specified by the "proto" keyword) */ struct xprt_ops *xprt; /* transport-layer operations for all listeners */ int is_ssl; /* SSL is required for these listeners */ int generate_certs; /* 1 if generate-certificates option is set, else 0 */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 1451243ad..16f70d631 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -8768,6 +8768,23 @@ out_uri_auth_compat: } } } + + /* Check the mux protocols, if any, for each listener + * attached to the current proxy */ + list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) { + int mode = (1 << (curproxy->mode == PR_MODE_HTTP)); + + if (!bind_conf->mux_proto) + continue; + if (!(bind_conf->mux_proto->mode & mode)) { + ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n", + proxy_type_str(curproxy), curproxy->id, + (int)bind_conf->mux_proto->token.len, + bind_conf->mux_proto->token.ptr, + bind_conf->arg, bind_conf->file, bind_conf->line); + cfgerr++; + } + } } /***********************************************************/ diff --git a/src/listener.c b/src/listener.c index 20244056f..a30d4fb4f 100644 --- a/src/listener.c +++ b/src/listener.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -964,6 +965,30 @@ static int bind_parse_process(char **args, int cur_arg, struct proxy *px, struct return 0; } +/* parse the "proto" bind keyword */ +static int bind_parse_proto(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) +{ + struct ist proto; + + if (!*args[cur_arg + 1]) { + memprintf(err, "'%s' : missing value", args[cur_arg]); + return ERR_ALERT | ERR_FATAL; + } + + proto = ist2(args[cur_arg + 1], strlen(args[cur_arg + 1])); + conf->mux_proto = get_mux_proto(proto); + if (!conf->mux_proto) { + memprintf(err, "'%s' : unknown MUX protocol '%s'", args[cur_arg], args[cur_arg+1]); + return ERR_ALERT | ERR_FATAL; + } + else if (!(conf->mux_proto->side & PROTO_SIDE_FE)) { + memprintf(err, "'%s' : MUX protocol '%s' cannot be used for incoming connections", + args[cur_arg], args[cur_arg+1]); + return ERR_ALERT | ERR_FATAL; + } + return 0; +} + /* Note: must not be declared as its list will be overwritten. * Please take care of keeping this list alphabetically sorted. */ @@ -996,6 +1021,7 @@ static struct bind_kw_list bind_kws = { "ALL", { }, { { "name", bind_parse_name, 1 }, /* set name of listening socket */ { "nice", bind_parse_nice, 1 }, /* set nice of listening socket */ { "process", bind_parse_process, 1 }, /* set list of allowed process for this socket */ + { "proto", bind_parse_proto, 1 }, /* set the proto to use for all incoming connections */ { /* END */ }, }};