]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add callback to set per-packet retry configuration
authorAlan T. DeKok <aland@freeradius.org>
Tue, 5 Mar 2024 20:34:55 +0000 (15:34 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 6 Mar 2024 14:21:55 +0000 (09:21 -0500)
so that one socket can do multiple different kinds of retries

src/lib/bio/retry.c
src/lib/bio/retry.h

index e2add9e4bfaf82c0e1c000aaef2485e2d4088f21..05d52b6b7b85d7ecca8edd720b7d85962183a9e4 100644 (file)
@@ -386,8 +386,6 @@ static ssize_t fr_bio_retry_write(fr_bio_t *bio, void *packet_ctx, void const *b
        fr_bio_retry_entry_t *item;
        fr_bio_retry_t *my = talloc_get_type_abort(bio, fr_bio_retry_t);
        fr_bio_t *next;
-       fr_time_t now;
-       fr_time_delta_t retransmit;
 
        fr_assert(!my->partial);
 
@@ -420,6 +418,8 @@ static ssize_t fr_bio_retry_write(fr_bio_t *bio, void *packet_ctx, void const *b
        item = fr_bio_retry_list_pop_head(&my->free);
        fr_assert(item != NULL);
 
+       item->retry.config = NULL;
+       item->retry.start = fr_time();
        item->packet_ctx = packet_ctx;
        item->buffer = buffer;
        item->size = size;
@@ -427,16 +427,15 @@ static ssize_t fr_bio_retry_write(fr_bio_t *bio, void *packet_ctx, void const *b
        item->have_reply = false;
        item->cancelled = false;
 
-       now = fr_time();
-       fr_retry_init(&item->retry, now, &my->retry_config);
-
-       retransmit = fr_time_sub_time_time(now, item->retry.next);
-
        /*
         *      Tell the application that we've saved the packet.  The "item" pointer allows the application
         *      to cancel this packet if necessary.
         */
-       my->sent(bio, packet_ctx, buffer, size, retransmit, item);
+       my->sent(bio, packet_ctx, buffer, size, item);
+
+       if (!item->retry.config) {
+               fr_retry_init(&item->retry, item->retry.start, &my->retry_config);
+       }
 
        /*
         *      This should never fail.
@@ -545,7 +544,7 @@ static int8_t _entry_cmp(void const *one, void const *two)
  *
  *  @todo - add a "cancel oldest packet API" so we can re-use IDs before we've received all replies.
  */
-int fr_bio_retry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *item)
+int fr_bio_retry_entry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *item)
 {
        fr_bio_retry_t *my = talloc_get_type_abort(bio, fr_bio_retry_t);
 
@@ -591,6 +590,22 @@ int fr_bio_retry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *item)
        return 0;
 }
 
+/**  Set a per-packet retry config 
+ *
+ *  This function should be called from the #fr_bio_retry_sent_t callback to set a unique retry timer for this
+ *  packet.  If no retry configuration is set, then the main one from the alloc() function is used.
+ */
+int fr_bio_retry_entry_start(UNUSED fr_bio_t *bio, fr_bio_retry_entry_t *item, fr_retry_config_t const *cfg)
+{
+       fr_assert(item->buffer != NULL);
+
+       if (item->retry.config) return -1;
+
+       fr_retry_init(&item->retry, item->retry.start, cfg);
+
+       return 0;
+}
+
 /**  Cancel all outstanding packets.
  *
  */
index 0c01e594ef53343c4c4fa8b9d3bafad0f0ccf36a..5c23d3b1abdabe96b458743b1c4d578561326742 100644 (file)
@@ -33,9 +33,9 @@ RCSIDH(lib_bio_retry_h, "$Id$")
 #include <freeradius-devel/util/event.h>
 
 typedef struct {
-       fr_event_list_t         *el;            //!< event li
+       fr_event_list_t         *el;            //!< event list
 
-       fr_retry_config_t       retry_config;
+       fr_retry_config_t       retry_config;   //!< base retry config
 } fr_bio_retry_config_t;
 
 typedef struct fr_bio_retry_entry_s fr_bio_retry_entry_t;
@@ -59,7 +59,7 @@ typedef enum {
  *  @param retry_ctx   pointer to save for use with later cancellation
  */
 typedef void   (*fr_bio_retry_sent_t)(fr_bio_t *bio, void *packet_ctx, const void *buffer, size_t size,
-                                      fr_time_delta_t next_retransmit, fr_bio_retry_entry_t *retry_ctx);
+                                      fr_bio_retry_entry_t *retry_ctx);
 
 typedef ssize_t        (*fr_bio_retry_rewrite_t)(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, const void *buffer, size_t size);
 
@@ -108,6 +108,8 @@ fr_bio_t    *fr_bio_retry_alloc(TALLOC_CTX *ctx, size_t max_saved,
                                    fr_bio_retry_config_t const *cfg,
                                    fr_bio_t *next) CC_HINT(nonnull(1,3,4,6,7,8));
 
-int            fr_bio_retry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx) CC_HINT(nonnull);
+int            fr_bio_retry_entry_cancel(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx) CC_HINT(nonnull);
+
+int            fr_bio_retry_entry_start(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, fr_retry_config_t const *cfg) CC_HINT(nonnull);
 
 ssize_t                fr_bio_retry_rewrite(fr_bio_t *bio, fr_bio_retry_entry_t *retry_ctx, const void *buffer, size_t size) CC_HINT(nonnull(1,2));