The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
Macros | Functions | Variables
bio_retry_tests.c File Reference

Tests for the retry bio running out of entries. More...

#include <freeradius-devel/util/test/acutest_common_init.h>
#include <freeradius-devel/util/test/acutest_helpers.h>
#include <freeradius-devel/bio/bio_priv.h>
#include <freeradius-devel/bio/null.h>
#include <freeradius-devel/bio/retry.h>
+ Include dependency graph for bio_retry_tests.c:

Go to the source code of this file.

Macros

#define _BIO_PRIVATE   1
 

Functions

static int cb_noop (fr_bio_t *bio)
 
static void cb_noop_void (fr_bio_t *bio)
 
static int cb_write_blocked (fr_bio_t *bio)
 
static int cb_write_resume (fr_bio_t *bio)
 
static void retry_release (UNUSED fr_bio_t *bio, UNUSED fr_bio_retry_entry_t *retry_ctx, UNUSED fr_bio_retry_release_reason_t reason)
 
static bool retry_response (UNUSED fr_bio_t *bio, UNUSED fr_bio_retry_entry_t **item_p, UNUSED void *packet_ctx, UNUSED const void *buffer, UNUSED size_t size)
 
static void retry_sent (UNUSED fr_bio_t *bio, UNUSED void *packet_ctx, UNUSED const void *buffer, UNUSED size_t size, fr_bio_retry_entry_t *retry_ctx)
 
static fr_bio_t * stub_alloc (TALLOC_CTX *ctx)
 
static ssize_t stub_write_all (UNUSED fr_bio_t *bio, UNUSED void *packet_ctx, void const *buffer, size_t size)
 A transport which accepts every write in full, and never has anything to read.
 
static ssize_t stub_write_one (UNUSED fr_bio_t *bio, UNUSED void *packet_ctx, void const *buffer, UNUSED size_t size)
 A transport which accepts one byte of each write, so the retry bio saves the rest of the packet.
 
static void test_all_used_resumes (void)
 Running out of entries blocks writes, and freeing an entry resumes writes.
 
static void test_block_expires_overdue (void)
 Blocking writes expires an overdue entry, and the expiry sees writes as blocked.
 
static void test_block_stops_retries (void)
 When one retransmission blocks writes, the other retransmissions due in the same pass wait.
 
static void test_partial_oom_releases (void)
 When the retry bio cannot save the rest of a partly written packet, the retry bio releases the entry of the packet.
 
static void test_partial_retransmit (void)
 The retry bio saves the rest of a partly written retransmission once, and a flush sends the rest once.
 
static void test_resume_can_write (void)
 The application may write from inside the resume callback, so fr_bio_retry_release() must put the freed entry on the free list before calling the resume callback.
 
static fr_bio_t * test_retry_alloc (TALLOC_CTX *ctx, fr_bio_retry_config_t *cfg)
 
static fr_bio_t * test_retry_alloc_full (TALLOC_CTX *ctx, fr_bio_retry_config_t *cfg, fr_time_delta_t mrd, size_t max_saved)
 Allocate a retry bio with one entry, in front of a stub.
 
static fr_bio_t * test_retry_alloc_mrd (TALLOC_CTX *ctx, fr_bio_retry_config_t *cfg, fr_time_delta_t mrd)
 

Variables

static int blocked_count
 
static uint8_t packet1 [4] = { 1, 2, 3, 4 }
 
static uint8_t packet2 [4] = { 5, 6, 7, 8 }
 
static int release_count
 
static int resume_count
 
static fr_bio_t * resume_write_bio
 when set, cb_write_resume() writes packet2 to this bio
 
static ssize_t resume_write_rcode
 
static fr_bio_retry_entry_t * saved_item
 
static size_t stub_bytes
 bytes of packet data which the stub has accepted
 
static fr_bio_cb_funcs_t test_cb
 
 TEST_LIST
 

Detailed Description

Tests for the retry bio running out of entries.

Definition in file bio_retry_tests.c.

Macro Definition Documentation

◆ _BIO_PRIVATE

#define _BIO_PRIVATE   1

Definition at line 26 of file bio_retry_tests.c.

Function Documentation

◆ cb_noop()

static int cb_noop ( fr_bio_t *  bio)
static

Definition at line 42 of file bio_retry_tests.c.

◆ cb_noop_void()

static void cb_noop_void ( fr_bio_t *  bio)
static

Definition at line 43 of file bio_retry_tests.c.

◆ cb_write_blocked()

static int cb_write_blocked ( fr_bio_t *  bio)
static

Definition at line 44 of file bio_retry_tests.c.

◆ cb_write_resume()

static int cb_write_resume ( fr_bio_t *  bio)
static

Definition at line 46 of file bio_retry_tests.c.

+ Here is the call graph for this function:

◆ retry_release()

static void retry_release ( UNUSED fr_bio_t *  bio,
UNUSED fr_bio_retry_entry_t *  retry_ctx,
UNUSED fr_bio_retry_release_reason_t  reason 
)
static

Definition at line 76 of file bio_retry_tests.c.

+ Here is the caller graph for this function:

◆ retry_response()

static bool retry_response ( UNUSED fr_bio_t *  bio,
UNUSED fr_bio_retry_entry_t **  item_p,
UNUSED void *  packet_ctx,
UNUSED const void *  buffer,
UNUSED size_t  size 
)
static

Definition at line 70 of file bio_retry_tests.c.

+ Here is the caller graph for this function:

◆ retry_sent()

static void retry_sent ( UNUSED fr_bio_t *  bio,
UNUSED void *  packet_ctx,
UNUSED const void *  buffer,
UNUSED size_t  size,
fr_bio_retry_entry_t *  retry_ctx 
)
static

Definition at line 64 of file bio_retry_tests.c.

+ Here is the caller graph for this function:

◆ stub_alloc()

static fr_bio_t * stub_alloc ( TALLOC_CTX *  ctx)
static

Definition at line 104 of file bio_retry_tests.c.

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

◆ stub_write_all()

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

A transport which accepts every write in full, and never has anything to read.

Definition at line 86 of file bio_retry_tests.c.

+ Here is the caller graph for this function:

◆ stub_write_one()

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

A transport which accepts one byte of each write, so the retry bio saves the rest of the packet.

Definition at line 96 of file bio_retry_tests.c.

+ Here is the caller graph for this function:

◆ test_all_used_resumes()

static void test_all_used_resumes ( void  )
static

Running out of entries blocks writes, and freeing an entry resumes writes.

See finding 1 in retry.md. Only fr_bio_retry_write_resume() clears write_blocked, and fr_bio_retry_write_resume() runs only when the socket becomes writable. If running out of entries set write_blocked, then the application would never resume writes.

Definition at line 168 of file bio_retry_tests.c.

+ Here is the call graph for this function:

◆ test_block_expires_overdue()

static void test_block_expires_overdue ( void  )
static

Blocking writes expires an overdue entry, and the expiry sees writes as blocked.

See finding 1 in retry.md. Arming the expiry list runs any expiry which is already due, and fr_bio_retry_expiry_timer() asserts that writes are blocked. fr_bio_retry_write_blocked() used to set the flag only after arming the list.

Definition at line 322 of file bio_retry_tests.c.

+ Here is the call graph for this function:

◆ test_block_stops_retries()

static void test_block_stops_retries ( void  )
static

When one retransmission blocks writes, the other retransmissions due in the same pass wait.

See finding 1 in retry.md. fr_bio_retry_write_blocked() disarms the retry list, and the timer list used to keep running the other entries which were due in the same pass.

Definition at line 370 of file bio_retry_tests.c.

+ Here is the call graph for this function:

◆ test_partial_oom_releases()

static void test_partial_oom_releases ( void  )
static

When the retry bio cannot save the rest of a partly written packet, the retry bio releases the entry of the packet.

See 'A related defect: a failed save kept the entry' in retry.md. Without the release, the entry stays on both timer lists after the sent() callback has passed the entry to the application. The write returns OOM, so an application which then frees the packet leaves the retry bio holding a pointer to freed memory.

Definition at line 281 of file bio_retry_tests.c.

+ Here is the call graph for this function:

◆ test_partial_retransmit()

static void test_partial_retransmit ( void  )
static

The retry bio saves the rest of a partly written retransmission once, and a flush sends the rest once.

See finding 2 in retry.md. Before the fix, fr_bio_retry_rewrite() saved the rest of the packet, and then fr_bio_retry_write_item() saved the rest of the packet again.

Definition at line 237 of file bio_retry_tests.c.

+ Here is the call graph for this function:

◆ test_resume_can_write()

static void test_resume_can_write ( void  )
static

The application may write from inside the resume callback, so fr_bio_retry_release() must put the freed entry on the free list before calling the resume callback.

Definition at line 205 of file bio_retry_tests.c.

+ Here is the call graph for this function:

◆ test_retry_alloc()

static fr_bio_t * test_retry_alloc ( TALLOC_CTX *  ctx,
fr_bio_retry_config_t *  cfg 
)
static

Definition at line 157 of file bio_retry_tests.c.

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

◆ test_retry_alloc_full()

static fr_bio_t * test_retry_alloc_full ( TALLOC_CTX *  ctx,
fr_bio_retry_config_t *  cfg,
fr_time_delta_t  mrd,
size_t  max_saved 
)
static

Allocate a retry bio with one entry, in front of a stub.

Only test_partial_retransmit() runs the timer list, so no timer fires in the other tests.

Definition at line 121 of file bio_retry_tests.c.

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

◆ test_retry_alloc_mrd()

static fr_bio_t * test_retry_alloc_mrd ( TALLOC_CTX *  ctx,
fr_bio_retry_config_t *  cfg,
fr_time_delta_t  mrd 
)
static

Definition at line 152 of file bio_retry_tests.c.

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

Variable Documentation

◆ blocked_count

int blocked_count
static

Definition at line 31 of file bio_retry_tests.c.

◆ packet1

uint8_t packet1[4] = { 1, 2, 3, 4 }
static

Definition at line 39 of file bio_retry_tests.c.

◆ packet2

uint8_t packet2[4] = { 5, 6, 7, 8 }
static

Definition at line 40 of file bio_retry_tests.c.

◆ release_count

int release_count
static

Definition at line 33 of file bio_retry_tests.c.

◆ resume_count

int resume_count
static

Definition at line 32 of file bio_retry_tests.c.

◆ resume_write_bio

fr_bio_t* resume_write_bio
static

when set, cb_write_resume() writes packet2 to this bio

Definition at line 36 of file bio_retry_tests.c.

◆ resume_write_rcode

ssize_t resume_write_rcode
static

Definition at line 37 of file bio_retry_tests.c.

◆ saved_item

fr_bio_retry_entry_t* saved_item
static

Definition at line 34 of file bio_retry_tests.c.

◆ stub_bytes

size_t stub_bytes
static

bytes of packet data which the stub has accepted

Definition at line 82 of file bio_retry_tests.c.

◆ test_cb

fr_bio_cb_funcs_t test_cb
static
Initial value:
= {
.read_resume = cb_noop,
.write_resume = cb_write_resume,
.read_blocked = cb_noop,
.write_blocked = cb_write_blocked,
.eof = cb_noop_void,
}
static int cb_write_blocked(fr_bio_t *bio)
static int cb_write_resume(fr_bio_t *bio)
static void cb_noop_void(fr_bio_t *bio)
static int cb_noop(fr_bio_t *bio)

Definition at line 56 of file bio_retry_tests.c.

◆ TEST_LIST

TEST_LIST
Initial value:
= {
{ "all_used_resumes", test_all_used_resumes },
{ "resume_can_write", test_resume_can_write },
{ "partial_retransmit", test_partial_retransmit },
{ "partial_oom_releases", test_partial_oom_releases },
{ "block_expires_overdue", test_block_expires_overdue },
{ "block_stops_retries", test_block_stops_retries },
}
#define TEST_TERMINATOR
Definition acutest.h:77
static void test_partial_oom_releases(void)
When the retry bio cannot save the rest of a partly written packet, the retry bio releases the entry ...
static void test_resume_can_write(void)
The application may write from inside the resume callback, so fr_bio_retry_release() must put the fre...
static void test_partial_retransmit(void)
The retry bio saves the rest of a partly written retransmission once, and a flush sends the rest once...
static void test_block_expires_overdue(void)
Blocking writes expires an overdue entry, and the expiry sees writes as blocked.
static void test_block_stops_retries(void)
When one retransmission blocks writes, the other retransmissions due in the same pass wait.
static void test_all_used_resumes(void)
Running out of entries blocks writes, and freeing an entry resumes writes.

Definition at line 401 of file bio_retry_tests.c.