From b56deabae758e131cc6a7137cd541171df6a78a8 Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Wed, 22 Apr 2026 09:07:02 -0400 Subject: [PATCH] Create different client cache lists for TCP and UDP If we had both TCP and UDP listeners, one would end up getting an empty client list. --- src/lib/server/client.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/lib/server/client.c b/src/lib/server/client.c index 40c825a4b95..f634846dde0 100644 --- a/src/lib/server/client.c +++ b/src/lib/server/client.c @@ -479,12 +479,40 @@ fr_client_list_t *client_list_parse_section(CONF_SECTION *section, int proto, TL fr_client_t *c = NULL; fr_client_list_t *clients = NULL; CONF_SECTION *server_cs = NULL; + char const *cache_name; + + /* + * Key the cached list by protocol. The section walk below + * filters out client definitions whose proto doesn't match + * the caller's, so caching the filtered list under a single + * key would let whichever listener instantiated first poison + * the cache for the other. In particular the UDP listener + * would reuse a TCP-filtered list (with UDP-default clients + * dropped) and never see its own clients. + */ + switch (proto) { + case IPPROTO_UDP: + cache_name = "udp"; + break; + + case IPPROTO_TCP: + cache_name = "tcp"; + break; + + default: + /* + * proto == 0 is the unfiltered / global path + * (main_config.c passes 0 for root clients). + */ + cache_name = NULL; + break; + } /* * Be forgiving. If there's already a clients, return * it. Otherwise create a new one. */ - clients = cf_data_value(cf_data_find(section, fr_client_list_t, NULL)); + clients = cf_data_value(cf_data_find(section, fr_client_list_t, cache_name)); if (clients) return clients; /* @@ -585,9 +613,11 @@ fr_client_list_t *client_list_parse_section(CONF_SECTION *section, int proto, TL } /* - * Associate the clients structure with the section. + * Associate the clients structure with the section, + * keyed by protocol so a per-proto listener's filtered + * list doesn't shadow another proto's. */ - if (!cf_data_add(section, clients, NULL, false)) { + if (!cf_data_add(section, clients, cache_name, false)) { cf_log_err(section, "Failed to associate clients with section %s", cf_section_name1(section)); talloc_free(clients); return NULL; -- 2.47.3