From 8ba10fea69aff458ee0be9c32a432dcc319f8f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Fri, 3 Apr 2020 09:43:47 +0200 Subject: [PATCH] BUG/MINOR: peers: Incomplete peers sections should be validated. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Jérôme Magnin for having reported this bug. Must be backported to 2.1 and 2.0. --- include/proto/server.h | 2 +- src/cfgparse-listen.c | 2 +- src/cfgparse.c | 16 +++++++++++++--- src/server.c | 17 +++++++++++------ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/include/proto/server.h b/include/proto/server.h index 2847a8cf2..f8fed3148 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -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); diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index ffc575c39..7ebd2d513 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -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; } diff --git a/src/cfgparse.c b/src/cfgparse.c index 993496192..59bdb3bab 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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 * and initializes ->proto. diff --git a/src/server.c b/src/server.c index 725a7c63e..4c745d655 100644 --- a/src/server.c +++ b/src/server.c @@ -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 and [:] 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 and [:] as arguments.\n", + file, linenum, args[0]); + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } } err = invalid_char(args[1]);