BUG/MINOR: peers: Incomplete peers sections should be validated.

Before supporting "server" line in "peers" section, such sections without
any local peer were removed from the configuration to get it validated.

This patch fixes the issue where a "server" line without address and port which
is a remote peer without address and port makes the configuration parsing fail.
When encoutering such cases we now ignore such lines remove them from the
configuration.

Thank you to Jrme Magnin for having reported this bug.

Must be backported to 2.1 and 2.0.
This commit is contained in:
Frdric Lcaille 2020-04-03 09:43:47 +02:00 committed by Willy Tarreau
parent 02c88036a6
commit 8ba10fea69
4 changed files with 26 additions and 11 deletions

View File

@ -46,7 +46,7 @@ extern struct mt_list toremove_connections[MAX_THREADS];
int srv_downtime(const struct server *s);
int srv_lastsession(const struct server *s);
int srv_getinter(const struct check *check);
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy, int parse_addr);
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy, int parse_addr, int in_peers_section);
int update_server_addr(struct server *s, void *ip, int ip_sin_family, const char *updater);
const char *update_server_addr_port(struct server *s, const char *addr, const char *port, char *updater);
struct server *server_find_by_id(struct proxy *bk, int id);

View File

@ -540,7 +540,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
if (!strcmp(args[0], "server") ||
!strcmp(args[0], "default-server") ||
!strcmp(args[0], "server-template")) {
err_code |= parse_server(file, linenum, args, curproxy, &defproxy, 1);
err_code |= parse_server(file, linenum, args, curproxy, &defproxy, 1, 0);
if (err_code & ERR_FATAL)
goto out;
}

View File

@ -712,7 +712,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, 0);
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, 0, 1);
}
else if (strcmp(args[0], "log") == 0) {
if (init_peers_frontend(file, linenum, NULL, curpeers) != 0) {
@ -821,9 +821,19 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
* The server address is parsed only if we are parsing a "peer" line,
* or if we are parsing a "server" line and the current peer is not the local one.
*/
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, peer || !local_peer);
if (!curpeers->peers_fe->srv)
err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, peer || !local_peer, 1);
if (!curpeers->peers_fe->srv) {
/* Remove the newly allocated peer. */
if (newpeer != curpeers->local) {
struct peer *p;
p = curpeers->remote;
curpeers->remote = curpeers->remote->next;
free(p->id);
free(p);
}
goto out;
}
/* If the peer address has just been parsed, let's copy it to <newpeer>
* and initializes ->proto.

View File

@ -2156,7 +2156,7 @@ static int server_template_init(struct server *srv, struct proxy *px)
return i - srv->tmpl_info.nb_low;
}
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy, int parse_addr)
int parse_server(const char *file, int linenum, char **args, struct proxy *curproxy, struct proxy *defproxy, int parse_addr, int in_peers_section)
{
struct server *newsrv = NULL;
const char *err = NULL;
@ -2186,11 +2186,16 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr
/* There is no mandatory first arguments for default server. */
if (srv && parse_addr) {
if (!*args[2]) {
/* 'server' line number of argument check. */
ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
if (in_peers_section) {
return 0;
}
else {
/* 'server' line number of argument check. */
ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
}
err = invalid_char(args[1]);