]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: peers: Incomplete peers sections should be validated.
authorFrédéric Lécaille <flecaille@haproxy.com>
Fri, 3 Apr 2020 07:43:47 +0000 (09:43 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 15 Apr 2020 08:47:39 +0000 (10:47 +0200)
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
src/cfgparse-listen.c
src/cfgparse.c
src/server.c

index 2847a8cf254269d8fd51647ded72e2c391693828..f8fed314884a5fb4ff1228f59640d90c56264cf5 100644 (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);
index ffc575c39a4a0c6ef0f68573cc43894de8986844..7ebd2d5134722a613bd838b43bfd8f668909837c 100644 (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;
        }
index 993496192ac19420c1a5950081b2a7e0c3ebfb57..59bdb3bab49e3c7224c7e803ab7bdb1bfc764649 100644 (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.
index 725a7c63e297dd23779d10e85c4dacdc2c0a0cd0..4c745d655d14ffc0ed11813f9def82163c1b46c1 100644 (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]);