The FreeRADIUS server
$Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
Simple state machine for managing connection states. More...
#include <freeradius-devel/server/connection.h>
#include <freeradius-devel/server/log.h>
#include <freeradius-devel/server/trigger.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/event.h>
#include <freeradius-devel/util/talloc.h>
#include <freeradius-devel/util/syserror.h>
#include <freeradius-devel/util/log.h>
#include <freeradius-devel/util/stdatomic.h>
Go to the source code of this file.
Data Structures | |
struct | connection_dsignal_entry_t |
Holds a signal from a handler until it's safe to process it. More... | |
struct | connection_s |
struct | connection_watch_entry_s |
An entry in a watch function list. More... | |
Macros | |
#define | _CONNECTION_PRIVATE 1 |
#define | BAD_STATE_TRANSITION(_new) |
#define | CONN_TRIGGER(_state) |
#define | DEFER_SIGNALS(_conn) ((_conn)->in_handler || (_conn)->signals_pause) |
#define | HANDLER_BEGIN(_conn, _func) |
Called when we enter a handler. More... | |
#define | HANDLER_END(_conn) |
Called when we exit a handler. More... | |
#define | LOG_PREFIX conn->pub.name |
#define | STATE_TRANSITION(_new) |
#define | WATCH_POST(_conn) |
Call the post handler watch functions. More... | |
#define | WATCH_PRE(_conn) |
Call the pre handler watch functions. More... | |
Typedefs | |
typedef struct connection_s | connection_t |
typedef struct connection_watch_entry_s | connection_watch_entry_t |
An entry in a watch function list. More... | |
Enumerations | |
enum | connection_dsignal_t { CONNECTION_DSIGNAL_INIT , CONNECTION_DSIGNAL_CONNECTED , CONNECTION_DSIGNAL_RECONNECT_FAILED , CONNECTION_DSIGNAL_RECONNECT_EXPIRED , CONNECTION_DSIGNAL_SHUTDOWN , CONNECTION_DSIGNAL_HALT , CONNECTION_DSIGNAL_FREE } |
Deferred signals. More... | |
Functions | |
static void | _connection_error (UNUSED fr_event_list_t *el, int fd, UNUSED int flags, int fd_errno, void *uctx) |
Receive an error notification when we're connecting a socket. More... | |
static int | _connection_free (connection_t *conn) |
Close a connection if it's freed. More... | |
static void | _connection_signal_on_fd_cleanup (connection_t *conn, UNUSED connection_state_t prev, connection_state_t state, void *uctx) |
Remove the FD we were watching for connection open/fail from the event loop. More... | |
static void | _connection_timeout (UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx) |
Connection timeout. More... | |
static void | _connection_writable (fr_event_list_t *el, int fd, UNUSED int flags, void *uctx) |
Receive a write notification after a socket is connected. More... | |
static void | _deferred_signal_connection_on_halted (UNUSED connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx) |
Notification function to tell connection_deferred_signal_process that the connection has been freed. More... | |
static void | _reconnect_delay_done (UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx) |
The requisite period of time has passed, try and re-open the connection. More... | |
CC_NO_UBSAN (function) | |
Call a list of watch functions associated with a state. More... | |
static connection_watch_entry_t * | connection_add_watch (connection_t *conn, fr_dlist_head_t *list, connection_watch_t watch, bool oneshot, void const *uctx) |
Add a watch entry to the pre/post[state] list. More... | |
connection_watch_entry_t * | connection_add_watch_post (connection_t *conn, connection_state_t state, connection_watch_t watch, bool oneshot, void const *uctx) |
Add a callback to be executed after a state function has been called. More... | |
connection_watch_entry_t * | connection_add_watch_pre (connection_t *conn, connection_state_t state, connection_watch_t watch, bool oneshot, void const *uctx) |
Add a callback to be executed before a state function has been called. More... | |
connection_t * | connection_alloc (TALLOC_CTX *ctx, fr_event_list_t *el, connection_funcs_t const *funcs, connection_conf_t const *conf, char const *log_prefix, void const *uctx) |
Allocate a new connection. More... | |
static void | connection_deferred_signal_add (connection_t *conn, connection_dsignal_t signal) |
Add a deferred signal to the signal list. More... | |
static void | connection_deferred_signal_process (connection_t *conn) |
Process any deferred signals. More... | |
static int | connection_del_watch (connection_t *conn, fr_dlist_head_t *state_lists, connection_state_t state, connection_watch_t watch) |
Remove a watch function from a pre/post[state] list. More... | |
int | connection_del_watch_post (connection_t *conn, connection_state_t state, connection_watch_t watch) |
Remove a watch function from a post list. More... | |
int | connection_del_watch_pre (connection_t *conn, connection_state_t state, connection_watch_t watch) |
Remove a watch function from a pre list. More... | |
uint64_t | connection_get_num_reconnected (connection_t const *conn) |
Return the number of times we've attempted to establish or re-establish this connection. More... | |
uint64_t | connection_get_num_timed_out (connection_t const *conn) |
Return the number of times this connection has timed out whilst connecting. More... | |
void | connection_signal_connected (connection_t *conn) |
Asynchronously signal that the connection is open. More... | |
void | connection_signal_halt (connection_t *conn) |
Shuts down a connection ungracefully. More... | |
void | connection_signal_init (connection_t *conn) |
Asynchronously signal a halted connection to start. More... | |
int | connection_signal_on_fd (connection_t *conn, int fd) |
Setup the connection to change states to connected or failed based on I/O events. More... | |
void | connection_signal_reconnect (connection_t *conn, connection_reason_t reason) |
Asynchronously signal the connection should be reconnected. More... | |
void | connection_signal_shutdown (connection_t *conn) |
Shuts down a connection gracefully. More... | |
void | connection_signals_pause (connection_t *conn) |
Pause processing of deferred signals. More... | |
void | connection_signals_resume (connection_t *conn) |
Resume processing of deferred signals. More... | |
static void | connection_state_enter_closed (connection_t *conn) |
Close the connection, then wait for another state change. More... | |
static void | connection_state_enter_connected (connection_t *conn) |
Enter the connected state. More... | |
static void | connection_state_enter_connecting (connection_t *conn) |
Enter the connecting state. More... | |
static void | connection_state_enter_failed (connection_t *conn) |
Connection failed. More... | |
static void | connection_state_enter_halted (connection_t *conn) |
Enter the halted state. More... | |
static void | connection_state_enter_init (connection_t *conn) |
Initial state of the connection. More... | |
static void | connection_state_enter_shutdown (connection_t *conn) |
Gracefully shutdown the handle. More... | |
static void | connection_state_enter_timeout (connection_t *conn) |
Enter the timeout state. More... | |
void | connection_watch_disable (connection_watch_entry_t *entry) |
Disable a watcher. More... | |
void | connection_watch_enable (connection_watch_entry_t *entry) |
Enable a watcher. More... | |
void | connection_watch_enable_set_uctx (connection_watch_entry_t *entry, void const *uctx) |
Enable a watcher and replace the uctx. More... | |
bool | connection_watch_is_enabled (connection_watch_entry_t *entry) |
Return the state of a watch entry. More... | |
void | connection_watch_set_uctx (connection_watch_entry_t *entry, void const *uctx) |
Change the uctx of an entry. More... | |
Variables | |
static atomic_uint_fast64_t | connection_counter = ATOMIC_VAR_INIT(1) |
static fr_table_num_ordered_t const | connection_dsignals [] |
static size_t | connection_dsignals_len = NUM_ELEMENTS(connection_dsignals) |
fr_table_num_ordered_t const | connection_states [] |
size_t | connection_states_len = NUM_ELEMENTS(connection_states) |
static fr_table_num_indexed_t const | connection_trigger_names [] |
Map connection states to trigger names. More... | |
static size_t | connection_trigger_names_len = NUM_ELEMENTS(connection_trigger_names) |
Simple state machine for managing connection states.
Definition in file connection.c.
struct connection_dsignal_entry_t |
Holds a signal from a handler until it's safe to process it.
Definition at line 180 of file connection.c.
Data Fields | ||
---|---|---|
fr_dlist_t | entry | Entry in the signals list. |
connection_dsignal_t | signal | Signal that was deferred. |
struct connection_s |
Definition at line 87 of file connection.c.
Data Fields | ||
---|---|---|
connection_close_t | close | Callback to close a connection. |
fr_time_delta_t | connection_timeout | How long to wait in the CONNECTION_STATE_CONNECTING state. |
fr_dlist_head_t | deferred_signals | A list of signals we received whilst we were in a handler. |
fr_event_timer_t const * | ev | State transition timer. |
connection_failed_t | failed | Callback for 'failed' notification. |
void * | in_handler | Connection is currently in a callback. |
connection_init_t | init | Callback for initialising a connection. |
bool | is_closed | The close callback has previously been called. |
connection_watch_entry_t * | next_watcher | Hack to insulate watcher iterator from deletions. |
connection_watch_entry_t * | on_halted | Used by the deferred signal processor to learn if a function deeper in the call stack freed the connection. |
connection_open_t | open | Callback for 'open' notification. |
bool | processing_signals | Processing deferred signals, don't let the deferred signal processor be called multiple times. |
struct connection_pub_s | pub | Public fields. |
fr_time_delta_t | reconnection_delay | How long to wait in the CONNECTION_STATE_FAILED state. |
connection_shutdown_t | shutdown | Signal the connection handle to start shutting down. |
unsigned int | signals_pause | Temporarily stop processing of signals. |
void * | uctx | User data. |
fr_dlist_head_t | watch_post[CONNECTION_STATE_MAX] | Function called after state callback. |
fr_dlist_head_t | watch_pre[CONNECTION_STATE_MAX] | Function called before state callback. |
struct connection_watch_entry_s |
An entry in a watch function list.
Definition at line 78 of file connection.c.
Data Fields | ||
---|---|---|
bool | enabled | Whether the watch entry is enabled. |
fr_dlist_t | entry | List entry. |
connection_watch_t | func | Function to call when a connection enters the state this list belongs to. |
bool | oneshot | Remove the function after it's called once. |
void * | uctx | User data to pass to the function. |
#define _CONNECTION_PRIVATE 1 |
Definition at line 28 of file connection.c.
#define BAD_STATE_TRANSITION | ( | _new | ) |
Definition at line 143 of file connection.c.
#define CONN_TRIGGER | ( | _state | ) |
Definition at line 126 of file connection.c.
#define DEFER_SIGNALS | ( | _conn | ) | ((_conn)->in_handler || (_conn)->signals_pause) |
Definition at line 151 of file connection.c.
#define HANDLER_BEGIN | ( | _conn, | |
_func | |||
) |
Called when we enter a handler.
Definition at line 337 of file connection.c.
#define HANDLER_END | ( | _conn | ) |
Called when we exit a handler.
Definition at line 346 of file connection.c.
Definition at line 25 of file connection.c.
#define STATE_TRANSITION | ( | _new | ) |
Definition at line 133 of file connection.c.
#define WATCH_POST | ( | _conn | ) |
Call the post handler watch functions.
Definition at line 406 of file connection.c.
#define WATCH_PRE | ( | _conn | ) |
Call the pre handler watch functions.
Definition at line 393 of file connection.c.
typedef struct connection_s connection_t |
Definition at line 1 of file connection.c.
typedef struct connection_watch_entry_s connection_watch_entry_t |
An entry in a watch function list.
enum connection_dsignal_t |
Deferred signals.
Definition at line 156 of file connection.c.
|
static |
Receive an error notification when we're connecting a socket.
[in] | el | event list the I/O event occurred on. |
[in] | fd | the I/O even occurred for. |
[in] | flags | from_kevent. |
[in] | fd_errno | from kevent. |
[in] | uctx | The connection_t this fd is associated with. |
Definition at line 1343 of file connection.c.
|
static |
Close a connection if it's freed.
[in] | conn | to free. |
Definition at line 1451 of file connection.c.
|
static |
Remove the FD we were watching for connection open/fail from the event loop.
Definition at line 1369 of file connection.c.
|
static |
Connection timeout.
Connection wasn't opened within the configured period of time
[in] | el | the time event occurred on. |
[in] | now | The current time. |
[in] | uctx | The connection_t the fd is associated with. |
Definition at line 693 of file connection.c.
|
static |
Receive a write notification after a socket is connected.
[in] | el | event list the I/O event occurred on. |
[in] | fd | the I/O even occurred for. |
[in] | flags | from kevent. |
[in] | uctx | The connection_t this fd is associated with. |
Definition at line 1358 of file connection.c.
|
static |
Notification function to tell connection_deferred_signal_process that the connection has been freed.
Definition at line 226 of file connection.c.
|
static |
The requisite period of time has passed, try and re-open the connection.
[in] | el | the time event occurred on. |
[in] | now | The current time. |
[in] | uctx | The connection_t the fd is associated with. |
Definition at line 624 of file connection.c.
CC_NO_UBSAN | ( | function | ) |
Call a list of watch functions associated with a state.
Definition at line 356 of file connection.c.
|
static |
Add a watch entry to the pre/post[state] list.
Definition at line 482 of file connection.c.
connection_watch_entry_t* connection_add_watch_post | ( | connection_t * | conn, |
connection_state_t | state, | ||
connection_watch_t | watch, | ||
bool | oneshot, | ||
void const * | uctx | ||
) |
Add a callback to be executed after a state function has been called.
Where a user callback is executed on state change, the post function is only called if the callback succeeds.
[in] | conn | to add watcher to. |
[in] | state | to call watcher on entering. |
[in] | watch | function to call. |
[in] | oneshot | If true, remove the function after calling. |
[in] | uctx | to pass to callbacks. |
Definition at line 532 of file connection.c.
connection_watch_entry_t* connection_add_watch_pre | ( | connection_t * | conn, |
connection_state_t | state, | ||
connection_watch_t | watch, | ||
bool | oneshot, | ||
void const * | uctx | ||
) |
Add a callback to be executed before a state function has been called.
[in] | conn | to add watcher to. |
[in] | state | to call watcher on entering. |
[in] | watch | function to call. |
[in] | oneshot | If true, remove the function after calling. |
[in] | uctx | to pass to callbacks. |
Definition at line 510 of file connection.c.
connection_t* connection_alloc | ( | TALLOC_CTX * | ctx, |
fr_event_list_t * | el, | ||
connection_funcs_t const * | funcs, | ||
connection_conf_t const * | conf, | ||
char const * | log_prefix, | ||
void const * | uctx | ||
) |
Allocate a new connection.
After the connection has been allocated, it should be started with a call to connection_signal_init.
The connection state machine can detect when the connection is open in one of two ways.
[in] | ctx | to allocate connection handle in. If the connection handle is freed, and the connection_state_t is CONNECTION_STATE_CONNECTING or CONNECTION_STATE_CONNECTED the close callback will be called. |
[in] | el | to use for timer events, and to pass to the connection_open_t callback. |
[in] | funcs | callback functions. |
[in] | conf | our configuration. |
[in] | log_prefix | To prepend to log messages. |
[in] | uctx | User context to pass to callbacks. |
Definition at line 1512 of file connection.c.
|
inlinestatic |
Add a deferred signal to the signal list.
Processing signals whilst in handlers usually leads to weird inconsistent states within the connection.
If a public signal function is called, and detects its being called from within the handler, it instead adds a deferred signal entry and immediately returns.
Once the handler is complete, and all pending C stack state changes are complete, the deferred signals are drained and processed.
Definition at line 209 of file connection.c.
|
static |
Process any deferred signals.
Definition at line 237 of file connection.c.
|
static |
Remove a watch function from a pre/post[state] list.
Definition at line 419 of file connection.c.
int connection_del_watch_post | ( | connection_t * | conn, |
connection_state_t | state, | ||
connection_watch_t | watch | ||
) |
Remove a watch function from a post list.
[in] | conn | The connection to remove the watcher from. |
[in] | state | to remove the watch from. |
[in] | watch | Function to remove. |
Definition at line 472 of file connection.c.
int connection_del_watch_pre | ( | connection_t * | conn, |
connection_state_t | state, | ||
connection_watch_t | watch | ||
) |
Remove a watch function from a pre list.
[in] | conn | The connection to remove the watcher from. |
[in] | state | to remove the watch from. |
[in] | watch | Function to remove. |
Definition at line 455 of file connection.c.
uint64_t connection_get_num_reconnected | ( | connection_t const * | conn | ) |
Return the number of times we've attempted to establish or re-establish this connection.
[in] | conn | to get count from. |
Definition at line 601 of file connection.c.
uint64_t connection_get_num_timed_out | ( | connection_t const * | conn | ) |
Return the number of times this connection has timed out whilst connecting.
[in] | conn | to get count from. |
Definition at line 613 of file connection.c.
void connection_signal_connected | ( | connection_t * | conn | ) |
Asynchronously signal that the connection is open.
Some libraries like libldap are extremely annoying and only return control to the caller after a connection is open.
For these libraries, we can't use an I/O handler to determine when the connection is open so we rely on callbacks built into the library to signal that the transition has occurred.
Definition at line 1137 of file connection.c.
void connection_signal_halt | ( | connection_t * | conn | ) |
Shuts down a connection ungracefully.
If a connection is in an open or connection state it will be closed immediately. Otherwise the connection will transition directly to the halted state.
[in] | conn | to halt. |
Definition at line 1291 of file connection.c.
void connection_signal_init | ( | connection_t * | conn | ) |
Asynchronously signal a halted connection to start.
Definition at line 1107 of file connection.c.
int connection_signal_on_fd | ( | connection_t * | conn, |
int | fd | ||
) |
Setup the connection to change states to connected or failed based on I/O events.
Will automatically cleanup after itself, in preparation for new I/O handlers to be installed in the open() callback.
Definition at line 1405 of file connection.c.
void connection_signal_reconnect | ( | connection_t * | conn, |
connection_reason_t | reason | ||
) |
Asynchronously signal the connection should be reconnected.
Should be called if the caller has knowledge that the connection is bad and should be reconnected.
[in] | conn | to reconnect. |
[in] | reason | Why the connection was signalled to reconnect. |
Definition at line 1167 of file connection.c.
void connection_signal_shutdown | ( | connection_t * | conn | ) |
Shuts down a connection gracefully.
If a shutdown function has been provided, it is called. It's then up to the shutdown function to install I/O handlers to signal when the connection has finished shutting down and should be closed via connection_signal_halt.
[in] | conn | to shutdown. |
Definition at line 1228 of file connection.c.
void connection_signals_pause | ( | connection_t * | conn | ) |
Pause processing of deferred signals.
[in] | conn | to pause signal processing for. |
Definition at line 310 of file connection.c.
void connection_signals_resume | ( | connection_t * | conn | ) |
Resume processing of deferred signals.
[in] | conn | to resume signal processing for. |
Definition at line 319 of file connection.c.
|
static |
Close the connection, then wait for another state change.
Definition at line 643 of file connection.c.
|
static |
Enter the connected state.
The connection is now fully connected. At this point we call the open callback so that the API client can install its normal set of I/O callbacks to deal with sending/receiving actual data.
After this, the connection will only transition states if an API client explicitly calls connection_signal_reconnect.
The connection API cannot monitor the connection for failure conditions.
[in] | conn | Entering the connecting state. |
Definition at line 947 of file connection.c.
|
static |
Enter the connecting state.
After this function returns we wait to be signalled with connection_singal_connected or for the connection timer to expire.
[in] | conn | Entering the connecting state. |
Definition at line 993 of file connection.c.
|
static |
Connection failed.
Transition to the CONNECTION_STATE_FAILED state.
If the connection was open, or couldn't be opened wait for reconnection_delay before transitioning back to init.
If no reconnection_delay was set, transition to halted.
[in] | conn | that failed. |
Definition at line 767 of file connection.c.
|
static |
Enter the halted state.
Here we wait, until signalled by connection_signal_reconnect.
Definition at line 914 of file connection.c.
|
static |
Initial state of the connection.
Calls the init function we were passed to allocate a library specific handle or file descriptor.
[in] | conn | To initialise. |
Definition at line 1040 of file connection.c.
|
static |
Gracefully shutdown the handle.
Definition at line 703 of file connection.c.
|
static |
Enter the timeout state.
The connection took took long to open. Timeout the attempt and transition to the failed state.
Definition at line 890 of file connection.c.
void connection_watch_disable | ( | connection_watch_entry_t * | entry | ) |
Disable a watcher.
[in] | entry | to disable. |
Definition at line 554 of file connection.c.
void connection_watch_enable | ( | connection_watch_entry_t * | entry | ) |
void connection_watch_enable_set_uctx | ( | connection_watch_entry_t * | entry, |
void const * | uctx | ||
) |
Enable a watcher and replace the uctx.
[in] | entry | to enabled. |
[in] | uctx | Opaque data to pass to the callback. |
Definition at line 565 of file connection.c.
bool connection_watch_is_enabled | ( | connection_watch_entry_t * | entry | ) |
Return the state of a watch entry.
[in] | entry | to return state of. |
Definition at line 590 of file connection.c.
void connection_watch_set_uctx | ( | connection_watch_entry_t * | entry, |
void const * | uctx | ||
) |
Change the uctx of an entry.
[in] | entry | to enabled. |
[in] | uctx | Opaque data to pass to the callback. |
Definition at line 577 of file connection.c.
|
static |
Definition at line 73 of file connection.c.
|
static |
Definition at line 166 of file connection.c.
|
static |
Definition at line 175 of file connection.c.
fr_table_num_ordered_t const connection_states[] |
Definition at line 46 of file connection.c.
size_t connection_states_len = NUM_ELEMENTS(connection_states) |
Definition at line 56 of file connection.c.
|
static |
Map connection states to trigger names.
Definition at line 61 of file connection.c.
|
static |
Definition at line 71 of file connection.c.