]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allocate tracking table at the start
authorAlan T. DeKok <aland@freeradius.org>
Wed, 6 Mar 2024 21:22:10 +0000 (16:22 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 9 Mar 2024 15:06:49 +0000 (10:06 -0500)
src/protocols/radius/client.c
src/protocols/radius/client.h

index 9ee85557ba43cf04fc974b4df204a2aa33c893ef..fe170eead7911a575dd2e86b145cdd44bda0aa61 100644 (file)
@@ -52,6 +52,7 @@ static int _radius_client_fd_bio_free(fr_radius_client_fd_bio_t *my)
 
 fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t read_size, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg)
 {
+       int i;
        fr_radius_client_fd_bio_t *my;
        fr_bio_t *fd, *mem;
 
@@ -60,6 +61,16 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t
        my = talloc_zero(ctx, fr_radius_client_fd_bio_t);
        if (!my) return NULL;
 
+       /*
+        *      Allocate tracking for all of the packets.
+        */
+       for (i = 1; i < FR_RADIUS_CODE_MAX; i++) {
+               if (!cfg->allowed[i]) continue;
+
+               my->codes[i] = fr_radius_id_alloc(my);
+               if (!my->codes[i]) goto fail;
+       }
+
        my->fd = fd = fr_bio_fd_alloc(my, NULL, fd_cfg, 0);
        if (!fd) {
        fail:
@@ -68,7 +79,7 @@ fr_radius_client_fd_bio_t *fr_radius_client_fd_bio_alloc(TALLOC_CTX *ctx, size_t
        }
        my->fd = fd;
 
-       my->mem = mem = fr_bio_mem_alloc(ctx, read_size, 2 * 4096, fd);
+       my->mem = mem = fr_bio_mem_alloc(my, read_size, 2 * 4096, fd);
        if (!mem) goto fail;
 
        my->cfg = *cfg;
@@ -91,12 +102,16 @@ int fr_radius_client_fd_bio_write(fr_radius_client_fd_bio_t *my, UNUSED void *pa
        fr_assert(packet->code > 0);
        fr_assert(packet->code < FR_RADIUS_CODE_MAX);
 
-       /*
-        *      @todo - Allocate when the socket is opened, so we don't check it for every packet.
-        */
-       if (!my->codes[packet->code] && !(my->codes[packet->code] = fr_radius_id_alloc(my))) return -1;
+       if (!my->codes[packet->code]) {
+               fr_strerror_printf("Outgoing packet code %s is disallowed by the configuration",
+                                  fr_radius_packet_names[packet->code]);
+               return -1;
+       }
 
-       if (fr_radius_code_id_pop(my->codes, packet) < 0) return -1;
+       if (fr_radius_code_id_pop(my->codes, packet) < 0) {
+               fr_strerror_const("All IDs are in use");
+               return -1;
+       }
 
        /*
         *      Encode the packet.
@@ -145,7 +160,6 @@ int fr_radius_client_fd_bio_read(fr_bio_packet_t *bio, UNUSED void *packet_ctx,
 
        if (slen < 0) {
                fr_assert(slen != fr_bio_error(IO_WOULD_BLOCK));
-
                return slen;
        }
 
@@ -177,14 +191,7 @@ int fr_radius_client_fd_bio_read(fr_bio_packet_t *bio, UNUSED void *packet_ctx,
        }
 
        /*
-        *      @todo - if we already have a reply then don't decode
-        *      it.  Just return "whoops, no packet".
-        *
-        *      @todo - provide an API to expire the outgoing packet.
-        *
-        *      @todo - provide an API to run timers for a particular packet.
-        *
-        *      Any retries, etc. are part of packet->uctx
+        *      Return the code to the free list.
         */
        if (fr_radius_code_id_push(my->codes, packet) < 0) {
                fr_assert(0);
index 4805dceb16343349a7c7dd2d7631c20870162044..451b885885c9647ef765a38467a7aa98a924255b 100644 (file)
@@ -33,7 +33,9 @@ RCSIDH(radius_client_h, "$Id$")
 typedef struct {
        fr_radius_bio_verify_t  verify;
 
-       fr_retry_config_t  retry[FR_RADIUS_CODE_MAX];
+       bool            allowed[FR_RADIUS_CODE_MAX];    //!< allowed outgoing packet types
+
+       fr_retry_config_t  retry[FR_RADIUS_CODE_MAX];   //!< default retry configuration for each packet type
 } fr_radius_client_config_t;
 
 fr_bio_packet_t *fr_radius_client_bio_alloc(TALLOC_CTX *ctx, fr_radius_client_config_t *cfg, fr_bio_fd_config_t const *fd_cfg) CC_HINT(nonnull);