The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Data Structures | Macros | Typedefs | Functions
retry.c File Reference

Binary IO abstractions for retrying packets. More...

#include <freeradius-devel/bio/bio_priv.h>
#include <freeradius-devel/bio/null.h>
#include <freeradius-devel/bio/buf.h>
#include <freeradius-devel/util/rb.h>
#include <freeradius-devel/util/dlist.h>
#include <freeradius-devel/bio/retry.h>
+ Include dependency graph for retry.c:

Go to the source code of this file.

Data Structures

struct  fr_bio_retry_entry_s
 
union  fr_bio_retry_entry_s.__unnamed10__
 
struct  fr_bio_retry_s
 

Macros

#define _BIO_RETRY_PRIVATE
 
#define fr_bio_retry_timer_clear(_x)
 

Typedefs

typedef struct fr_bio_retry_list_s fr_bio_retry_list_t
 
typedef struct fr_bio_retry_s fr_bio_retry_t
 

Functions

static int8_t _expiry_cmp (void const *one, void const *two)
 
static int8_t _next_retry_cmp (void const *one, void const *two)
 
fr_bio_tfr_bio_retry_alloc (TALLOC_CTX *ctx, size_t max_saved, fr_bio_retry_sent_t sent, fr_bio_retry_response_t response, fr_bio_retry_rewrite_t rewrite, fr_bio_retry_release_t release, fr_bio_retry_config_t const *cfg, fr_bio_t *next)
 Allocate a fr_bio_retry_t. More...
 
static int fr_bio_retry_destructor (fr_bio_retry_t *my)
 Cancel all outstanding packets. More...
 
int fr_bio_retry_entry_cancel (fr_bio_t *bio, fr_bio_retry_entry_t *item)
 Cancel one item. More...
 
const fr_retry_tfr_bio_retry_entry_info (UNUSED fr_bio_t *bio, fr_bio_retry_entry_t *item)
 Allow the callbacks / application to know when things are being retried. More...
 
int fr_bio_retry_entry_init (UNUSED fr_bio_t *bio, fr_bio_retry_entry_t *item, fr_retry_config_t const *cfg)
 Set a per-packet retry config. More...
 
static void fr_bio_retry_expiry_timer (UNUSED fr_event_list_t *el, fr_time_t now, void *uctx)
 Run an expiry timer event. More...
 
static int fr_bio_retry_expiry_timer_reset (fr_bio_retry_t *my)
 Reset the expiry timer after expiring one element. More...
 
fr_bio_retry_info_t const * fr_bio_retry_info (fr_bio_t *bio)
 
fr_bio_retry_entry_tfr_bio_retry_item_reserve (fr_bio_t *bio)
 Reserve an entry for later use with fr_bio_retry_rewrite() More...
 
size_t fr_bio_retry_outstanding (fr_bio_t *bio)
 
static ssize_t fr_bio_retry_read (fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
 
static void fr_bio_retry_release (fr_bio_retry_t *my, fr_bio_retry_entry_t *item, fr_bio_retry_release_reason_t reason)
 Release an entry back to the free list. More...
 
ssize_t fr_bio_retry_rewrite (fr_bio_t *bio, fr_bio_retry_entry_t *item, const void *buffer, size_t size)
 Resend a packet. More...
 
static ssize_t fr_bio_retry_save_write (fr_bio_retry_t *my, fr_bio_retry_entry_t *item, ssize_t rcode)
 Save a partial packet when the write becomes blocked. More...
 
static void fr_bio_retry_shutdown (fr_bio_t *bio)
 Orderly shutdown. More...
 
static void fr_bio_retry_timer (UNUSED fr_event_list_t *el, fr_time_t now, void *uctx)
 Run a timer event. More...
 
static int fr_bio_retry_timer_reset (fr_bio_retry_t *my)
 Reset the timer after changing the rb tree. More...
 
static ssize_t fr_bio_retry_write (fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
 Write a request, and see if we have a reply. More...
 
static int fr_bio_retry_write_blocked (fr_bio_t *bio)
 Writes are blocked. More...
 
static int fr_bio_retry_write_delayed (fr_bio_retry_t *my, fr_time_t now)
 
static ssize_t fr_bio_retry_write_fatal (fr_bio_t *bio, UNUSED void *packet_ctx, UNUSED void const *buffer, UNUSED size_t size)
 A previous timer write had a fatal error, so we forbid further writes. More...
 
static int fr_bio_retry_write_item (fr_bio_retry_t *my, fr_bio_retry_entry_t *item, fr_time_t now)
 Write one item. More...
 
static ssize_t fr_bio_retry_write_partial (fr_bio_t *bio, void *packet_ctx, const void *buffer, size_t size)
 There's a partial packet written. More...
 
static int fr_bio_retry_write_resume (fr_bio_t *bio)
 Resume writes. More...
 

Detailed Description

Binary IO abstractions for retrying packets.

Id
a0d3078b8bb4db8ba2a96e7b0d3ef85a54c66f4b

The retry BIO provides a mechanism for the application to send one packet, and then delegate retransmissions to the retry bio.

This BIO will monitor writes, and run callbacks when a packet is sent, received, and released. The application should cache the request and response until the release callback has been run. The BIO will call the application on retries, or when the retransmissions have stopped.

The retry BIO also deals with partially written packets. The BIO takes responsibility for not writing partial packets, which means that requests can be rleeased even if the data has been partially written. The application can also cancel an ongoing retryt entrty at any time.

If something blocks IO, the application should call the blocked / resume functions for this BIO to inform it of IO changes. Otherwise, the only time this BIO blocks is when it runs out of retransmission slots.

There are provisions for application-layer watchdogs, where the application can reserve a retry entry. It can then call the fr_bio_retry_rewrite() function instead of fr_bio_write() to write the watchdog packet. Any retransmission timers for the application-layer watchdog must be handled by the application. The BIO will not retry reserved watchdog requests.

In general, the next BIO after this one should be the memory bio, so that this bio receives only complete packets.

Definition in file retry.c.


Data Structure Documentation

◆ fr_bio_retry_entry_s

struct fr_bio_retry_entry_s

Definition at line 64 of file retry.c.

+ Collaboration diagram for fr_bio_retry_entry_s:
Data Fields
union fr_bio_retry_entry_s __unnamed__
uint8_t const * buffer cached copy of the packet to send
bool cancelled was this item cancelled?
fr_rb_node_t expiry_node for expiries
fr_bio_retry_t * my so we can get to it from the event timer callback
void * packet_ctx packet_ctx from the write() call
bool reserved for application-layer watchdog
fr_retry_t retry retry timers and counters
fr_retry_t _CONST retry retry timers and counters
fr_bio_retry_rewrite_t rewrite per-packet rewrite callback
void * rewrite_ctx context specifically for rewriting this packet
size_t size size of the cached packet
void * uctx user-writable context

◆ fr_bio_retry_entry_s.__unnamed10__

union fr_bio_retry_entry_s.__unnamed10__

Definition at line 72 of file retry.c.

Data Fields
fr_rb_node_t next_retry_node for retries

◆ fr_bio_retry_s

struct fr_bio_retry_s

Definition at line 89 of file retry.c.

+ Collaboration diagram for fr_bio_retry_s:
Data Fields
bool all_used blocked due to no free entries
fr_bio_buf_t buffer to store partial packets
ssize_t error
fr_event_timer_t const * ev we only need one timer event: next time we do something
fr_rb_tree_t expiry_tree when packets expire, so that we expire packets when the socket is blocked.
FR_BIO_COMMON
fr_bio_retry_info_t info
fr_bio_retry_entry_t * next_retry_item for timers
fr_rb_tree_t next_retry_tree when packets are retried next
fr_bio_retry_entry_t * partial for partial writes
fr_bio_retry_release_t release callback to release a request / response pair
fr_bio_retry_response_t response callback to see if we got a valid response
fr_retry_config_t retry_config
fr_bio_retry_rewrite_t rewrite optional callback which can change a packet on retry
fr_bio_retry_sent_t sent callback for when we successfully sent a packet

Macro Definition Documentation

◆ _BIO_RETRY_PRIVATE

#define _BIO_RETRY_PRIVATE

Definition at line 53 of file retry.c.

◆ fr_bio_retry_timer_clear

#define fr_bio_retry_timer_clear (   _x)
Value:
do { \
talloc_const_free((_x)->ev); \
(_x)->next_retry_item = NULL; \
} while (0)

Definition at line 132 of file retry.c.

Typedef Documentation

◆ fr_bio_retry_list_t

typedef struct fr_bio_retry_list_s fr_bio_retry_list_t

Definition at line 1 of file retry.c.

◆ fr_bio_retry_t

Definition at line 1 of file retry.c.

Function Documentation

◆ _expiry_cmp()

static int8_t _expiry_cmp ( void const *  one,
void const *  two 
)
static

Definition at line 971 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _next_retry_cmp()

static int8_t _next_retry_cmp ( void const *  one,
void const *  two 
)
static

Definition at line 955 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_alloc()

fr_bio_t* fr_bio_retry_alloc ( TALLOC_CTX *  ctx,
size_t  max_saved,
fr_bio_retry_sent_t  sent,
fr_bio_retry_response_t  response,
fr_bio_retry_rewrite_t  rewrite,
fr_bio_retry_release_t  release,
fr_bio_retry_config_t const *  cfg,
fr_bio_t next 
)

Allocate a fr_bio_retry_t.

Definition at line 1087 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_destructor()

static int fr_bio_retry_destructor ( fr_bio_retry_t my)
static

Cancel all outstanding packets.

Definition at line 1055 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_entry_cancel()

int fr_bio_retry_entry_cancel ( fr_bio_t bio,
fr_bio_retry_entry_t item 
)

Cancel one item.

If "item" is NULL, the last entry in the timer tree is cancelled.

Parameters
biothe binary IO handler
itemthe retry context from fr_bio_retry_sent_t
Returns
  • <0 error
  • 0 - didn't cancel
  • 1 - did cancel

Definition at line 993 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_entry_info()

const fr_retry_t* fr_bio_retry_entry_info ( UNUSED fr_bio_t bio,
fr_bio_retry_entry_t item 
)

Allow the callbacks / application to know when things are being retried.

This is not initialized util after fr_bio_retry_entry_start() has been called.

Definition at line 1042 of file retry.c.

+ Here is the call graph for this function:

◆ fr_bio_retry_entry_init()

int fr_bio_retry_entry_init ( UNUSED fr_bio_t bio,
fr_bio_retry_entry_t item,
fr_retry_config_t const *  cfg 
)

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.

Definition at line 1025 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_expiry_timer()

static void fr_bio_retry_expiry_timer ( UNUSED fr_event_list_t el,
fr_time_t  now,
void *  uctx 
)
static

Run an expiry timer event.

Definition at line 630 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_expiry_timer_reset()

static int fr_bio_retry_expiry_timer_reset ( fr_bio_retry_t my)
static

Reset the expiry timer after expiring one element.

Definition at line 140 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_info()

fr_bio_retry_info_t const* fr_bio_retry_info ( fr_bio_t bio)

Definition at line 1158 of file retry.c.

+ Here is the caller graph for this function:

◆ fr_bio_retry_item_reserve()

fr_bio_retry_entry_t* fr_bio_retry_item_reserve ( fr_bio_t bio)

Reserve an entry for later use with fr_bio_retry_rewrite()

So that application-layer watchdogs can bypass the normal write / retry routines.

Definition at line 1184 of file retry.c.

+ Here is the call graph for this function:

◆ fr_bio_retry_outstanding()

size_t fr_bio_retry_outstanding ( fr_bio_t bio)

Definition at line 1165 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_read()

static ssize_t fr_bio_retry_read ( fr_bio_t bio,
void *  packet_ctx,
void *  buffer,
size_t  size 
)
static

Definition at line 851 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_release()

static void fr_bio_retry_release ( fr_bio_retry_t my,
fr_bio_retry_entry_t item,
fr_bio_retry_release_reason_t  reason 
)
static

Release an entry back to the free list.

Definition at line 212 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_rewrite()

ssize_t fr_bio_retry_rewrite ( fr_bio_t bio,
fr_bio_retry_entry_t item,
const void *  buffer,
size_t  size 
)

Resend a packet.

This function should be called by the rewrite() callback, after (possibly) re-encoding the packet.

Parameters
biothe binary IO handler
itemthe retry context from fr_bio_retry_sent_t
bufferraw data for the packet. May be NULL, in which case the previous packet is retried
sizesize of the raw data
Returns
  • <0 on error
  • 0 for "wrote no data"
  • >0 for "wrote data".

Definition at line 554 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_save_write()

static ssize_t fr_bio_retry_save_write ( fr_bio_retry_t my,
fr_bio_retry_entry_t item,
ssize_t  rcode 
)
static

Save a partial packet when the write becomes blocked.

Definition at line 503 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_shutdown()

static void fr_bio_retry_shutdown ( fr_bio_t bio)
static

Orderly shutdown.

Definition at line 1077 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_timer()

static void fr_bio_retry_timer ( UNUSED fr_event_list_t el,
fr_time_t  now,
void *  uctx 
)
static

Run a timer event.

Usually to write out another packet.

Definition at line 669 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_timer_reset()

static int fr_bio_retry_timer_reset ( fr_bio_retry_t my)
static

Reset the timer after changing the rb tree.

Definition at line 173 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_write()

static ssize_t fr_bio_retry_write ( fr_bio_t bio,
void *  packet_ctx,
void const *  buffer,
size_t  size 
)
static

Write a request, and see if we have a reply.

Definition at line 717 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_write_blocked()

static int fr_bio_retry_write_blocked ( fr_bio_t bio)
static

Writes are blocked.

Definition at line 278 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_write_delayed()

static int fr_bio_retry_write_delayed ( fr_bio_retry_t my,
fr_time_t  now 
)
static

Definition at line 375 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_write_fatal()

static ssize_t fr_bio_retry_write_fatal ( fr_bio_t bio,
UNUSED void *  packet_ctx,
UNUSED void const *  buffer,
UNUSED size_t  size 
)
static

A previous timer write had a fatal error, so we forbid further writes.

Definition at line 616 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_write_item()

static int fr_bio_retry_write_item ( fr_bio_retry_t my,
fr_bio_retry_entry_t item,
fr_time_t  now 
)
static

Write one item.

Returns
  • <0 on error
  • 0 for "can't write any more"
  • 1 for "wrote a packet"

Definition at line 303 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_write_partial()

static ssize_t fr_bio_retry_write_partial ( fr_bio_t bio,
void *  packet_ctx,
const void *  buffer,
size_t  size 
)
static

There's a partial packet written.

Write all of that one first, before writing another packet.

The packet can either be cancelled, or IO blocked. In either case, we must write the full packet before going on to the next one, OR retrying another packet.

Definition at line 442 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_bio_retry_write_resume()

static int fr_bio_retry_write_resume ( fr_bio_t bio)
static

Resume writes.

On resume, we try to flush any pending packets which should have been sent.

Definition at line 418 of file retry.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function: