MINOR: config: make sure to associate the proper mux to bind and servers

Currently a mux may be forced on a bind or server line by specifying the
"proto" keyword. The problem is that the mux may depend on the proxy's
mode, which is not known when parsing this keyword, so a wrong mux could
be picked.

Let's simply update the mux entry while checking its validity. We do have
the name and the side, we only need to see if a better mux fits based on
the proxy's mode. It also requires to remove the side check while parsing
the "proto" keyword since a wrong mux could be picked.

This way it becomes possible to declare multiple muxes with the same
protocol names and different sides or modes.
This commit is contained in:
Willy Tarreau 2018-12-02 13:09:09 +01:00
parent 3fbea1d8d0
commit 76a551de2e
3 changed files with 24 additions and 12 deletions

View File

@ -3319,6 +3319,7 @@ int check_config_validity()
* attached to the current proxy */ * attached to the current proxy */
list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) { list_for_each_entry(bind_conf, &curproxy->conf.bind, by_fe) {
int mode = (1 << (curproxy->mode == PR_MODE_HTTP)); int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
const struct mux_proto_list *mux_ent;
/* Special case for HTX because it is still experimental */ /* Special case for HTX because it is still experimental */
if (curproxy->options2 & PR_O2_USE_HTX) if (curproxy->options2 & PR_O2_USE_HTX)
@ -3326,7 +3327,14 @@ int check_config_validity()
if (!bind_conf->mux_proto) if (!bind_conf->mux_proto)
continue; continue;
if (!(bind_conf->mux_proto->mode & mode)) {
/* it is possible that an incorrect mux was referenced
* due to the proxy's mode not being taken into account
* on first pass. Let's adjust it now.
*/
mux_ent = conn_get_best_mux_entry(bind_conf->mux_proto->token, PROTO_SIDE_FE, mode);
if (!mux_ent || !isteq(mux_ent->token, bind_conf->mux_proto->token)) {
ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n", ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for 'bind %s' at [%s:%d].\n",
proxy_type_str(curproxy), curproxy->id, proxy_type_str(curproxy), curproxy->id,
(int)bind_conf->mux_proto->token.len, (int)bind_conf->mux_proto->token.len,
@ -3334,9 +3342,13 @@ int check_config_validity()
bind_conf->arg, bind_conf->file, bind_conf->line); bind_conf->arg, bind_conf->file, bind_conf->line);
cfgerr++; cfgerr++;
} }
/* update the mux */
bind_conf->mux_proto = mux_ent;
} }
for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) { for (newsrv = curproxy->srv; newsrv; newsrv = newsrv->next) {
int mode = (1 << (curproxy->mode == PR_MODE_HTTP)); int mode = (1 << (curproxy->mode == PR_MODE_HTTP));
const struct mux_proto_list *mux_ent;
/* Special case for HTX because it is still experimental */ /* Special case for HTX because it is still experimental */
if (curproxy->options2 & PR_O2_USE_HTX) if (curproxy->options2 & PR_O2_USE_HTX)
@ -3344,7 +3356,14 @@ int check_config_validity()
if (!newsrv->mux_proto) if (!newsrv->mux_proto)
continue; continue;
if (!(newsrv->mux_proto->mode & mode)) {
/* it is possible that an incorrect mux was referenced
* due to the proxy's mode not being taken into account
* on first pass. Let's adjust it now.
*/
mux_ent = conn_get_best_mux_entry(newsrv->mux_proto->token, PROTO_SIDE_BE, mode);
if (!mux_ent || !isteq(mux_ent->token, newsrv->mux_proto->token)) {
ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n", ha_alert("config : %s '%s' : MUX protocol '%.*s' is not usable for server '%s' at [%s:%d].\n",
proxy_type_str(curproxy), curproxy->id, proxy_type_str(curproxy), curproxy->id,
(int)newsrv->mux_proto->token.len, (int)newsrv->mux_proto->token.len,
@ -3352,6 +3371,9 @@ int check_config_validity()
newsrv->id, newsrv->conf.file, newsrv->conf.line); newsrv->id, newsrv->conf.file, newsrv->conf.line);
cfgerr++; cfgerr++;
} }
/* update the mux */
newsrv->mux_proto = mux_ent;
} }
} }

View File

@ -999,11 +999,6 @@ static int bind_parse_proto(char **args, int cur_arg, struct proxy *px, struct b
memprintf(err, "'%s' : unknown MUX protocol '%s'", args[cur_arg], args[cur_arg+1]); memprintf(err, "'%s' : unknown MUX protocol '%s'", args[cur_arg], args[cur_arg+1]);
return ERR_ALERT | ERR_FATAL; 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; return 0;
} }

View File

@ -520,11 +520,6 @@ static int srv_parse_proto(char **args, int *cur_arg,
memprintf(err, "'%s' : unknown MUX protocol '%s'", args[*cur_arg], args[*cur_arg+1]); memprintf(err, "'%s' : unknown MUX protocol '%s'", args[*cur_arg], args[*cur_arg+1]);
return ERR_ALERT | ERR_FATAL; 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; return 0;
} }