]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: server: detect name conflict earlier during parsing
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 31 Jul 2026 14:00:32 +0000 (16:00 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 3 Aug 2026 09:13:19 +0000 (11:13 +0200)
Since 3.3, server name unicity is strictly enforced, even in case of
different numerical IDs.

  d7fad1320eae7efba98135628d0c04af6e15495e
  MAJOR: cfgparse: make sure server names are unique within a backend

This was implemented as a post parsing check via
check_config_validity(). Now, this is performed directly during the
parsing of each new server instances. The main benefit is that it is a
much clearer operation.

Multiple checks are required : in _srv_parse_init() for standard server
and in _srv_parse_tmpl_init() for server-template. Note that the latter
check requires the following patch to ensure errors are properly
reported when duplicating a server-template instance.

  commit 467440a34f81c635ccb33d434328799b027cbf03
  MINOR: server: do not ignore errors during server-template init

src/proxy.c
src/server.c

index 78f2aa64ecbac3e93942463a6262847be796c29b..ad25446e97522ed8da41e51ece3a5170641d6b77 100644 (file)
@@ -2495,32 +2495,6 @@ int proxy_finalize(struct proxy *px, int *err_code)
                        break;
        }
 
-       /* Check that no server name conflicts. This causes trouble in the stats.
-        * We only emit an error for the first conflict affecting each server,
-        * in order to avoid combinatory explosion if all servers have the same
-        * name. Since servers names are stored in a tree before landing here,
-        * we simply have to check for the current server's duplicates to spot
-        * conflicts.
-        */
-       list_for_each_entry(newsrv, &px->servers, el_px) {
-               struct server *other_srv;
-
-               /* Note: internal servers are not always registered and
-                * they do not conflict.
-                */
-               if (!ceb_intree(&newsrv->conf.name_node))
-                       continue;
-
-               if ((other_srv = cebis_item_prev_dup(&px->conf.used_server_name, conf.name_node, id, newsrv))) {
-                       ha_alert("parsing [%s:%d] : %s '%s', another server named '%s' was already defined at line %d, please use distinct names.\n",
-                                newsrv->conf.file, newsrv->conf.line,
-                                proxy_type_str(px), px->id,
-                                newsrv->id, other_srv->conf.line);
-                       cfgerr++;
-                       continue;
-               }
-       }
-
        /* assign automatic UIDs to servers which don't have one yet */
        next_id = 1;
        list_for_each_entry(newsrv, &px->servers, el_px) {
index d342aaca555181207c9d6d60132bc80e3133f40b..9a9ac081d686d06ff5f521c77531f6e1fe3ebf5d 100644 (file)
@@ -3446,7 +3446,7 @@ int srv_configure_auto_sni(struct server *srv, int *err_code, char **err)
 static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
 {
        int err_code = ERR_NONE, i = 0;
-       struct server *newsrv = NULL;
+       struct server *newsrv = NULL, *other;
        char *msg = NULL;
 
        /* Set the first server's ID. */
@@ -3458,6 +3458,13 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
                goto out;
        }
 
+       if ((other = server_find_by_name(px, srv->id))) {
+               ha_alert("another server named '%s' was already defined at line %d, please use a distinct name.\n",
+                        srv->id, other->conf.line);
+               err_code |= ERR_ALERT | ERR_FATAL;
+               goto out;
+       }
+
        cebis_item_insert(&curproxy->conf.used_server_name, conf.name_node, id, srv);
 
        /* then create other servers from this one */
@@ -3493,6 +3500,13 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
                        goto out;
                }
 
+               if ((other = server_find_by_name(px, newsrv->id))) {
+                       ha_alert("another server named '%s' was already defined at line %d, please use a distinct name.\n",
+                                newsrv->id, other->conf.line);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+
                cebis_item_insert(&curproxy->conf.used_server_name, conf.name_node, id, newsrv);
        }
 
@@ -3665,7 +3679,7 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
                            struct proxy *curproxy,
                            int parse_flags)
 {
-       struct server *newsrv = NULL;
+       struct server *newsrv = NULL, *other;
        const char *err = NULL;
        int err_code = 0;
        char *fqdn = NULL;
@@ -3747,6 +3761,13 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
                                err_code |= ERR_ALERT | ERR_ABORT;
                                goto out;
                        }
+
+                       if ((other = server_find_by_name(curproxy, newsrv->id))) {
+                               ha_alert("another server named '%s' was already defined at line %d, please use a distinct name.\n",
+                                        args[1], other->conf.line);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
                }
                else {
                        newsrv->tmpl_info.prefix = strdup(args[1]);