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

Binary IO abstractions for queues of raw packets. More...

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

Go to the source code of this file.

Data Structures

struct  fr_bio_queue_entry_s
 
struct  fr_bio_queue_s
 

Typedefs

typedef struct fr_bio_queue_list_s fr_bio_queue_list_t
 
typedef struct fr_bio_queue_s fr_bio_queue_t
 

Functions

fr_bio_tfr_bio_queue_alloc (TALLOC_CTX *ctx, size_t max_saved, fr_bio_queue_saved_t saved, fr_bio_queue_callback_t sent, fr_bio_queue_callback_t cancel, fr_bio_t *next)
 Allocate a packet-based bio. More...
 
int fr_bio_queue_cancel (fr_bio_t *bio, fr_bio_queue_entry_t *item)
 Cancel the write for a packet. More...
 
static int fr_bio_queue_destructor (fr_bio_queue_t *my)
 
static void fr_bio_queue_list_cancel (fr_bio_queue_t *my)
 Forcibly cancel all outstanding packets. More...
 
static ssize_t fr_bio_queue_list_push (fr_bio_queue_t *my, void *packet_ctx, const void *buffer, size_t size, size_t already_written)
 Push a packet onto a list. More...
 
static ssize_t fr_bio_queue_read (fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
 Read one packet from next bio. More...
 
static void fr_bio_queue_shutdown (fr_bio_t *bio)
 Shutdown. More...
 
static ssize_t fr_bio_queue_write_buffer (fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
 Write to the packet list buffer. More...
 
static ssize_t fr_bio_queue_write_flush (fr_bio_queue_t *my, size_t size)
 Flush the packet list. More...
 
static ssize_t fr_bio_queue_write_next (fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
 Write one packet to the next bio. More...
 

Detailed Description

Binary IO abstractions for queues of raw packets.

Id
6c3f2996bb9624e9043d8e877db66e8179b53787

Definition in file queue.c.


Data Structure Documentation

◆ fr_bio_queue_entry_s

struct fr_bio_queue_entry_s

Definition at line 43 of file queue.c.

+ Collaboration diagram for fr_bio_queue_entry_s:
Data Fields
size_t already_written
void const * buffer
bool cancelled
fr_bio_queue_t * my
void * packet_ctx
size_t size

◆ fr_bio_queue_s

struct fr_bio_queue_s

Definition at line 57 of file queue.c.

+ Collaboration diagram for fr_bio_queue_s:
Data Fields
fr_bio_queue_callback_t cancel
FR_BIO_COMMON
size_t max_saved
fr_bio_queue_saved_t saved
fr_bio_queue_callback_t sent

Typedef Documentation

◆ fr_bio_queue_list_t

typedef struct fr_bio_queue_list_s fr_bio_queue_list_t

Definition at line 1 of file queue.c.

◆ fr_bio_queue_t

Definition at line 1 of file queue.c.

Function Documentation

◆ fr_bio_queue_alloc()

fr_bio_t* fr_bio_queue_alloc ( TALLOC_CTX *  ctx,
size_t  max_saved,
fr_bio_queue_saved_t  saved,
fr_bio_queue_callback_t  sent,
fr_bio_queue_callback_t  cancel,
fr_bio_t next 
)

Allocate a packet-based bio.

This bio assumes that each call to fr_bio_write() is for one packet, and only one packet. If the next bio returns a partial write, or WOULD BLOCK, then information about the packet is cached. Subsequent writes will write the partial data first, and then continue with subsequent writes.

The caller is responsible for not freeing the packet ctx or the packet buffer until either the write has been performed, or the write has been cancelled.

The read() API makes no provisions for reading complete packets. It simply returns whatever the next bio allows. If instead there is a need to read only complete packets, then the next bio should be fr_bio_mem_alloc() with a fr_bio_mem_set_verify()

The read() API may return 0. There may have been data read from an underlying FD, but that data did not make it through the filters of the "next" bios. e.g. Any underlying FD should be put into a "wait for readable" state.

The write() API will return a full write, even if the next layer is blocked. Any underlying FD should be put into a "wait for writeable" state. The packet which was supposed to be written has been cached, and cannot be cancelled as it is partially written. The caller should likely start using another bio for writes. If the caller continues to use the bio, then any subsequent writes will always cache the packets.

Todo:
  • we need to mark up the bio as "blocked", and then have a write_blocked() API? ugh. or just add bool blocked and bool eof to both read/write bios

Once the underlying FD has become writeable, the caller should call fr_bio_write(bio, NULL, NULL, SIZE_MAX); That will cause the pending packets to be flushed.

The write() API may return that it's written a full packet, in which case it's either completely written to the next bio, or to the pending queue.

The read / write APIs can return WOULD_BLOCK, in which case nothing was done. Any underlying FD should be put into a "wait for writeable" state. Other errors from bios "further down" the chain can also be returned.

Parameters
ctxthe talloc ctx
max_savedMaximum number of packets to cache. Must be 1..1^17
savedcallback to run when a packet is saved in the pending queue
sentcallback to run when a packet is sent.
cancelcallback to run when a packet is cancelled.
nextthe next bio which will perform the underlying reads and writes.
  • NULL on error, memory allocation failed
  • !NULL the bio

Definition at line 388 of file queue.c.

+ Here is the call graph for this function:

◆ fr_bio_queue_cancel()

int fr_bio_queue_cancel ( fr_bio_t bio,
fr_bio_queue_entry_t item 
)

Cancel the write for a packet.

Cancel one a saved packets, and call the cancel() routine if it exists.

There is no way to cancel all packets. The caller must find the lowest bio in the chain, and shutdown it. e.g. by closing the socket via fr_bio_fd_close(). That function will take care of walking back up the chain, and shutting down each bio.

Parameters
biothe fr_bio_queue_t
itemThe context returned from fr_bio_queue_saved_t
Returns
  • <0 no such packet was found in the list of saved packets, OR the packet cannot be cancelled.
  • 0 the packet was cancelled.

Definition at line 450 of file queue.c.

+ Here is the call graph for this function:

◆ fr_bio_queue_destructor()

static int fr_bio_queue_destructor ( fr_bio_queue_t my)
static

Definition at line 101 of file queue.c.

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

◆ fr_bio_queue_list_cancel()

static void fr_bio_queue_list_cancel ( fr_bio_queue_t my)
static

Forcibly cancel all outstanding packets.

Even partially written ones. This function is called from shutdown(), when the destructor is called, or on fatal read / write errors.

Definition at line 80 of file queue.c.

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

◆ fr_bio_queue_list_push()

static ssize_t fr_bio_queue_list_push ( fr_bio_queue_t my,
void *  packet_ctx,
const void *  buffer,
size_t  size,
size_t  already_written 
)
static

Push a packet onto a list.

Definition at line 113 of file queue.c.

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

◆ fr_bio_queue_read()

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

Read one packet from next bio.

This function does NOT respect packet boundaries. The caller should use other APIs to determine how big the "next" packet is.

The caller may buffer the output data itself, or it may use other APIs to do checking.

The main

Definition at line 308 of file queue.c.

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

◆ fr_bio_queue_shutdown()

static void fr_bio_queue_shutdown ( fr_bio_t bio)
static

Shutdown.

Cancel / close has to be called before re-init.

Definition at line 337 of file queue.c.

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

◆ fr_bio_queue_write_buffer()

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

Write to the packet list buffer.

The special buffer pointer of NULL means flush(). On flush, we call next->read(), and if that succeeds, go back to "pass through" mode for the buffers.

Definition at line 287 of file queue.c.

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

◆ fr_bio_queue_write_flush()

static ssize_t fr_bio_queue_write_flush ( fr_bio_queue_t my,
size_t  size 
)
static

Flush the packet list.

Definition at line 200 of file queue.c.

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

◆ fr_bio_queue_write_next()

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

Write one packet to the next bio.

If it blocks, save the packet and return OK to the caller.

Definition at line 145 of file queue.c.

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