From 1e2f920be6bf56216ab793487f9aa5406f23ef7e Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Wed, 29 Oct 2025 11:43:33 +0100 Subject: [PATCH] MINOR: listener: implement bind_conf_find_by_name() Returns a pointer to the first bind_conf matching in a frontend . When name is prefixed by a @ (@:), it tries to look for the corresponding filename and line of the configuration file. NULL is returned if no match is found. --- include/haproxy/listener.h | 6 ++++ src/listener.c | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/include/haproxy/listener.h b/include/haproxy/listener.h index d8aea274b..cc32703c1 100644 --- a/include/haproxy/listener.h +++ b/include/haproxy/listener.h @@ -258,6 +258,12 @@ static inline uint accept_queue_ring_len(const struct accept_queue_ring *ring) return len; } +/* Returns a pointer to the first bind_conf matching either name , or + * filename:linenum in if begins with a '@'. NULL is returned if + * no match is found. + */ +struct bind_conf *bind_conf_find_by_name(struct proxy *front, const char *name); + #endif /* _HAPROXY_LISTENER_H */ /* diff --git a/src/listener.c b/src/listener.c index 3bb4cf862..5c81fe080 100644 --- a/src/listener.c +++ b/src/listener.c @@ -16,6 +16,8 @@ #include #include +#include + #include #include #include @@ -1944,6 +1946,63 @@ int bind_generate_guid(struct bind_conf *bind_conf) return 0; } +/* Returns a pointer to the first bind_conf matching either name , or + * filename:linenum if begins with a '@'. NULL is returned if no + * match is found. + */ +struct bind_conf *bind_conf_find_by_name(struct proxy *front, const char *name) +{ + struct bind_conf *bind_conf = NULL; + int linenum = -1; + struct ist filename = IST_NULL; + + if (*name == '@') { + /* handle @filename:linenum */ + char *endptr = NULL; + const char *p = name + 1; + + filename.ptr = (char *)p; + + while (*p != '\0' && *p != ':') + p++; + + filename.len = p - filename.ptr; + + if (*p) + p++; + + linenum = strtol(p, &endptr, 10); + if (*endptr != '\0' || endptr == p) { + linenum = -1; + /* parsing error */ + } + /* we're not using name for the next steps */ + name = NULL; + } + + /* loop on binds */ + list_for_each_entry(bind_conf, &front->conf.bind, by_fe) { + + /* if we are using a name, look at the name of the first listener, + * because bind_parse_name() sets the name on all listeners */ + if (name) { + struct listener *l; + + list_for_each_entry(l, &bind_conf->listeners, by_bind) { + if (l->name && strcmp(l->name, name) == 0) + return bind_conf; + /* we just need the first one */ + break; + } + } else { + if ((strncmp(bind_conf->file, filename.ptr, filename.len) == 0) + && bind_conf->line == linenum) + return bind_conf; + } + } + return NULL; +} + /* * Registers the bind keyword list as a list of valid keywords for next * parsing sessions. -- 2.47.3