]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
move client list to simple rbtree
authorAlan T. DeKok <aland@freeradius.org>
Thu, 2 Mar 2023 02:06:37 +0000 (21:06 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 2 Mar 2023 21:27:38 +0000 (16:27 -0500)
so that we can loop over it ourselves.

And because we can't have ip/mask for BFD.  The packets are
always sent to a particular IP

src/listen/bfd/proto_bfd.c
src/listen/bfd/proto_bfd.h
src/listen/bfd/proto_bfd_udp.c

index b97e6f019d2a2aa65aa71f00575b62bcd6b4bf25..9dd27b9f2d48c1bbd888150806bc91bd2dad387c 100644 (file)
@@ -75,6 +75,17 @@ fr_dict_attr_autoload_t proto_bfd_dict_attr[] = {
        { NULL }
 };
 
+/*
+ *     They all have to be UDP.
+ */
+static int8_t client_cmp(void const *one, void const *two)
+{
+       fr_client_t const *a = one;
+       fr_client_t const *b = two;
+
+       return fr_ipaddr_cmp(&a->ipaddr, &b->ipaddr);
+}
+
 /** Wrapper around dl_instance
  *
  * @param[in] ctx      to allocate data in (instance of proto_bfd).
@@ -423,11 +434,11 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx)
 
        server = inst->io.server_cs;
 
-       inst->peers = cf_data_value(cf_data_find(server, fr_client_list_t, NULL));
+       inst->peers = cf_data_value(cf_data_find(server, fr_rb_tree_t, "peers"));
        if (!inst->peers) {
                CONF_SECTION *cs = NULL;
 
-               inst->peers = client_list_init(server);
+               inst->peers = fr_rb_inline_talloc_alloc(inst, fr_client_t, node, client_cmp, NULL);
                if (!inst->peers) return -1;
 
                while ((cs = cf_section_find_next(server, cs, "peer", CF_IDENT_ANY))) {
@@ -460,13 +471,19 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx)
                        FR_INTEGER_BOUND_CHECK("peer.max_timeouts", peer->max_timeouts, >=, 1);
                        FR_INTEGER_BOUND_CHECK("peer.max_timeouts", peer->max_timeouts, <=, 10);
 
-                       if (!client_add(inst->peers, c)) {
+                       if (((c->ipaddr.af == AF_INET) && (c->ipaddr.prefix != 32)) ||
+                           ((c->ipaddr.af == AF_INET6) && (c->ipaddr.prefix != 128))) {
+                               cf_log_err(cs, "Invalid IP prefix - cannot use ip/mask for BFD");
+                               goto error;
+                       }
+
+                       if (!fr_rb_insert(inst->peers, c)) {
                                cf_log_err(cs, "Failed to add peer %s", cf_section_name2(cs));
                                goto error;
                        }
                }
 
-               (void) cf_data_add(server, inst->peers, NULL, true);
+               (void) cf_data_add(server, inst->peers, "peers", false);
        }
 
        /*
index 8c84c15dc8ca9804cf106719ba4ee04e5bccb57f..0de1304270f2801969fea2abce3b181c03687803 100644 (file)
@@ -35,7 +35,7 @@ typedef struct {
        uint32_t                        max_packet_size;                //!< for message ring buffer.
        uint32_t                        num_messages;                   //!< for message ring buffer.
 
-       fr_client_list_t                *peers;
+       fr_rb_tree_t                    *peers;
 } proto_bfd_t;
 
 typedef struct {
index 99d74576ac30fcc75339a9ef6aeb51a21141ef39..dc815fe1bed6fda078b7f62e52f2a25079c99fd1 100644 (file)
@@ -47,6 +47,8 @@ typedef struct {
 typedef struct {
        CONF_SECTION                    *cs;                    //!< our configuration
 
+       fr_event_list_t                 *el;
+
        fr_ipaddr_t                     ipaddr;                 //!< IP address to listen on.
 
        char const                      *interface;             //!< Interface to bind to.
@@ -63,7 +65,7 @@ typedef struct {
        bool                            send_buff_is_set;       //!< Whether we were provided with a send_buff
        bool                            dynamic_clients;        //!< whether we have dynamic clients
 
-       fr_client_list_t                *clients;               //!< local clients
+       fr_rb_tree_t                    *peers;                 //!< our peers
 
        fr_trie_t                       *trie;                  //!< for parsed networks
        fr_ipaddr_t                     *allow;                 //!< allowed networks for dynamic clients
@@ -390,14 +392,11 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx)
        server_cs = cf_item_to_section(ci);
 
        /*
-        *      Look up local clients, if they exist.
-        *
-        *      @todo - ensure that we only parse clients which are
-        *      for IPPROTO_UDP, and require a "secret".
+        *      Look up peer list.
         */
-       inst->clients = cf_data_value(cf_data_find(server_cs, fr_client_list_t, NULL));
-       if (!inst->clients) {
-               cf_log_err(conf, "Failed finding local clients");
+       inst->peers = cf_data_value(cf_data_find(server_cs, fr_rb_tree_t, "peers"));
+       if (!inst->peers) {
+               cf_log_err(conf, "Failed finding peer list");
                return -1;
        }
 
@@ -406,18 +405,11 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx)
 
 static fr_client_t *mod_client_find(fr_listen_t *li, fr_ipaddr_t const *ipaddr, int ipproto)
 {
-       proto_bfd_udp_t const           *inst = talloc_get_type_abort_const(li->app_io_instance, proto_bfd_udp_t);
-       fr_client_t             *client;
+       proto_bfd_udp_t const   *inst = talloc_get_type_abort_const(li->app_io_instance, proto_bfd_udp_t);
 
-       /*
-        *      Prefer local clients.
-        */
-       if (inst->clients) {
-               client = client_find(inst->clients, ipaddr, ipproto);
-               if (client) return client;
-       }
+       if (ipproto != IPPROTO_UDP) return NULL;
 
-       return client_find(NULL, ipaddr, ipproto);
+       return fr_rb_find(inst->peers, &(fr_client_t) { .ipaddr = *ipaddr, .proto = IPPROTO_UDP });
 }
 
 fr_app_io_t proto_bfd_udp = {