]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: server: prevent name collision with a default-server
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 31 Jul 2026 14:23:08 +0000 (16:23 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 3 Aug 2026 14:52:09 +0000 (16:52 +0200)
The previous patch has introduced the support for named default-server.
It is not possible though to declare a default-server with a name if it
collides with an already existing server instance.

This patch implements a similar check but on the other side : it ensures
that a newly created server instance does not collide with an already
existing default-server.

To implement this, a new function server_find_by_name2() is defined. It
is similar to server_find_by_name() except it also lookup in the named
default-server tree. Checks are performed on several places :
* _srv_parse_init() for a server parsing
* _srv_parse_tmpl_init() for a server-template parsing
* srv_update_server_name() for the CLI command "set server name"
* cli_parse_add_server() for the CLI command "add server"

include/haproxy/server.h
src/server.c

index 2ef7e0e62ed50dec54107a4b9102153f552a14ab..3c9667dfa2007e3060eb69c7f504ff7e95da3420 100644 (file)
@@ -66,6 +66,7 @@ const char *srv_update_check_addr_port(struct server *s, const char *addr, const
 const char *srv_update_agent_addr_port(struct server *s, const char *addr, const char *port);
 struct server *server_find_by_id_unique(struct proxy *bk, int id, uint32_t rid);
 struct server *server_find_by_name(struct proxy *px, const char *name);
+struct server *server_find_by_name2(struct proxy *px, const char *name);
 struct server *server_find_by_addr(struct proxy *px, const char *addr);
 struct server *server_find(struct proxy *bk, const char *name);
 struct server *server_find_unique(struct proxy *bk, const char *name, uint32_t rid);
index 6a15801d478bdb7cc5d584d0ccbb0ebacb684e9e..83024f89b8c888e93cc975bf0c4390282d051b38 100644 (file)
@@ -3470,7 +3470,7 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
                goto out;
        }
 
-       if ((other = server_find_by_name(px, srv->id))) {
+       if ((other = server_find_by_name2(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;
@@ -3512,7 +3512,7 @@ static int _srv_parse_tmpl_init(struct server *srv, struct proxy *px)
                        goto out;
                }
 
-               if ((other = server_find_by_name(px, newsrv->id))) {
+               if ((other = server_find_by_name2(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;
@@ -3774,7 +3774,7 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
                                goto out;
                        }
 
-                       if ((other = server_find_by_name(curproxy, newsrv->id))) {
+                       if ((other = server_find_by_name2(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;
@@ -4352,6 +4352,21 @@ struct server *server_find_by_name(struct proxy *px, const char *name)
        return cebuis_item_lookup(&px->conf.used_server_name, conf.name_node, id, name, struct server);
 }
 
+/* Equivalent to server_find_by_name() excepts it also lookup in the named
+ * default-server tree.
+ */
+struct server *server_find_by_name2(struct proxy *px, const char *name)
+{
+       struct server *srv;
+
+       srv = server_find_by_name(px, name);
+       if (srv)
+               return srv;
+
+       return cebuis_item_lookup(&px->defsrv_by_name, conf.name_node, id, name,
+                                 struct server);
+}
+
 /*
  * This function returns the server with a matching address within selected
  * proxy, or NULL if not found. The proxy lock is taken for reads during this
@@ -5743,7 +5758,7 @@ static const char *srv_update_server_name(struct server *srv, const char *new_na
        /* re-check for name conflict under isolation — another rename or
         * add server could have raced before we isolated.
         */
-       if (server_find_by_name(be, new_name)) {
+       if (server_find_by_name2(be, new_name)) {
                thread_release();
                free(dup);
                return "A server with the same name already exists in this backend.\n";
@@ -6553,7 +6568,7 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct
        /*
         * If a server with the same name is found, reject the new one.
         */
-       if (server_find(be, sv_name)) {
+       if (server_find_by_name2(be, sv_name)) {
                thread_release();
                cli_err(appctx, "Already exists a server with the same name in backend.\n");
                return 1;