From: Amaury Denoyelle Date: Fri, 31 Jul 2026 14:00:32 +0000 (+0200) Subject: MINOR: server: detect name conflict earlier during parsing X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e47582a5b0db1d24347cfd0ca13110f88e7fb03;p=thirdparty%2Fhaproxy.git MINOR: server: detect name conflict earlier during parsing 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 --- diff --git a/src/proxy.c b/src/proxy.c index 78f2aa64e..ad25446e9 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -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) { diff --git a/src/server.c b/src/server.c index d342aaca5..9a9ac081d 100644 --- a/src/server.c +++ b/src/server.c @@ -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]);