Skip to content

Commit b56deab

Browse files
committed
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.
1 parent 14ed1d2 commit b56deab

1 file changed

Lines changed: 33 additions & 3 deletions

File tree

src/lib/server/client.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,12 +479,40 @@ fr_client_list_t *client_list_parse_section(CONF_SECTION *section, int proto, TL
479479
fr_client_t *c = NULL;
480480
fr_client_list_t *clients = NULL;
481481
CONF_SECTION *server_cs = NULL;
482+
char const *cache_name;
483+
484+
/*
485+
* Key the cached list by protocol. The section walk below
486+
* filters out client definitions whose proto doesn't match
487+
* the caller's, so caching the filtered list under a single
488+
* key would let whichever listener instantiated first poison
489+
* the cache for the other. In particular the UDP listener
490+
* would reuse a TCP-filtered list (with UDP-default clients
491+
* dropped) and never see its own clients.
492+
*/
493+
switch (proto) {
494+
case IPPROTO_UDP:
495+
cache_name = "udp";
496+
break;
497+
498+
case IPPROTO_TCP:
499+
cache_name = "tcp";
500+
break;
501+
502+
default:
503+
/*
504+
* proto == 0 is the unfiltered / global path
505+
* (main_config.c passes 0 for root clients).
506+
*/
507+
cache_name = NULL;
508+
break;
509+
}
482510

483511
/*
484512
* Be forgiving. If there's already a clients, return
485513
* it. Otherwise create a new one.
486514
*/
487-
clients = cf_data_value(cf_data_find(section, fr_client_list_t, NULL));
515+
clients = cf_data_value(cf_data_find(section, fr_client_list_t, cache_name));
488516
if (clients) return clients;
489517

490518
/*
@@ -585,9 +613,11 @@ fr_client_list_t *client_list_parse_section(CONF_SECTION *section, int proto, TL
585613
}
586614

587615
/*
588-
* Associate the clients structure with the section.
616+
* Associate the clients structure with the section,
617+
* keyed by protocol so a per-proto listener's filtered
618+
* list doesn't shadow another proto's.
589619
*/
590-
if (!cf_data_add(section, clients, NULL, false)) {
620+
if (!cf_data_add(section, clients, cache_name, false)) {
591621
cf_log_err(section, "Failed to associate clients with section %s", cf_section_name1(section));
592622
talloc_free(clients);
593623
return NULL;

0 commit comments

Comments
 (0)