The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
Multi-packet state handling. More...
#include <freeradius-devel/server/request.h>
#include <freeradius-devel/server/request_data.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>
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.__unnamed71__ |
union | fr_state_entry_t.__unnamed73__ |
struct | fr_state_tree_s |
struct | state_child_entry_t |
A child of a fr_state_entry_t. More... | |
struct | state_comp.__unnamed71__.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. | |
static int | _state_entry_free (fr_state_entry_t *entry) |
Frees any data associated with a state. | |
static int | _state_tree_free (fr_state_tree_t *state) |
Free the state tree. | |
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. | |
void | fr_state_discard (fr_state_tree_t *state, request_t *request) |
Called when sending an Access-Accept/Access-Reject to discard state information. | |
void | fr_state_discard_child (request_t *parent, void const *unique_ptr, int unique_int) |
Remove state from a child. | |
uint64_t | fr_state_entries_created (fr_state_tree_t *state) |
Return number of entries created. | |
uint64_t | fr_state_entries_timeout (fr_state_tree_t *state) |
Return number of entries that timed out. | |
uint64_t | fr_state_entries_tracked (fr_state_tree_t *state) |
Return number of entries we're currently tracking. | |
void | fr_state_restore_to_child (request_t *child, void const *unique_ptr, int unique_int) |
Restore subrequest data from a parent request. | |
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. | |
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. | |
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. | |
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. | |
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) |
Create a new state entry. | |
static fr_state_entry_t * | state_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. | |
static void | state_entry_unlink (fr_state_tree_t *state, fr_state_entry_t *entry) |
Unlink an entry and remove if from the tree. | |
Multi-packet state handling.
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.
struct fr_state_entry_t |
Data Fields | ||
---|---|---|
union fr_state_entry_t.__unnamed71__ | __unnamed__ | |
union fr_state_entry_t.__unnamed73__ | __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 |
union fr_state_entry_t.__unnamed71__ |
Data Fields | ||
---|---|---|
uint8_t | state[sizeof(struct state_comp)] | State value in binary. |
struct state_comp.__unnamed71__.state_comp | state_comp |
union fr_state_entry_t.__unnamed73__ |
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. |
struct 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. |
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.
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. |
struct fr_state_entry_t::state_comp.__unnamed71__.state_comp |
Server ID components.
State values should be unique to a given server
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. |
#define PTHREAD_MUTEX_LOCK if (state->thread_safe) pthread_mutex_lock |
#define PTHREAD_MUTEX_UNLOCK if (state->thread_safe) pthread_mutex_unlock |
|
static |
|
static |
|
static |
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.
void fr_state_discard | ( | fr_state_tree_t * | state, |
request_t * | request | ||
) |
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.
[in] | parent | Holding the child's state. |
[in] | unique_ptr | A parent may have multiple subrequests spawned by different modules. This identifies the module or other facility that spawned the subrequest. |
[in] | unique_int | Further identification. |
Definition at line 908 of file state.c.
uint64_t fr_state_entries_created | ( | fr_state_tree_t * | state | ) |
uint64_t fr_state_entries_timeout | ( | fr_state_tree_t * | state | ) |
uint64_t fr_state_entries_tracked | ( | fr_state_tree_t * | state | ) |
void fr_state_restore_to_child | ( | request_t * | child, |
void const * | unique_ptr, | ||
int | unique_int | ||
) |
Restore subrequest data from a parent request.
[in] | child | The child request to restore state to. |
[in] | unique_ptr | A parent may have multiple subrequests spawned by different modules. This identifies the module or other facility that spawned the subrequest. |
[in] | unique_int | Further identification. |
Definition at line 858 of file state.c.
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.
[in] | child | The child request to retrieve state from. |
[in] | unique_ptr | A parent may have multiple subrequests spawned by different modules. This identifies the module or other facility that spawned the subrequest. |
[in] | unique_int | Further identification. |
Definition at line 812 of file state.c.
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.
[in] | state | tree to lookup state in. |
[in] | request | to restore state for. |
Definition at line 660 of file state.c.
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.
[in] | ctx | to link the lifecycle of the state tree to. |
[in] | da | Attribute used to store and retrieve state from. |
[in] | thread_safe | Whether we should mutex protect the state tree. |
[in] | max_sessions | we track state for. |
[in] | timeout | How long to wait before cleaning up entries. |
[in] | server_id | ID byte to use in load-balancing operations. |
[in] | context_id | Specifies a unique ctx id to prevent states being used in contexts for which they weren't intended. |
Definition at line 222 of file state.c.
|
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.
|
static |
|
static |
|
inlinestatic |