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; }