From 8ed0a3e32a90af08a23ca8ab79d52d5d30666780 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 10 Apr 2018 14:45:45 +0200 Subject: [PATCH] MINOR: mux/server: Add 'proto' keyword to force the multiplexer's 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 server's definition. --- doc/configuration.txt | 9 +++++++++ include/types/server.h | 1 + src/cfgparse.c | 16 +++++++++++++++- src/server.c | 27 +++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 181e5230a..295e27c40 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -11669,6 +11669,15 @@ port inetd for instance. This parameter is ignored if the "check" parameter is not set. See also the "addr" parameter. +proto + + Forces the multiplexer's protocol to use for the outgoing connections to this + server. It must be compatible with the mode of the backend (TCP or HTTP). It + must also be usable on the backend 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 established to this server. + redir The "redir" parameter enables the redirection mode for all GET and HEAD requests addressing this server. This means that instead of having HAProxy diff --git a/include/types/server.h b/include/types/server.h index c30003bdb..7c6d2257b 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -205,6 +205,7 @@ struct server { char *rdr_pfx; /* the redirection prefix */ struct proxy *proxy; /* the proxy this server belongs to */ + struct mux_proto_list *mux_proto; /* the mux to use for all outgoing connections (specified by the "proto" keyword) */ int served; /* # of active sessions currently being served (ie not pending) */ int cur_sess; /* number of currently active sessions (including syn_sent) */ unsigned maxconn, minconn; /* max # of active sessions (0 = unlimited), min# for dynamic limit. */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 16f70d631..2ac7b9659 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -8769,7 +8769,7 @@ out_uri_auth_compat: } } - /* Check the mux protocols, if any, for each listener + /* Check the mux protocols, if any, for each listener and server * attached to the current proxy */ list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) { int mode = (1 << (curproxy->mode == PR_MODE_HTTP)); @@ -8785,6 +8785,20 @@ out_uri_auth_compat: cfgerr++; } } + for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) { + int mode = (1 << (curproxy->mode == PR_MODE_HTTP)); + + if (!newsrv->mux_proto) + continue; + if (!(newsrv->mux_proto->mode & mode)) { + ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n", + proxy_type_str(curproxy), curproxy->id, + (int)newsrv->mux_proto->token.len, + newsrv->mux_proto->token.ptr, + newsrv->id, newsrv->conf.file, newsrv->conf.line); + cfgerr++; + } + } } /***********************************************************/ diff --git a/src/server.c b/src/server.c index c5e894537..c885debca 100644 --- a/src/server.c +++ b/src/server.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -499,6 +500,29 @@ static int inline srv_enable_pp_flags(struct server *srv, unsigned int flags) srv->pp_opts |= flags; return 0; } +/* parse the "proto" server keyword */ +static int srv_parse_proto(char **args, int *cur_arg, + struct proxy *px, struct server *newsrv, 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])); + newsrv->mux_proto = get_mux_proto(proto); + if (!newsrv->mux_proto) { + memprintf(err, "'%s' : unknown MUX protocol '%s'", args[*cur_arg], args[*cur_arg+1]); + return ERR_ALERT | ERR_FATAL; + } + else if (!(newsrv->mux_proto->side & PROTO_SIDE_BE)) { + memprintf(err, "'%s' : MUX protocol '%s' cannot be used for outgoing connections", + args[*cur_arg], args[*cur_arg+1]); + return ERR_ALERT | ERR_FATAL; + } + return 0; +} /* parse the "proxy-v2-options" */ static int srv_parse_proxy_v2_options(char **args, int *cur_arg, @@ -1179,6 +1203,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, { { "no-send-proxy-v2", srv_parse_no_send_proxy_v2, 0, 1 }, /* Disable use of PROXY V2 protocol */ { "non-stick", srv_parse_non_stick, 0, 1 }, /* Disable stick-table persistence */ { "observe", srv_parse_observe, 1, 1 }, /* Enables health adjusting based on observing communication with the server */ + { "proto", srv_parse_proto, 1, 1 }, /* Set the proto to use for all outgoing connections */ { "proxy-v2-options", srv_parse_proxy_v2_options, 1, 1 }, /* options for send-proxy-v2 */ { "redir", srv_parse_redir, 1, 1 }, /* Enable redirection mode */ { "send-proxy", srv_parse_send_proxy, 0, 1 }, /* Enforce use of PROXY V1 protocol */ @@ -1584,6 +1609,8 @@ static void srv_settings_cpy(struct server *srv, struct server *src, int srv_tmp #ifdef TCP_USER_TIMEOUT srv->tcp_ut = src->tcp_ut; #endif + srv->mux_proto = src->mux_proto; + if (srv_tmpl) srv->srvrq = src->srvrq; }