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 Jérôme Magnin for having reported this bug.

Must be backported to 2.1 and 2.0.

(cherry picked from commit 8ba10fea69aff458ee0be9c32a432dcc319f8f0b)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit b36b13a079702db5b8284fd2af06be30401449a9)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index e7fe935..de453f6 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -681,7 +681,7 @@
 	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 a3cbca5..10d8f55 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -713,7 +713,7 @@
 			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], "peers") == 0) { /* new peers section */
 		/* Initialize these static variables when entering a new "peers" section*/
@@ -811,9 +811,19 @@
 		 * 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.
diff --git a/src/server.c b/src/server.c
index 064d374..a22c04f 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2148,7 +2148,7 @@
 	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;
@@ -2178,11 +2178,16 @@
 		/* 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]);