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

Multi-packet state handling. More...

#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/request.h>
#include <freeradius-devel/server/state.h>
#include <freeradius-devel/io/listen.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/dlist.h>
#include <freeradius-devel/util/md5.h>
#include <freeradius-devel/util/misc.h>
#include <freeradius-devel/util/rand.h>
+ Include dependency graph for state.c:

Go to the source code of this file.

Data Structures

struct  fr_state_entry_t
 Holds a state value, and associated fr_pair_ts and data. More...
 
union  fr_state_entry_t.__unnamed69__
 
union  fr_state_entry_t.__unnamed71__
 
struct  fr_state_tree_s
 
struct  state_child_entry_t
 A child of a fr_state_entry_t. More...
 
struct  state_comp.__unnamed69__.state_comp
 Server ID components. More...
 

Macros

#define PTHREAD_MUTEX_LOCK   if (state->thread_safe) pthread_mutex_lock
 
#define PTHREAD_MUTEX_UNLOCK   if (state->thread_safe) pthread_mutex_unlock
 

Functions

static int _free_child_data (state_child_entry_t *child_entry)
 Free any subrequest request data if the dlist head is freed. More...
 
static int _state_entry_free (fr_state_entry_t *entry)
 Frees any data associated with a state. More...
 
static int _state_tree_free (fr_state_tree_t *state)
 Free the state tree. More...
 
int fr_request_to_state (fr_state_tree_t *state, request_t *request)
 Transfer ownership of the state fr_pair_ts and ctx, back to a state entry. More...
 
void fr_state_discard (fr_state_tree_t *state, request_t *request)
 Called when sending an Access-Accept/Access-Reject to discard state information. More...
 
void fr_state_discard_child (request_t *parent, void const *unique_ptr, int unique_int)
 Remove state from a child. More...
 
uint64_t fr_state_entries_created (fr_state_tree_t *state)
 Return number of entries created. More...
 
uint64_t fr_state_entries_timeout (fr_state_tree_t *state)
 Return number of entries that timed out. More...
 
uint64_t fr_state_entries_tracked (fr_state_tree_t *state)
 Return number of entries we're currently tracking. More...
 
void fr_state_restore_to_child (request_t *child, void const *unique_ptr, int unique_int)
 Restore subrequest data from a parent request. More...
 
void fr_state_store_in_parent (request_t *child, void const *unique_ptr, int unique_int)
 Store subrequest's session-state list and persistable request data in its parent. More...
 
int fr_state_to_request (fr_state_tree_t *state, request_t *request)
 Copy a pointer to the head of the list of state fr_pair_ts (and their ctx) into the request. More...
 
fr_state_tree_tfr_state_tree_init (TALLOC_CTX *ctx, fr_dict_attr_t const *da, bool thread_safe, uint32_t max_sessions, fr_time_delta_t timeout, uint8_t server_id, uint32_t context_id)
 Initialise a new state tree. More...
 
static int8_t state_entry_cmp (void const *one, void const *two)
 Compare two fr_state_entry_t based on their state value i.e. More...
 
static fr_state_entry_tstate_entry_create (fr_state_tree_t *state, request_t *request, fr_pair_list_t *reply_list, fr_state_entry_t *old)
 Create a new state entry. More...
 
static fr_state_entry_tstate_entry_find_and_unlink (fr_state_tree_t *state, fr_value_box_t const *vb)
 Find the entry based on the State attribute and remove it from the state tree. More...
 
static void state_entry_unlink (fr_state_tree_t *state, fr_state_entry_t *entry)
 Unlink an entry and remove if from the tree. More...
 

Detailed Description

Multi-packet state handling.

Id
0b11a910d2bfd5743448d32b56b771ec0b378974

For each round of a multi-round authentication method such as EAP, or a 2FA method such as OTP, a state entry will be created. The state entry holds data that should be available during the complete lifecycle of the authentication attempt.

When a request is complete, fr_request_to_state is called to transfer ownership of the state fr_pair_ts and state_ctx (which the fr_pair_ts are allocated in) to a fr_state_entry_t. This fr_state_entry_t holds the value of the State attribute, that will be send out in the response.

When the next request is received, fr_state_to_request is called to transfer the fr_pair_ts and state ctx to the new request.

The ownership of the state_ctx and state fr_pair_ts is transferred as below:

  request -> state_entry -> request -> state_entry -> request -> free()
         \-> reply                 \-> reply                 \-> access-reject/access-accept
* 

Definition in file state.c.


Data Structure Documentation

◆ fr_state_entry_t

struct fr_state_entry_t

Holds a state value, and associated fr_pair_ts and data.

Definition at line 64 of file state.c.

+ Collaboration diagram for fr_state_entry_t:
Data Fields
union fr_state_entry_t __unnamed__
union fr_state_entry_t __unnamed__
fr_time_t cleanup When this entry should be cleaned up.
fr_pair_t * ctx for all session specific data.
fr_dlist_head_t data Persistable request data, also parented by ctx.
uint64_t id State number within state heap.
fr_rb_node_t node Entry in the state rbtree.
uint64_t seq_start Number of first request in this sequence.
fr_state_tree_t * state_tree Tree this entry belongs to.
request_t * thawed The request that thawed this entry.
int tries

◆ fr_state_entry_t.__unnamed69__

union fr_state_entry_t.__unnamed69__

Definition at line 67 of file state.c.

Data Fields
uint8_t state[sizeof(struct state_comp)] State value in binary.
__unnamed69__ state_comp

◆ fr_state_entry_t.__unnamed71__

union fr_state_entry_t.__unnamed71__

Definition at line 110 of file state.c.

Data Fields
fr_dlist_t expire_entry Entry in the list of things to expire.
fr_dlist_t free_entry Entry in the list of things to free.

◆ fr_state_tree_s

struct fr_state_tree_s

Definition at line 145 of file state.c.

+ Collaboration diagram for fr_state_tree_s:
Data Fields
uint32_t context_id ID binding state values to a context such as a virtual server.
fr_dict_attr_t const * da State attribute used.
uint64_t id Next ID to assign.
uint32_t max_sessions Maximum number of sessions we track.
pthread_mutex_t mutex Synchronisation mutex.
uint8_t server_id ID to use for load balancing.
bool thread_safe Whether we lock the tree whilst modifying it.
uint64_t timed_out Number of states that were cleaned up due to timeout.
fr_time_delta_t timeout How long to wait before cleaning up state entries.
fr_dlist_head_t to_expire Linked list of entries to free.
fr_rb_tree_t * tree rbtree used to lookup state value.
uint32_t used_sessions How many sessions are currently in progress.

◆ state_child_entry_t

struct state_child_entry_t

A child of a fr_state_entry_t.

Children are tracked using the request data of parents.

request data is added with identifiers that uniquely identify the subrequest it should be restored to.

In this way a top level fr_state_entry_t can hold the session information for multiple children, and the children may hold state_child_entry_ts for grandchildren.

Definition at line 137 of file state.c.

+ Collaboration diagram for state_child_entry_t:
Data Fields
fr_pair_t * ctx for all session specific data.
fr_dlist_head_t data Persistable request data, also parented by ctx.
request_t * thawed The request that thawed this entry.

◆ fr_state_entry_t::state_comp.__unnamed69__.state_comp

struct fr_state_entry_t::state_comp.__unnamed69__.state_comp

Server ID components.

State values should be unique to a given server

Definition at line 72 of file state.c.

Data Fields
uint32_t context_id Hash of the current virtual server, xor'd with r1, r2, r3, r4 after the original state value is sent, but before the state entry is inserted into the tree.

The receiving virtual server xor's its hash with the received state before performing the lookup. This means one virtual server can't act on a state entry generated by another, even though the state tree is global to all virtual servers.

uint8_t r_0 Random component.
uint8_t r_5 Random component.
uint8_t r_6 Random component.
uint8_t r_8 Random component.
uint8_t r_9 Random component.
uint8_t server_id Configured server ID.

Used for debugging to locate authentication sessions originating from a particular backend authentication server.

uint8_t tries Number of rounds so far in this state sequence.
uint8_t tx Bits changed in the tries counter for this round.
uint8_t vx_0 Random component.
uint8_t vx_1 Random component.
uint8_t vx_2 Random component.
uint8_t vx_3 Random component.

Macro Definition Documentation

◆ PTHREAD_MUTEX_LOCK

#define PTHREAD_MUTEX_LOCK   if (state->thread_safe) pthread_mutex_lock

Definition at line 166 of file state.c.

◆ PTHREAD_MUTEX_UNLOCK

#define PTHREAD_MUTEX_UNLOCK   if (state->thread_safe) pthread_mutex_unlock

Definition at line 167 of file state.c.

Function Documentation

◆ _free_child_data()

static int _free_child_data ( state_child_entry_t child_entry)
static

Free any subrequest request data if the dlist head is freed.

Definition at line 796 of file state.c.

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

◆ _state_entry_free()

static int _state_entry_free ( fr_state_entry_t entry)
static

Frees any data associated with a state.

Definition at line 291 of file state.c.

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

◆ _state_tree_free()

static int _state_tree_free ( fr_state_tree_t state)
static

Free the state tree.

Definition at line 186 of file state.c.

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

◆ fr_request_to_state()

int fr_request_to_state ( fr_state_tree_t state,
request_t request 
)

Transfer ownership of the state fr_pair_ts and ctx, back to a state entry.

Put request->session_state_pairs into the State attribute. Put the State attribute into the vps list. Delete the original entry, if it exists

Also creates a new state entry.

Definition at line 737 of file state.c.

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

◆ fr_state_discard()

void fr_state_discard ( fr_state_tree_t state,
request_t request 
)

Called when sending an Access-Accept/Access-Reject to discard state information.

Definition at line 606 of file state.c.

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

◆ fr_state_discard_child()

void fr_state_discard_child ( request_t parent,
void const *  unique_ptr,
int  unique_int 
)

Remove state from a child.

This is useful for modules like EAP, where we keep a persistent eap_session but may call multiple EAP method modules during negotiation, and need to discard the state between each module call.

Parameters
[in]parentHolding the child's state.
[in]unique_ptrA parent may have multiple subrequests spawned by different modules. This identifies the module or other facility that spawned the subrequest.
[in]unique_intFurther identification.

Definition at line 908 of file state.c.

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

◆ fr_state_entries_created()

uint64_t fr_state_entries_created ( fr_state_tree_t state)

Return number of entries created.

Definition at line 925 of file state.c.

◆ fr_state_entries_timeout()

uint64_t fr_state_entries_timeout ( fr_state_tree_t state)

Return number of entries that timed out.

Definition at line 933 of file state.c.

◆ fr_state_entries_tracked()

uint64_t fr_state_entries_tracked ( fr_state_tree_t state)

Return number of entries we're currently tracking.

Definition at line 941 of file state.c.

+ Here is the call graph for this function:

◆ fr_state_restore_to_child()

void fr_state_restore_to_child ( request_t child,
void const *  unique_ptr,
int  unique_int 
)

Restore subrequest data from a parent request.

Parameters
[in]childThe child request to restore state to.
[in]unique_ptrA parent may have multiple subrequests spawned by different modules. This identifies the module or other facility that spawned the subrequest.
[in]unique_intFurther identification.

Definition at line 858 of file state.c.

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

◆ fr_state_store_in_parent()

void fr_state_store_in_parent ( request_t child,
void const *  unique_ptr,
int  unique_int 
)

Store subrequest's session-state list and persistable request data in its parent.

Parameters
[in]childThe child request to retrieve state from.
[in]unique_ptrA parent may have multiple subrequests spawned by different modules. This identifies the module or other facility that spawned the subrequest.
[in]unique_intFurther identification.

Definition at line 812 of file state.c.

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

◆ fr_state_to_request()

int fr_state_to_request ( fr_state_tree_t state,
request_t request 
)

Copy a pointer to the head of the list of state fr_pair_ts (and their ctx) into the request.

Note
Does not copy the actual fr_pair_ts. The fr_pair_ts and their context are transferred between state entries as the conversation progresses.
Called with the mutex free.
Parameters
[in]statetree to lookup state in.
[in]requestto restore state for.
Returns
  • 2 if the state attribute didn't match any known states.
  • 1 if no state attribute existed.
  • 0 on success (state restored)
  • -1 if a state entry has already been thawed by a another request.

Definition at line 660 of file state.c.

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

◆ fr_state_tree_init()

fr_state_tree_t* fr_state_tree_init ( TALLOC_CTX *  ctx,
fr_dict_attr_t const *  da,
bool  thread_safe,
uint32_t  max_sessions,
fr_time_delta_t  timeout,
uint8_t  server_id,
uint32_t  context_id 
)

Initialise a new state tree.

Parameters
[in]ctxto link the lifecycle of the state tree to.
[in]daAttribute used to store and retrieve state from.
[in]thread_safeWhether we should mutex protect the state tree.
[in]max_sessionswe track state for.
[in]timeoutHow long to wait before cleaning up entries.
[in]server_idID byte to use in load-balancing operations.
[in]context_idSpecifies a unique ctx id to prevent states being used in contexts for which they weren't intended.
Returns
  • A new state tree.
  • NULL on failure.

Definition at line 222 of file state.c.

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

◆ state_entry_cmp()

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

Compare two fr_state_entry_t based on their state value i.e.

the value of the attribute

Definition at line 174 of file state.c.

+ Here is the caller graph for this function:

◆ state_entry_create()

static fr_state_entry_t* state_entry_create ( fr_state_tree_t state,
request_t request,
fr_pair_list_t reply_list,
fr_state_entry_t old 
)
static

Create a new state entry.

Note
Called with the mutex held.

Definition at line 332 of file state.c.

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

◆ state_entry_find_and_unlink()

static fr_state_entry_t* state_entry_find_and_unlink ( fr_state_tree_t state,
fr_value_box_t const *  vb 
)
static

Find the entry based on the State attribute and remove it from the state tree.

Definition at line 563 of file state.c.

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

◆ state_entry_unlink()

static void state_entry_unlink ( fr_state_tree_t state,
fr_state_entry_t entry 
)
inlinestatic

Unlink an entry and remove if from the tree.

Definition at line 275 of file state.c.

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