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.
This commit is contained in:
Christopher Faulet 2018-04-10 14:43:00 +02:00
parent 9c9ef03bf4
commit a717b99284
4 changed files with 54 additions and 0 deletions

View File

@ -10995,6 +10995,16 @@ process <process-set>[/<thread-set>]
smoother inter-process load balancing. Currently Linux 3.9 and above is known
for supporting this. See also "bind-process" and "nbproc".
proto <name>
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

View File

@ -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 */

View File

@ -8768,6 +8768,23 @@ int check_config_validity()
}
}
}
/* 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++;
}
}
}
/***********************************************************/

View File

@ -30,6 +30,7 @@
#include <types/protocol.h>
#include <proto/acl.h>
#include <proto/connection.h>
#include <proto/fd.h>
#include <proto/freq_ctr.h>
#include <proto/log.h>
@ -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 <const> 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 */ },
}};