The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 6b671eabf4f042e0d23377fd0dbf8c9b12d52646 $
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  */
25 RCSIDH(connection_h, "$Id: 6b671eabf4f042e0d23377fd0dbf8c9b12d52646 $")
26 
27 #ifdef __cplusplus
28 extern "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
39 typedef struct fr_connection_pub_s fr_connection_t; /* We use the private version of the fr_connection_t */
40 # define _CONST const
41 #else
42 # define _CONST
43 #endif
44 
45 typedef enum {
46  FR_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  FR_CONNECTION_STATE_INIT, //!< Init state, sets up connection.
50  FR_CONNECTION_STATE_CONNECTING, //!< Waiting for connection to establish.
51  FR_CONNECTION_STATE_TIMEOUT, //!< Timeout during #FR_CONNECTION_STATE_CONNECTING.
52  FR_CONNECTION_STATE_CONNECTED, //!< File descriptor is open (ready for writing).
53  FR_CONNECTION_STATE_SHUTDOWN, //!< Connection is shutting down.
54  FR_CONNECTION_STATE_FAILED, //!< Connection has failed.
55  FR_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  fr_connection_state_t _CONST state; //!< Current connection state.
71  fr_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 
83 typedef enum {
84  FR_CONNECTION_FAILED = 0, //!< Connection is being reconnected because it failed.
85  FR_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 
91 typedef 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 
100 extern size_t fr_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  * - #FR_CONNECTION_STATE_CONNECTING if a handle was successfully created.
114  * - #FR_CONNECTION_STATE_FAILED if we could not create a handle.
115  */
116 typedef fr_connection_state_t (*fr_connection_init_t)(void **h_out, fr_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  * - #FR_CONNECTION_STATE_CONNECTED if the handle is usable.
128  * - #FR_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  * - #FR_CONNECTION_STATE_SHUTDOWN if the handle has shutdown.
146  * - #FR_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 #FR_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  * - #FR_CONNECTION_STATE_CONNECTING the connection attempt explicitly failed.
158  * - #FR_CONNECTION_STATE_CONNECTED something called #fr_connection_signal_reconnect.
159  * - #FR_CONNECTION_STATE_TIMEOUT the connection attempt timed out.
160  * @param[in] uctx User context.
161  * @return
162  * - #FR_CONNECTION_STATE_INIT to transition to the init state.
163  * - #FR_CONNECTION_STATE_HALTED To prevent further reconnection
164  * attempts Can be restarted with
165  * #fr_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  */
181 typedef void (*fr_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  */
186 typedef struct {
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 fr_connection_add_watch_*.
203  */
205  fr_connection_state_t prev, fr_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  fr_connection_watch_t watch, bool oneshot, void const *uctx);
212 
214  fr_connection_watch_t watch, bool oneshot, void const *uctx);
215 
217  fr_connection_watch_t watch);
218 
220  fr_connection_watch_t watch);
221 
223 
225 
227 
228 void fr_connection_watch_set_uctx(fr_connection_watch_entry_t *entry, void const *uctx);
229 
231 /** @} */
232 
233 /** @name Statistics
234  * @{
235  */
237 
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  */
263 /** @} */
264 
265 /** @name Allocate a new connection
266  * @{
267  */
269  fr_connection_funcs_t const *funcs, fr_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
278 
279 
#define RCSIDH(h, id)
Definition: build.h:445
fr_connection_shutdown_t shutdown
Definition: connection.h:189
uint64_t _CONST id
Unique identifier for the connection.
Definition: connection.h:72
uint64_t _CONST timed_out
How many times has this connection timed out when connecting.
Definition: connection.h:78
fr_connection_state_t(* fr_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
void fr_connection_signals_pause(fr_connection_t *conn)
Pause processing of deferred signals.
Definition: connection.c:310
fr_connection_state_t
Definition: connection.h:45
@ FR_CONNECTION_STATE_CLOSED
Connection has been closed.
Definition: connection.h:55
@ FR_CONNECTION_STATE_HALTED
The connection is in a halted stat.
Definition: connection.h:46
@ FR_CONNECTION_STATE_CONNECTING
Waiting for connection to establish.
Definition: connection.h:50
@ FR_CONNECTION_STATE_FAILED
Connection has failed.
Definition: connection.h:54
@ FR_CONNECTION_STATE_TIMEOUT
Timeout during FR_CONNECTION_STATE_CONNECTING.
Definition: connection.h:51
@ FR_CONNECTION_STATE_INIT
Init state, sets up connection.
Definition: connection.h:49
@ FR_CONNECTION_STATE_SHUTDOWN
Connection is shutting down.
Definition: connection.h:53
@ FR_CONNECTION_STATE_MAX
Definition: connection.h:56
@ FR_CONNECTION_STATE_CONNECTED
File descriptor is open (ready for writing).
Definition: connection.h:52
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.
Definition: connection.c:454
void fr_connection_watch_enable(fr_connection_watch_entry_t *entry)
Enable a watcher.
Definition: connection.c:543
void(* fr_connection_watch_t)(fr_connection_t *conn, fr_connection_state_t prev, fr_connection_state_t state, void *uctx)
Receive a notification when a connection enters a particular state.
Definition: connection.h:204
fr_time_delta_t reconnection_delay
How long to wait after failures.
Definition: connection.h:94
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.
Definition: connection.c:612
void(* fr_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
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.
Definition: connection.c:531
void fr_connection_signal_connected(fr_connection_t *conn)
Asynchronously signal that the connection is open.
Definition: connection.c:1136
fr_connection_state_t _CONST state
Current connection state.
Definition: connection.h:70
void fr_connection_signal_halt(fr_connection_t *conn)
Shuts down a connection ungracefully.
Definition: connection.c:1290
fr_connection_init_t init
Definition: connection.h:187
void fr_connection_signals_resume(fr_connection_t *conn)
Resume processing of deferred signals.
Definition: connection.c:319
fr_connection_state_t(* fr_connection_init_t)(void **h_out, fr_connection_t *conn, void *uctx)
Callback for the initialise state.
Definition: connection.h:116
fr_connection_state_t(* fr_connection_failed_t)(void *h, fr_connection_state_t state, void *uctx)
Notification that a connection attempt has failed.
Definition: connection.h:167
void fr_connection_signal_init(fr_connection_t *conn)
Asynchronously signal a halted connection to start.
Definition: connection.c:1106
size_t fr_connection_states_len
Definition: connection.c:56
fr_connection_state_t(* fr_connection_open_t)(fr_event_list_t *el, void *h, void *uctx)
Notification that the connection is now open.
Definition: connection.h:130
fr_connection_failed_t failed
Definition: connection.h:190
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.
Definition: connection.c:509
void fr_connection_watch_enable_set_uctx(fr_connection_watch_entry_t *entry, void const *uctx)
Enable a watcher and replace the uctx.
Definition: connection.c:564
fr_connection_close_t close
Definition: connection.h:191
fr_connection_open_t open
Definition: connection.h:188
#define _CONST
Definition: connection.h:40
void fr_connection_signal_shutdown(fr_connection_t *conn)
Shuts down a connection gracefully.
Definition: connection.c:1227
void *_CONST h
Connection handle.
Definition: connection.h:73
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.
Definition: connection.c:600
bool _CONST triggers
do we run the triggers?
Definition: connection.h:80
fr_event_list_t *_CONST el
Event list for timers and I/O events.
Definition: connection.h:74
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.
Definition: connection.c:471
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
char const *_CONST name
Prefix to add to log messages.
Definition: connection.h:68
bool fr_connection_watch_is_enabled(fr_connection_watch_entry_t *entry)
Return the state of a watch entry.
Definition: connection.c:589
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.
Definition: connection.c:1400
fr_connection_reason_t
Definition: connection.h:83
@ FR_CONNECTION_EXPIRED
Connection is being reconnected because it's at the end of its life.
Definition: connection.h:85
@ FR_CONNECTION_FAILED
Connection is being reconnected because it failed.
Definition: connection.h:84
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.
Definition: connection.c:1507
uint64_t _CONST reconnected
How many times we've attempted to establish or re-establish this connection.
Definition: connection.h:76
fr_connection_state_t _CONST prev
The previous state the connection was in.
Definition: connection.h:71
void fr_connection_watch_disable(fr_connection_watch_entry_t *entry)
Disable a watcher.
Definition: connection.c:553
fr_table_num_ordered_t const fr_connection_states[]
Definition: connection.c:46
void fr_connection_watch_set_uctx(fr_connection_watch_entry_t *entry, void const *uctx)
Change the uctx of an entry.
Definition: connection.c:576
void fr_connection_signal_reconnect(fr_connection_t *conn, fr_connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
Definition: connection.c:1166
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: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:53
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
static fr_event_list_t * el