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: 524f5d1ca431424c85351c91d0ea390f4a54e23f $
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: 524f5d1ca431424c85351c91d0ea390f4a54e23f $")
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
35#ifdef _CONST
36# error _CONST can only be defined in the local header
37#endif
38#ifndef _CONNECTION_PRIVATE
39typedef struct connection_pub_s connection_t; /* We use the private version of the connection_t */
40# define _CONST const
41#else
42# define _CONST
43#endif
44
45typedef enum {
46 CONNECTION_STATE_HALTED = 0, //!< The connection is in a halted stat. It does not have
47 ///< a valid file descriptor, and it will not try and
48 ///< and create one.
49 CONNECTION_STATE_INIT, //!< Init state, sets up connection.
50 CONNECTION_STATE_CONNECTING, //!< Waiting for connection to establish.
51 CONNECTION_STATE_TIMEOUT, //!< Timeout during #CONNECTION_STATE_CONNECTING.
52 CONNECTION_STATE_CONNECTED, //!< File descriptor is open (ready for writing).
53 CONNECTION_STATE_SHUTDOWN, //!< Connection is shutting down.
54 CONNECTION_STATE_FAILED, //!< Connection has failed.
55 CONNECTION_STATE_CLOSED, //!< Connection has been closed.
58
59/** Public fields for the connection
60 *
61 * This saves the overhead of using accessors for commonly used fields in
62 * connections.
63 *
64 * Though these fields are public, they should _NOT_ be modified by clients of
65 * the connection API.
66 */
68 char const * _CONST name; //!< Prefix to add to log messages.
69
70 connection_state_t _CONST state; //!< Current connection state.
71 connection_state_t _CONST prev; //!< The previous state the connection was in.
72 uint64_t _CONST id; //!< Unique identifier for the connection.
73 void * _CONST h; //!< Connection handle
74 fr_event_list_t * _CONST el; //!< Event list for timers and I/O events.
75
76 uint64_t _CONST reconnected; //!< How many times we've attempted to establish or
77 ///< re-establish this connection.
78 uint64_t _CONST timed_out; //!< How many times has this connection timed out when
79 ///< connecting.
80 bool _CONST triggers; //!< do we run the triggers?
81};
82
83typedef enum {
84 CONNECTION_FAILED = 0, //!< Connection is being reconnected because it failed.
85 CONNECTION_EXPIRED //!< Connection is being reconnected because it's at
86 ///< the end of its life. In this case we enter the
87 ///< closing state and try and close the connection
88 ///< gracefully.
90
91typedef struct {
92 fr_time_delta_t connection_timeout; //!< How long to wait for the connection to open
93 //!< or for shutdown to close the connection.
94 fr_time_delta_t reconnection_delay; //!< How long to wait after failures.
96
98
100extern size_t connection_states_len;
101
102/** Callback for the initialise state
103 *
104 * Should attempt to open a non-blocking connection and return it in fd_out.
105 *
106 * @param[out] h_out Where to write the new handle.
107 * @param[in] conn If integrating with a 3rd party library
108 * that will trigger connection API state transitions,
109 * the connection should be passed as the uctx argument
110 * for library I/O callbacks.
111 * @param[in] uctx User context.
112 * @return
113 * - #CONNECTION_STATE_CONNECTING if a handle was successfully created.
114 * - #CONNECTION_STATE_FAILED if we could not create a handle.
115 */
116typedef connection_state_t (*connection_init_t)(void **h_out, connection_t *conn, void *uctx);
117
118/** Notification that the connection is now open
119 *
120 * This should be used to add any additional I/O events for the file descriptor
121 * to call other code if it becomes readable or writable.
122 *
123 * @param[in] el to use for inserting I/O events.
124 * @param[in] h Handle that was successfully opened.
125 * @param[in] uctx User context.
126 * @return
127 * - #CONNECTION_STATE_CONNECTED if the handle is usable.
128 * - #CONNECTION_STATE_FAILED if the handle is unusable.
129 */
131
132/** Start the process of gracefully shutting down the connection
133 *
134 * This function is called when the connection is signalled to gracefully
135 * disconnect. It should place the connection in a state where pending
136 * I/O operations complete, and buffers are flushed.
137 *
138 * After all pending events are complete, the connection should be signalled
139 * that the handle is in the closed state.
140 *
141 * @param[in] el to use for inserting I/O events.
142 * @param[in] h Handle that needs to be closed.
143 * @param[in] uctx User context.
144 * @return
145 * - #CONNECTION_STATE_SHUTDOWN if the handle has shutdown.
146 * - #CONNECTION_STATE_FAILED if the handle is unusable, and we
147 * should just transition directly to failed.
148 */
150
151/** Notification that a connection attempt has failed
152 *
153 * @note If the callback frees the connection, it must return #CONNECTION_STATE_HALTED.
154 *
155 * @param[in] h Handle that failed.
156 * @param[in] state the connection was in when it failed. Usually one of:
157 * - #CONNECTION_STATE_CONNECTING the connection attempt explicitly failed.
158 * - #CONNECTION_STATE_CONNECTED something called #connection_signal_reconnect.
159 * - #CONNECTION_STATE_TIMEOUT the connection attempt timed out.
160 * @param[in] uctx User context.
161 * @return
162 * - #CONNECTION_STATE_INIT to transition to the init state.
163 * - #CONNECTION_STATE_HALTED To prevent further reconnection
164 * attempts Can be restarted with
165 * #connection_signal_init().
166 */
168
169/** Notification that the connection has errored and must be closed
170 *
171 * This should be used to close the file descriptor. It is assumed
172 * that the file descriptor is invalid after this callback has been executed.
173 *
174 * If this callback does not close the file descriptor, the server will leak
175 * file descriptors.
176 *
177 * @param[in] el to use for inserting I/O events.
178 * @param[in] h Handle to close.
179 * @param[in] uctx User context.
180 */
181typedef void (*connection_close_t)(fr_event_list_t *el, void *h, void *uctx);
182
183/** Holds a complete set of functions for a connection
184 *
185 */
193
194/** Receive a notification when a connection enters a particular state
195 *
196 * It is permitted for watchers to signal state changes, and/or to free the
197 * connection. The actual free will be deferred until the watcher returns.
198 *
199 * @param[in] conn Being watched.
200 * @param[in] prev State we came from.
201 * @param[in] state State that was entered (the current state)
202 * @param[in] uctx that was passed to connection_add_watch_*.
203 */
204typedef void(*connection_watch_t)(connection_t *conn,
205 connection_state_t prev, connection_state_t state, void *uctx);
206
207/** @name Add watcher functions that get called before (pre) the state callback and after (post)
208 * @{
209 */
211 connection_watch_t watch, bool oneshot, void const *uctx);
212
214 connection_watch_t watch, bool oneshot, void const *uctx);
215
217 connection_watch_t watch);
218
220 connection_watch_t watch);
221
223
225
227
228void connection_watch_set_uctx(connection_watch_entry_t *entry, void const *uctx);
229
231/** @} */
232
233/** @name Statistics
234 * @{
235 */
236uint64_t connection_get_num_reconnected(connection_t const *conn);
237
238uint64_t connection_get_num_timed_out(connection_t const *conn);
239/** @} */
240
241/** @name Signal the connection to change states
242 * @{
243 */
245
247
249
251
253
255
257/** @} */
258
259/** @name Install generic I/O events on an FD to signal state changes
260 * @{
261 */
262int connection_signal_on_fd(connection_t *conn, int fd);
263/** @} */
264
265/** @name Allocate a new connection
266 * @{
267 */
269 connection_funcs_t const *funcs, connection_conf_t const *conf,
270 char const *log_prefix, void const *uctx);
271/** @} */
272
273#undef _CONST
274
275#ifdef __cplusplus
276}
277#endif
#define RCSIDH(h, id)
Definition build.h:484
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:204
void connection_watch_enable(connection_watch_entry_t *entry)
Enable a watcher.
Definition connection.c:547
connection_state_t(* connection_failed_t)(void *h, connection_state_t state, void *uctx)
Notification that a connection attempt has failed.
Definition connection.h:167
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:616
uint64_t _CONST timed_out
How many times has this connection timed out when connecting.
Definition connection.h:78
void connection_watch_disable(connection_watch_entry_t *entry)
Disable a watcher.
Definition connection.c:557
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:181
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:475
fr_event_list_t *_CONST el
Event list for timers and I/O events.
Definition connection.h:74
connection_state_t(* connection_init_t)(void **h_out, connection_t *conn, void *uctx)
Callback for the initialise state.
Definition connection.h:116
bool connection_watch_is_enabled(connection_watch_entry_t *entry)
Return the state of a watch entry.
Definition connection.c:593
void connection_signal_halt(connection_t *conn)
Shuts down a connection ungracefully.
connection_state_t
Definition connection.h:45
@ CONNECTION_STATE_FAILED
Connection has failed.
Definition connection.h:54
@ CONNECTION_STATE_HALTED
The connection is in a halted stat.
Definition connection.h:46
@ CONNECTION_STATE_CLOSED
Connection has been closed.
Definition connection.h:55
@ CONNECTION_STATE_CONNECTED
File descriptor is open (ready for writing).
Definition connection.h:52
@ CONNECTION_STATE_TIMEOUT
Timeout during CONNECTION_STATE_CONNECTING.
Definition connection.h:51
@ CONNECTION_STATE_INIT
Init state, sets up connection.
Definition connection.h:49
@ CONNECTION_STATE_MAX
Definition connection.h:56
@ CONNECTION_STATE_CONNECTING
Waiting for connection to establish.
Definition connection.h:50
@ CONNECTION_STATE_SHUTDOWN
Connection is shutting down.
Definition connection.h:53
void connection_signals_resume(connection_t *conn)
Resume processing of deferred signals.
Definition connection.c:322
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:604
uint64_t _CONST reconnected
How many times we've attempted to establish or re-establish this connection.
Definition connection.h:76
void *_CONST h
Connection handle.
Definition connection.h:73
bool _CONST triggers
do we run the triggers?
Definition connection.h:80
connection_reason_t
Definition connection.h:83
@ CONNECTION_EXPIRED
Connection is being reconnected because it's at the end of its life.
Definition connection.h:85
@ CONNECTION_FAILED
Connection is being reconnected because it failed.
Definition connection.h:84
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:130
void connection_watch_set_uctx(connection_watch_entry_t *entry, void const *uctx)
Change the uctx of an entry.
Definition connection.c:580
connection_state_t _CONST state
Current connection state.
Definition connection.h:70
connection_init_t init
Definition connection.h:187
void connection_signal_reconnect(connection_t *conn, connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
#define _CONST
Definition connection.h:40
char const *_CONST name
Prefix to add to log messages.
Definition connection.h:68
connection_state_t _CONST prev
The previous state the connection was in.
Definition connection.h:71
fr_table_num_ordered_t const connection_states[]
Definition connection.c:49
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:189
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:513
connection_failed_t failed
Definition connection.h:190
size_t connection_states_len
Definition connection.c:59
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:535
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:458
fr_time_delta_t reconnection_delay
How long to wait after failures.
Definition connection.h:94
void connection_watch_enable_set_uctx(connection_watch_entry_t *entry, void const *uctx)
Enable a watcher and replace the uctx.
Definition connection.c:568
void connection_signal_connected(connection_t *conn)
Asynchronously signal that the connection is open.
connection_open_t open
Definition connection.h:188
void connection_signals_pause(connection_t *conn)
Pause processing of deferred signals.
Definition connection.c:313
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:92
uint64_t _CONST id
Unique identifier for the connection.
Definition connection.h:72
connection_close_t close
Definition connection.h:191
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:149
Holds a complete set of functions for a connection.
Definition connection.h:186
Public fields for the connection.
Definition connection.h:67
Stores all information relating to an event list.
Definition event.c:411
static rs_t * conf
Definition radsniff.c:53
void * uctx
User data to pass to the function.
Definition connection.c:87
An entry in a watch function list.
Definition connection.c:81
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