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

BIO abstractions for memory buffers. More...

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

Go to the source code of this file.

Data Structures

struct  fr_bio_mem_s
 The memory buffer bio. More...
 

Typedefs

typedef struct fr_bio_mem_s fr_bio_mem_t
 The memory buffer bio. More...
 

Functions

fr_bio_tfr_bio_mem_alloc (TALLOC_CTX *ctx, size_t read_size, size_t write_size, fr_bio_t *next)
 Allocate a memory buffer bio. More...
 
static bool fr_bio_mem_buf_alloc (fr_bio_mem_t *my, fr_bio_buf_t *buf, size_t size)
 Allocate a memory buffer bio for either reading or writing. More...
 
static int fr_bio_mem_call_verify (fr_bio_t *bio, void *packet_ctx, size_t *size)
 Verify that a packet is OK. More...
 
static int fr_bio_mem_eof (fr_bio_t *bio)
 
static ssize_t fr_bio_mem_read (fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
 Read from a memory BIO. More...
 
static ssize_t fr_bio_mem_read_buffer (fr_bio_t *bio, UNUSED void *packet_ctx, void *buffer, size_t size)
 Read from a buffer which a previous bio has filled. More...
 
void fr_bio_mem_read_discard (fr_bio_t *bio, size_t size)
 Discard data from the read buffer. More...
 
static ssize_t fr_bio_mem_read_eof (fr_bio_t *bio, UNUSED void *packet_ctx, void *buffer, size_t size)
 At EOF, read data from the buffer until it is empty. More...
 
uint8_t const * fr_bio_mem_read_peek (fr_bio_t *bio, size_t *size)
 Peek at the data in the read buffer. More...
 
static ssize_t fr_bio_mem_read_verify (fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
 Return data only if we have a complete packet. More...
 
static ssize_t fr_bio_mem_read_verify_datagram (fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
 Return data only if we have a complete packet. More...
 
int fr_bio_mem_set_verify (fr_bio_t *bio, fr_bio_verify_t verify, void *verify_ctx, bool datagram)
 Set the verification function for memory bios. More...
 
static void fr_bio_mem_shutdown (fr_bio_t *bio)
 
fr_bio_tfr_bio_mem_sink_alloc (TALLOC_CTX *ctx, size_t read_size)
 Allocate a memory buffer which sinks data from a bio system into the callers application. More...
 
fr_bio_tfr_bio_mem_source_alloc (TALLOC_CTX *ctx, size_t write_size, fr_bio_t *next)
 Allocate a memory buffer which sources data from the callers application into the bio system. More...
 
static ssize_t fr_bio_mem_write_buffer (fr_bio_t *bio, UNUSED void *packet_ctx, void const *buffer, size_t size)
 Write to the memory buffer. More...
 
static ssize_t fr_bio_mem_write_buffer (fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
 
static ssize_t fr_bio_mem_write_flush (fr_bio_mem_t *my, size_t size)
 Flush the memory buffer. More...
 
static ssize_t fr_bio_mem_write_next (fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
 Pass writes to the next BIO. More...
 
static ssize_t fr_bio_mem_write_read_buffer (fr_bio_t *bio, UNUSED void *packet_ctx, void const *buffer, size_t size)
 Write to the read buffer. More...
 
int fr_bio_mem_write_resume (fr_bio_t *bio)
 See if we can resume writes to the memory bio. More...
 

Detailed Description

BIO abstractions for memory buffers.

Id
c66df4f187d40d34e23024b6dd53cf5529c3df32

Definition in file mem.c.


Data Structure Documentation

◆ fr_bio_mem_s

struct fr_bio_mem_s

The memory buffer bio.

It is used to buffer reads / writes to a streaming socket.

Definition at line 35 of file mem.c.

+ Collaboration diagram for fr_bio_mem_s:
Data Fields
FR_BIO_COMMON
fr_bio_buf_t read_buffer buffering for reads
fr_bio_verify_t verify verify data to see if we have a packet.
void * verify_ctx verify context
fr_bio_buf_t write_buffer buffering for writes

Typedef Documentation

◆ fr_bio_mem_t

typedef struct fr_bio_mem_s fr_bio_mem_t

The memory buffer bio.

It is used to buffer reads / writes to a streaming socket.

Function Documentation

◆ fr_bio_mem_alloc()

fr_bio_t* fr_bio_mem_alloc ( TALLOC_CTX *  ctx,
size_t  read_size,
size_t  write_size,
fr_bio_t next 
)

Allocate a memory buffer bio.

The "read buffer" will cache reads from the next bio in the chain. If the next bio returns more data than the caller asked for, the extra data is cached in the read buffer.

The "write buffer" will buffer writes to the next bio in the chain. If the caller writes more data than the next bio can process, the extra data is cached in the write buffer.

When the bio is closed (or freed) any pending data in the buffers is lost. The same happens if the next bio returns a fatal error.

At some point during a read, the next bio may return EOF. When that happens, the caller should not rely on the next FD being readable or writable. Instead, it should keep reading from the memory bio until it returns EOF. See fr_bio_fd_eof() for details.

Parameters
ctxthe talloc ctx
read_sizesize of the read buffer. Must be 1024..1^20
write_sizesize of the write buffer. Can be zero. If non-zero, must be 1024..1^20
nextthe next bio which will perform the underlying reads and writes.
  • NULL on error, memory allocation failed
  • !NULL the bio

Definition at line 727 of file mem.c.

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

◆ fr_bio_mem_buf_alloc()

static bool fr_bio_mem_buf_alloc ( fr_bio_mem_t my,
fr_bio_buf_t buf,
size_t  size 
)
static

Allocate a memory buffer bio for either reading or writing.

Definition at line 692 of file mem.c.

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

◆ fr_bio_mem_call_verify()

static int fr_bio_mem_call_verify ( fr_bio_t bio,
void *  packet_ctx,
size_t size 
)
static

Verify that a packet is OK.

Todo:
  • have this as a parameter to the read routines, so that they only return complete packets?
Parameters
biothe fr_bio_mem_t
packet_ctxthe packet ctx
[out]sizehow big the verified packet is
Returns
  • <0 for FR_BIO_VERIFY_ERROR_CLOSE, the caller should close the bio.
  • 0 for "we have a partial packet", the size to read is in *size
  • 1 for "we have at least one good packet", the size of it is in *size

Definition at line 623 of file mem.c.

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

◆ fr_bio_mem_eof()

static int fr_bio_mem_eof ( fr_bio_t bio)
static

Definition at line 77 of file mem.c.

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

◆ fr_bio_mem_read()

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

Read from a memory BIO.

This bio reads as much data as possible into the memory buffer. On the theory that a few memcpy() or memmove() calls are much cheaper than a system call.

If the read buffer has enough data to satisfy the read, then it is returned.

Otherwise the next bio is called to re-fill the buffer. The next read call will try to get as much data as possible into the buffer, even if that results in reading more than "size" bytes.

Once the next read has been done, then the data from the buffer is returned, even if it is less than "size".

Definition at line 106 of file mem.c.

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

◆ fr_bio_mem_read_buffer()

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

Read from a buffer which a previous bio has filled.

This function is called by the application which wants to read from a sink.

Definition at line 807 of file mem.c.

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

◆ fr_bio_mem_read_discard()

void fr_bio_mem_read_discard ( fr_bio_t bio,
size_t  size 
)

Discard data from the read buffer.

Discarding allows the caller to silently omit packets, so that they are not passed up to previous bios.

Definition at line 604 of file mem.c.

+ Here is the call graph for this function:

◆ fr_bio_mem_read_eof()

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

At EOF, read data from the buffer until it is empty.

When "next" bio returns EOF, there may still be pending data in the memory buffer. Return that until it's empty, and then EOF from then on.

Definition at line 54 of file mem.c.

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

◆ fr_bio_mem_read_peek()

uint8_t const* fr_bio_mem_read_peek ( fr_bio_t bio,
size_t size 
)

Peek at the data in the read buffer.

Peeking at the data allows us to avoid many memory copies.

Definition at line 586 of file mem.c.

+ Here is the call graph for this function:

◆ fr_bio_mem_read_verify()

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

Return data only if we have a complete packet.

Definition at line 167 of file mem.c.

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

◆ fr_bio_mem_read_verify_datagram()

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

Return data only if we have a complete packet.

Definition at line 295 of file mem.c.

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

◆ fr_bio_mem_set_verify()

int fr_bio_mem_set_verify ( fr_bio_t bio,
fr_bio_verify_t  verify,
void *  verify_ctx,
bool  datagram 
)

Set the verification function for memory bios.

It is possible to add a verification function. It is not currently possible to remove one.

Parameters
biothe binary IO handler
verifythe verification function
datagramwhether or not this bio is a datagram one.
Returns
  • <0 on error
  • 0 on success

Definition at line 880 of file mem.c.

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

◆ fr_bio_mem_shutdown()

static void fr_bio_mem_shutdown ( fr_bio_t bio)
static

Definition at line 684 of file mem.c.

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

◆ fr_bio_mem_sink_alloc()

fr_bio_t* fr_bio_mem_sink_alloc ( TALLOC_CTX *  ctx,
size_t  read_size 
)

Allocate a memory buffer which sinks data from a bio system into the callers application.

The caller reads data from this bio, but never writes to it. Upstream BIOs will source the data.

Definition at line 845 of file mem.c.

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

◆ fr_bio_mem_source_alloc()

fr_bio_t* fr_bio_mem_source_alloc ( TALLOC_CTX *  ctx,
size_t  write_size,
fr_bio_t next 
)

Allocate a memory buffer which sources data from the callers application into the bio system.

The caller writes data to the buffer, but never reads from it. This bio will call the "next" bio to sink the data.

Definition at line 772 of file mem.c.

+ Here is the call graph for this function:

◆ fr_bio_mem_write_buffer() [1/2]

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

Write to the memory 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 527 of file mem.c.

+ Here is the call graph for this function:

◆ fr_bio_mem_write_buffer() [2/2]

static ssize_t fr_bio_mem_write_buffer ( fr_bio_t bio,
void *  packet_ctx,
void const *  buffer,
size_t  size 
)
static
+ Here is the caller graph for this function:

◆ fr_bio_mem_write_flush()

static ssize_t fr_bio_mem_write_flush ( fr_bio_mem_t my,
size_t  size 
)
static

Flush the memory buffer.

Definition at line 460 of file mem.c.

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

◆ fr_bio_mem_write_next()

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

Pass writes to the next BIO.

For speed, we try to bypass the memory buffer and write directly to the next bio. However, if the next bio returns EWOULDBLOCK, we write the data to the memory buffer, even if it is partial data.

Definition at line 370 of file mem.c.

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

◆ fr_bio_mem_write_read_buffer()

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

Write to the read buffer.

This function is called by an upstream function which writes into our local buffer.

Definition at line 818 of file mem.c.

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

◆ fr_bio_mem_write_resume()

int fr_bio_mem_write_resume ( fr_bio_t bio)

See if we can resume writes to the memory bio.

Note that there is no equivalent fr_bio_mem_write_blocked(), as that function wouldn't do anything. Perhaps it could swap the write function to fr_bio_mem_write_buffer(), but the fr_bio_mem_write_next() function should automatically do that when the write to the next bio only writes part of the data, or if it returns fr_bio_error(IO_WOULD_BLOCK)

Definition at line 926 of file mem.c.

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