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 */ }, }};