The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
connection.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or (at
6 * your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/**
19 * $Id: cd913ddb55a5986b96d7a133d771214740804267 $
20 * @file lib/server/connection.h
21 * @brief Simple state machine for managing connection states.
22 *
23 * @copyright 2017-2020 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 */
25RCSIDH(connection_h, "$Id: cd913ddb55a5986b96d7a133d771214740804267 $")
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include <freeradius-devel/util/event.h>
32#include <freeradius-devel/util/table.h>
33#include <freeradius-devel/util/talloc.h>
34#include <freeradius-devel/util/pair.h>
35#include <freeradius-devel/server/cf_util.h>
36
37#ifdef _CONST
38# error _CONST can only be defined in the local header
39#endif
40#ifndef _CONNECTION_PRIVATE
41typedef struct connection_pub_s connection_t; /* We use the private version of the connection_t */
42# define _CONST const
43#else
44# define _CONST
45#endif
46
47typedef enum {
48 CONNECTION_STATE_HALTED = 0, //!< The connection is in a halted stat. It does not have
49 ///< a valid file descriptor, and it will not try and
50 ///< and create one.
51 CONNECTION_STATE_INIT, //!< Init state, sets up connection.
52 CONNECTION_STATE_CONNECTING, //!< Waiting for connection to establish.
53 CONNECTION_STATE_TIMEOUT, //!< Timeout during #CONNECTION_STATE_CONNECTING.
54 CONNECTION_STATE_CONNECTED, //!< File descriptor is open (ready for writing).
55 CONNECTION_STATE_SHUTDOWN, //!< Connection is shutting down.
56 CONNECTION_STATE_FAILED, //!< Connection has failed.
57 CONNECTION_STATE_CLOSED, //!< Connection has been closed.
60
61/** Public fields for the connection
62 *
63 * This saves the overhead of using accessors for commonly used fields in
64 * connections.
65 *
66 * Though these fields are public, they should _NOT_ be modified by clients of
67 * the connection API.
68 */
70 char const * _CONST name; //!< Prefix to add to log messages.
71
72 connection_state_t _CONST state; //!< Current connection state.
73 connection_state_t _CONST prev; //!< The previous state the connection was in.
74 uint64_t _CONST id; //!< Unique identifier for the connection.
75 void * _CONST h; //!< Connection handle
76 fr_event_list_t * _CONST el; //!< Event list for timers and I/O events.
77
78 uint64_t _CONST reconnected; //!< How many times we've attempted to establish or
79 ///< re-establish this connection.
80 uint64_t _CONST timed_out; //!< How many times has this connection timed out when
81 ///< connecting.
82};
83
84typedef enum {
85 CONNECTION_FAILED = 0, //!< Connection is being reconnected because it failed.
86 CONNECTION_EXPIRED //!< Connection is being reconnected because it's at
87 ///< the end of its life. In this case we enter the
88 ///< closing state and try and close the connection
89 ///< gracefully.
91
92typedef struct {
93 fr_time_delta_t connection_timeout; //!< How long to wait for the connection to open
94 //!< or for shutdown to close the connection.
95 fr_time_delta_t reconnection_delay; //!< How long to wait after failures.
96
97 CONF_SECTION *trigger_cs; //!< Local configuration section we also search for triggers in.
98 ///< Lifetime must be longer than the connection.
99
100 fr_pair_list_t *trigger_args; //!< Additional pairs to pass to the trigger function
101 ///< Lifetime must be longer than the connection.
103
105
107extern size_t connection_states_len;
108
109/** Callback for the initialise state
110 *
111 * Should attempt to open a non-blocking connection and return it in fd_out.
112 *
113 * @param[out] h_out Where to write the new handle.
114 * @param[in] conn If integrating with a 3rd party library
115 * that will trigger connection API state transitions,
116 * the connection should be passed as the uctx argument
117 * for library I/O callbacks.
118 * @param[in] uctx User context.
119 * @return
120 * - #CONNECTION_STATE_CONNECTING if a handle was successfully created.
121 * - #CONNECTION_STATE_FAILED if we could not create a handle.
122 */
123typedef connection_state_t (*connection_init_t)(void **h_out, connection_t *conn, void *uctx);
124
125/** Notification that the connection is now open
126 *
127 * This should be used to add any additional I/O events for the file descriptor
128 * to call other code if it becomes readable or writable.
129 *
130 * @param[in] el to use for inserting I/O events.
131 * @param[in] h Handle that was successfully opened.
132 * @param[in] uctx User context.
133 * @return
134 * - #CONNECTION_STATE_CONNECTED if the handle is usable.
135 * - #CONNECTION_STATE_FAILED if the handle is unusable.
136 */
138
139/** Start the process of gracefully shutting down the connection
140 *
141 * This function is called when the connection is signalled to gracefully
142 * disconnect. It should place the connection in a state where pending
143 * I/O operations complete, and buffers are flushed.
144 *
145 * After all pending events are complete, the connection should be signalled
146 * that the handle is in the closed state.
147 *
148 * @param[in] el to use for inserting I/O events.
149 * @param[in] h Handle that needs to be closed.
150 * @param[in] uctx User context.
151 * @return
152 * - #CONNECTION_STATE_SHUTDOWN if the handle has shutdown.
153 * - #CONNECTION_STATE_FAILED if the handle is unusable, and we
154 * should just transition directly to failed.
155 */
157
158/** Notification that a connection attempt has failed
159 *
160 * @note If the callback frees the connection, it must return #CONNECTION_STATE_HALTED.
161 *
162 * @param[in] h Handle that failed.
163 * @param[in] state the connection was in when it failed. Usually one of:
164 * - #CONNECTION_STATE_CONNECTING the connection attempt explicitly failed.
165 * - #CONNECTION_STATE_CONNECTED something called #connection_signal_reconnect.
166 * - #CONNECTION_STATE_TIMEOUT the connection attempt timed out.
167 * @param[in] uctx User context.
168 * @return
169 * - #CONNECTION_STATE_INIT to transition to the init state.
170 * - #CONNECTION_STATE_HALTED To prevent further reconnection
171 * attempts Can be restarted with
172 * #connection_signal_init().
173 */
175
176/** Notification that the connection has errored and must be closed
177 *
178 * This should be used to close the file descriptor. It is assumed
179 * that the file descriptor is invalid after this callback has been executed.
180 *
181 * If this callback does not close the file descriptor, the server will leak
182 * file descriptors.
183 *
184 * @param[in] el to use for inserting I/O events.
185 * @param[in] h Handle to close.
186 * @param[in] uctx User context.
187 */
188typedef void (*connection_close_t)(fr_event_list_t *el, void *h, void *uctx);
189
190/** Holds a complete set of functions for a connection
191 *
192 */
200
201/** Receive a notification when a connection enters a particular state
202 *
203 * It is permitted for watchers to signal state changes, and/or to free the
204 * connection. The actual free will be deferred until the watcher returns.
205 *
206 * @param[in] conn Being watched.
207 * @param[in] prev State we came from.
208 * @param[in] state State that was entered (the current state)
209 * @param[in] uctx that was passed to connection_add_watch_*.
210 */
211typedef void(*connection_watch_t)(connection_t *conn,
212 connection_state_t prev, connection_state_t state, void *uctx);
213
214/** @name Add watcher functions that get called before (pre) the state callback and after (post)
215 * @{
216 */
218 connection_watch_t watch, bool oneshot, void const *uctx);
219
221 connection_watch_t watch, bool oneshot, void const *uctx);
222
224 connection_watch_t watch);
225
227 connection_watch_t watch);
228
230
232
234
235void connection_watch_set_uctx(connection_watch_entry_t *entry, void const *uctx);
236
238/** @} */
239
240/** @name Statistics
241 * @{
242 */
243uint64_t connection_get_num_reconnected(connection_t const *conn);
244
245uint64_t connection_get_num_timed_out(connection_t const *conn);
246/** @} */
247
248/** @name Signal the connection to change states
249 * @{
250 */
252
254
256
258
260
262
264/** @} */
265
266/** @name Install generic I/O events on an FD to signal state changes
267 * @{
268 */
269int connection_signal_on_fd(connection_t *conn, int fd);
270
272/** @} */
273
274/** @name Allocate a new connection
275 * @{
276 */
278 connection_funcs_t const *funcs, connection_conf_t const *conf,
279 char const *log_prefix, void const *uctx);
280/** @} */
281
282#undef _CONST
283
284#ifdef __cplusplus
285}
286#endif
#define RCSIDH(h, id)
Definition build.h:486
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
void connection_signal_shutdown(connection_t *conn)
Shuts down a connection gracefully.
void(* connection_watch_t)(connection_t *conn, connection_state_t prev, connection_state_t state, void *uctx)
Receive a notification when a connection enters a particular state.
Definition connection.h:211
CONF_SECTION * trigger_cs
Local configuration section we also search for triggers in.
Definition connection.h:97
void connection_watch_enable(connection_watch_entry_t *entry)
Enable a watcher.
Definition connection.c:545
connection_state_t(* connection_failed_t)(void *h, connection_state_t state, void *uctx)
Notification that a connection attempt has failed.
Definition connection.h:174
uint64_t connection_get_num_timed_out(connection_t const *conn)
Return the number of times this connection has timed out whilst connecting.
Definition connection.c:614
uint64_t _CONST timed_out
How many times has this connection timed out when connecting.
Definition connection.h:80
void connection_watch_disable(connection_watch_entry_t *entry)
Disable a watcher.
Definition connection.c:555
void(* connection_close_t)(fr_event_list_t *el, void *h, void *uctx)
Notification that the connection has errored and must be closed.
Definition connection.h:188
int connection_del_watch_post(connection_t *conn, connection_state_t state, connection_watch_t watch)
Remove a watch function from a post list.
Definition connection.c:473
fr_event_list_t *_CONST el
Event list for timers and I/O events.
Definition connection.h:76
connection_state_t(* connection_init_t)(void **h_out, connection_t *conn, void *uctx)
Callback for the initialise state.
Definition connection.h:123
bool connection_watch_is_enabled(connection_watch_entry_t *entry)
Return the state of a watch entry.
Definition connection.c:591
void connection_signal_halt(connection_t *conn)
Shuts down a connection ungracefully.
connection_state_t
Definition connection.h:47
@ CONNECTION_STATE_FAILED
Connection has failed.
Definition connection.h:56
@ CONNECTION_STATE_HALTED
The connection is in a halted stat.
Definition connection.h:48
@ CONNECTION_STATE_CLOSED
Connection has been closed.
Definition connection.h:57
@ CONNECTION_STATE_CONNECTED
File descriptor is open (ready for writing).
Definition connection.h:54
@ CONNECTION_STATE_TIMEOUT
Timeout during CONNECTION_STATE_CONNECTING.
Definition connection.h:53
@ CONNECTION_STATE_INIT
Init state, sets up connection.
Definition connection.h:51
@ CONNECTION_STATE_MAX
Definition connection.h:58
@ CONNECTION_STATE_CONNECTING
Waiting for connection to establish.
Definition connection.h:52
@ CONNECTION_STATE_SHUTDOWN
Connection is shutting down.
Definition connection.h:55
void connection_signals_resume(connection_t *conn)
Resume processing of deferred signals.
Definition connection.c:320
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.
Definition connection.c:602
uint64_t _CONST reconnected
How many times we've attempted to establish or re-establish this connection.
Definition connection.h:78
void *_CONST h
Connection handle.
Definition connection.h:75
connection_reason_t
Definition connection.h:84
@ CONNECTION_EXPIRED
Connection is being reconnected because it's at the end of its life.
Definition connection.h:86
@ CONNECTION_FAILED
Connection is being reconnected because it failed.
Definition connection.h:85
connection_state_t(* connection_open_t)(fr_event_list_t *el, void *h, void *uctx)
Notification that the connection is now open.
Definition connection.h:137
void connection_watch_set_uctx(connection_watch_entry_t *entry, void const *uctx)
Change the uctx of an entry.
Definition connection.c:578
connection_state_t _CONST state
Current connection state.
Definition connection.h:72
connection_init_t init
Definition connection.h:194
void connection_signal_reconnect(connection_t *conn, connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
#define _CONST
Definition connection.h:42
fr_pair_list_t * trigger_args
Additional pairs to pass to the trigger function Lifetime must be longer than the connection.
Definition connection.h:100
char const *_CONST name
Prefix to add to log messages.
Definition connection.h:70
connection_state_t _CONST prev
The previous state the connection was in.
Definition connection.h:73
fr_table_num_ordered_t const connection_states[]
Definition connection.c:46
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.
void connection_signal_init(connection_t *conn)
Asynchronously signal a halted connection to start.
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.
connection_shutdown_t shutdown
Definition connection.h:196
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.
Definition connection.c:511
connection_failed_t failed
Definition connection.h:197
size_t connection_states_len
Definition connection.c:56
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.
Definition connection.c:533
int connection_del_watch_pre(connection_t *conn, connection_state_t state, connection_watch_t watch)
Remove a watch function from a pre list.
Definition connection.c:456
fr_time_delta_t reconnection_delay
How long to wait after failures.
Definition connection.h:95
void connection_watch_enable_set_uctx(connection_watch_entry_t *entry, void const *uctx)
Enable a watcher and replace the uctx.
Definition connection.c:566
void connection_signal_connected(connection_t *conn)
Asynchronously signal that the connection is open.
connection_open_t open
Definition connection.h:195
void connection_signals_pause(connection_t *conn)
Pause processing of deferred signals.
Definition connection.c:311
fr_time_delta_t connection_timeout
How long to wait for the connection to open or for shutdown to close the connection.
Definition connection.h:93
uint64_t _CONST id
Unique identifier for the connection.
Definition connection.h:74
connection_close_t close
Definition connection.h:198
connection_state_t connection_failed_reinit(void *handle, connection_state_t state, void *uctx)
connection_state_t(* connection_shutdown_t)(fr_event_list_t *el, void *h, void *uctx)
Start the process of gracefully shutting down the connection.
Definition connection.h:156
Holds a complete set of functions for a connection.
Definition connection.h:193
Public fields for the connection.
Definition connection.h:69
Stores all information relating to an event list.
Definition event.c:377
static rs_t * conf
Definition radsniff.c:53
void * uctx
User data to pass to the function.
Definition connection.c:84
An entry in a watch function list.
Definition connection.c:78
An element in an arbitrarily ordered array of name to num mappings.
Definition table.h:57
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
static fr_event_list_t * el