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);
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;
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.
*
* @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);
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.
*
*/
#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;
* @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);
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));