From: Alan T. DeKok Date: Tue, 5 Mar 2024 20:34:55 +0000 (-0500) Subject: add callback to set per-packet retry configuration X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=185031a614632c68fda4a1ab998c6f3360cc5fa8;p=thirdparty%2Ffreeradius-server.git add callback to set per-packet retry configuration so that one socket can do multiple different kinds of retries --- diff --git a/src/lib/bio/retry.c b/src/lib/bio/retry.c index e2add9e4bfa..05d52b6b7b8 100644 --- a/src/lib/bio/retry.c +++ b/src/lib/bio/retry.c @@ -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. * */ diff --git a/src/lib/bio/retry.h b/src/lib/bio/retry.h index 0c01e594ef5..5c23d3b1abd 100644 --- a/src/lib/bio/retry.h +++ b/src/lib/bio/retry.h @@ -33,9 +33,9 @@ RCSIDH(lib_bio_retry_h, "$Id$") #include 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));