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 | fr_connection_s |
struct | fr_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 fr_connection_s | fr_connection_t |
typedef struct fr_connection_watch_entry_s | fr_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 (fr_connection_t *conn) |
Close a connection if it's freed. More... | |
static void | _connection_signal_on_fd_cleanup (fr_connection_t *conn, UNUSED fr_connection_state_t prev, fr_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 fr_connection_t *conn, UNUSED fr_connection_state_t prev, UNUSED fr_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... | |
static fr_connection_watch_entry_t * | connection_add_watch (fr_connection_t *conn, fr_dlist_head_t *list, fr_connection_watch_t watch, bool oneshot, void const *uctx) |
Add a watch entry to the pre/post[state] list. More... | |
static void | connection_deferred_signal_add (fr_connection_t *conn, connection_dsignal_t signal) |
Add a deferred signal to the signal list. More... | |
static void | connection_deferred_signal_process (fr_connection_t *conn) |
Process any deferred signals. More... | |
static int | connection_del_watch (fr_connection_t *conn, fr_dlist_head_t *state_lists, fr_connection_state_t state, fr_connection_watch_t watch) |
Remove a watch function from a pre/post[state] list. More... | |
static void | connection_state_enter_closed (fr_connection_t *conn) |
Close the connection, then wait for another state change. More... | |
static void | connection_state_enter_connected (fr_connection_t *conn) |
Enter the connected state. More... | |
static void | connection_state_enter_connecting (fr_connection_t *conn) |
Enter the connecting state. More... | |
static void | connection_state_enter_failed (fr_connection_t *conn) |
Connection failed. More... | |
static void | connection_state_enter_halted (fr_connection_t *conn) |
Enter the halted state. More... | |
static void | connection_state_enter_init (fr_connection_t *conn) |
Initial state of the connection. More... | |
static void | connection_state_enter_shutdown (fr_connection_t *conn) |
Gracefully shutdown the handle. More... | |
static void | connection_state_enter_timeout (fr_connection_t *conn) |
Enter the timeout state. More... | |
static void | connection_watch_call (fr_connection_t *conn, fr_dlist_head_t *list) |
Call a list of watch functions associated with a state. More... | |
fr_connection_watch_entry_t * | fr_connection_add_watch_post (fr_connection_t *conn, fr_connection_state_t state, fr_connection_watch_t watch, bool oneshot, void const *uctx) |
Add a callback to be executed after a state function has been called. More... | |
fr_connection_watch_entry_t * | fr_connection_add_watch_pre (fr_connection_t *conn, fr_connection_state_t state, fr_connection_watch_t watch, bool oneshot, void const *uctx) |
Add a callback to be executed before a state function has been called. More... | |
fr_connection_t * | fr_connection_alloc (TALLOC_CTX *ctx, fr_event_list_t *el, fr_connection_funcs_t const *funcs, fr_connection_conf_t const *conf, char const *log_prefix, void const *uctx) |
Allocate a new connection. More... | |
int | fr_connection_del_watch_post (fr_connection_t *conn, fr_connection_state_t state, fr_connection_watch_t watch) |
Remove a watch function from a post list. More... | |
int | fr_connection_del_watch_pre (fr_connection_t *conn, fr_connection_state_t state, fr_connection_watch_t watch) |
Remove a watch function from a pre list. More... | |
uint64_t | fr_connection_get_num_reconnected (fr_connection_t const *conn) |
Return the number of times we've attempted to establish or re-establish this connection. More... | |
uint64_t | fr_connection_get_num_timed_out (fr_connection_t const *conn) |
Return the number of times this connection has timed out whilst connecting. More... | |
void | fr_connection_signal_connected (fr_connection_t *conn) |
Asynchronously signal that the connection is open. More... | |
void | fr_connection_signal_halt (fr_connection_t *conn) |
Shuts down a connection ungracefully. More... | |
void | fr_connection_signal_init (fr_connection_t *conn) |
Asynchronously signal a halted connection to start. More... | |
int | fr_connection_signal_on_fd (fr_connection_t *conn, int fd) |
Setup the connection to change states to connected or failed based on I/O events. More... | |
void | fr_connection_signal_reconnect (fr_connection_t *conn, fr_connection_reason_t reason) |
Asynchronously signal the connection should be reconnected. More... | |
void | fr_connection_signal_shutdown (fr_connection_t *conn) |
Shuts down a connection gracefully. More... | |
void | fr_connection_signals_pause (fr_connection_t *conn) |
Pause processing of deferred signals. More... | |
void | fr_connection_signals_resume (fr_connection_t *conn) |
Resume processing of deferred signals. More... | |
void | fr_connection_watch_disable (fr_connection_watch_entry_t *entry) |
Disable a watcher. More... | |
void | fr_connection_watch_enable (fr_connection_watch_entry_t *entry) |
Enable a watcher. More... | |
void | fr_connection_watch_enable_set_uctx (fr_connection_watch_entry_t *entry, void const *uctx) |
Enable a watcher and replace the uctx. More... | |
bool | fr_connection_watch_is_enabled (fr_connection_watch_entry_t *entry) |
Return the state of a watch entry. More... | |
void | fr_connection_watch_set_uctx (fr_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 | fr_connection_states [] |
size_t | fr_connection_states_len = NUM_ELEMENTS(fr_connection_states) |
static fr_table_num_indexed_t const | fr_connection_trigger_names [] |
Map connection states to trigger names. More... | |
static size_t | fr_connection_trigger_names_len = NUM_ELEMENTS(fr_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 fr_connection_s |
Definition at line 87 of file connection.c.
Data Fields | ||
---|---|---|
fr_connection_close_t | close | Callback to close a connection. |
fr_time_delta_t | connection_timeout | How long to wait in the FR_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. |
fr_connection_failed_t | failed | Callback for 'failed' notification. |
void * | in_handler | Connection is currently in a callback. |
fr_connection_init_t | init | Callback for initialising a connection. |
bool | is_closed | The close callback has previously been called. |
fr_connection_watch_entry_t * | next_watcher | Hack to insulate watcher iterator from deletions. |
fr_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. |
fr_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 fr_connection_pub_s | pub | Public fields. |
fr_time_delta_t | reconnection_delay | How long to wait in the FR_CONNECTION_STATE_FAILED state. |
fr_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[FR_CONNECTION_STATE_MAX] | Function called after state callback. |
fr_dlist_head_t | watch_pre[FR_CONNECTION_STATE_MAX] | Function called before state callback. |
struct fr_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. |
fr_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 405 of file connection.c.
#define WATCH_PRE | ( | _conn | ) |
Call the pre handler watch functions.
Definition at line 392 of file connection.c.
typedef struct fr_connection_s fr_connection_t |
Definition at line 1 of file connection.c.
typedef struct fr_connection_watch_entry_s fr_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 fr_connection_t this fd is associated with. |
Definition at line 1338 of file connection.c.
|
static |
Close a connection if it's freed.
[in] | conn | to free. |
Definition at line 1446 of file connection.c.
|
static |
Remove the FD we were watching for connection open/fail from the event loop.
Definition at line 1364 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 fr_connection_t the fd is associated with. |
Definition at line 692 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 fr_connection_t this fd is associated with. |
Definition at line 1353 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 fr_connection_t the fd is associated with. |
Definition at line 623 of file connection.c.
|
static |
Add a watch entry to the pre/post[state] list.
Definition at line 481 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 418 of file connection.c.
|
static |
Close the connection, then wait for another state change.
Definition at line 642 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 fr_connection_signal_reconnect.
The connection API cannot monitor the connection for failure conditions.
[in] | conn | Entering the connecting state. |
Definition at line 946 of file connection.c.
|
static |
Enter the connecting state.
After this function returns we wait to be signalled with fr_connection_singal_connected or for the connection timer to expire.
[in] | conn | Entering the connecting state. |
Definition at line 992 of file connection.c.
|
static |
Connection failed.
Transition to the FR_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 766 of file connection.c.
|
static |
Enter the halted state.
Here we wait, until signalled by fr_connection_signal_reconnect.
Definition at line 913 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 1039 of file connection.c.
|
static |
Gracefully shutdown the handle.
Definition at line 702 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 889 of file connection.c.
|
inlinestatic |
Call a list of watch functions associated with a state.
Definition at line 356 of file connection.c.
fr_connection_watch_entry_t* fr_connection_add_watch_post | ( | fr_connection_t * | conn, |
fr_connection_state_t | state, | ||
fr_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 531 of file connection.c.
fr_connection_watch_entry_t* fr_connection_add_watch_pre | ( | fr_connection_t * | conn, |
fr_connection_state_t | state, | ||
fr_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 509 of file connection.c.
fr_connection_t* fr_connection_alloc | ( | TALLOC_CTX * | ctx, |
fr_event_list_t * | el, | ||
fr_connection_funcs_t const * | funcs, | ||
fr_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 fr_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 fr_connection_state_t is FR_CONNECTION_STATE_CONNECTING or FR_CONNECTION_STATE_CONNECTED the close callback will be called. |
[in] | el | to use for timer events, and to pass to the fr_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 1507 of file connection.c.
int fr_connection_del_watch_post | ( | fr_connection_t * | conn, |
fr_connection_state_t | state, | ||
fr_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 471 of file connection.c.
int fr_connection_del_watch_pre | ( | fr_connection_t * | conn, |
fr_connection_state_t | state, | ||
fr_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 454 of file connection.c.
uint64_t fr_connection_get_num_reconnected | ( | fr_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 600 of file connection.c.
uint64_t fr_connection_get_num_timed_out | ( | fr_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 612 of file connection.c.
void fr_connection_signal_connected | ( | fr_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 1136 of file connection.c.
void fr_connection_signal_halt | ( | fr_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 1290 of file connection.c.
void fr_connection_signal_init | ( | fr_connection_t * | conn | ) |
Asynchronously signal a halted connection to start.
Definition at line 1106 of file connection.c.
int fr_connection_signal_on_fd | ( | fr_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 1400 of file connection.c.
void fr_connection_signal_reconnect | ( | fr_connection_t * | conn, |
fr_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 1166 of file connection.c.
void fr_connection_signal_shutdown | ( | fr_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 fr_connection_signal_halt.
[in] | conn | to shutdown. |
Definition at line 1227 of file connection.c.
void fr_connection_signals_pause | ( | fr_connection_t * | conn | ) |
Pause processing of deferred signals.
[in] | conn | to pause signal processing for. |
Definition at line 310 of file connection.c.
void fr_connection_signals_resume | ( | fr_connection_t * | conn | ) |
Resume processing of deferred signals.
[in] | conn | to resume signal processing for. |
Definition at line 319 of file connection.c.
void fr_connection_watch_disable | ( | fr_connection_watch_entry_t * | entry | ) |
Disable a watcher.
[in] | entry | to disable. |
Definition at line 553 of file connection.c.
void fr_connection_watch_enable | ( | fr_connection_watch_entry_t * | entry | ) |
void fr_connection_watch_enable_set_uctx | ( | fr_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 564 of file connection.c.
bool fr_connection_watch_is_enabled | ( | fr_connection_watch_entry_t * | entry | ) |
Return the state of a watch entry.
[in] | entry | to return state of. |
Definition at line 589 of file connection.c.
void fr_connection_watch_set_uctx | ( | fr_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 576 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 fr_connection_states[] |
Definition at line 46 of file connection.c.
size_t fr_connection_states_len = NUM_ELEMENTS(fr_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.