The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
trunk.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: 5f6e2b3fb4e86009733695b5b24573e60df83cfa $
20 *
21 * @file src/lib/server/trunk.c
22 * @brief A management API for bonding multiple connections together.
23 *
24 * @copyright 2019-2020 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25 * @copyright 2019-2020 The FreeRADIUS server project
26 */
27RCSIDH(server_trunk_h, "$Id: 5f6e2b3fb4e86009733695b5b24573e60df83cfa $")
28
29#include <freeradius-devel/server/connection.h>
30#include <freeradius-devel/server/request.h>
31#include <freeradius-devel/server/cf_parse.h>
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37/*
38 * Allow public and private versions of the same structures
39 */
40#ifdef _CONST
41# error _CONST can only be defined in the local header
42#endif
43#ifndef _TRUNK_PRIVATE
46typedef struct trunk_pub_s trunk_t;
47# define _CONST const
48#else
49# define _CONST
50#endif
51
52/** Reasons for a request being cancelled
53 *
54 */
55typedef enum {
56 TRUNK_CANCEL_REASON_NONE = 0, //!< Request has not been cancelled.
57 TRUNK_CANCEL_REASON_SIGNAL, //!< Request cancelled due to a signal.
58 TRUNK_CANCEL_REASON_MOVE, //!< Request cancelled because it's being moved.
59 TRUNK_CANCEL_REASON_REQUEUE //!< A previously sent request is being requeued.
61
62typedef enum {
63 TRUNK_STATE_IDLE = 0, //!< Trunk has no connections
64 TRUNK_STATE_ACTIVE, //!< Trunk has active connections
65 TRUNK_STATE_PENDING, //!< Trunk has connections, but none are active
68
69/** What type of I/O events the trunk connection is currently interested in receiving
70 *
71 */
72typedef enum {
73 TRUNK_CONN_EVENT_NONE = 0x00, //!< Don't notify the trunk on connection state
74 ///< changes.
75 TRUNK_CONN_EVENT_READ = 0x01, //!< Trunk should be notified if a connection is
76 ///< readable.
77 TRUNK_CONN_EVENT_WRITE = 0x02, //!< Trunk should be notified if a connection is
78 ///< writable.
79 TRUNK_CONN_EVENT_BOTH = 0x03, //!< Trunk should be notified if a connection is
80 ///< readable or writable.
81
83
84/** Used for sanity checks and to track which list the connection is in
85 *
86 */
87typedef enum {
88 TRUNK_CONN_HALTED = 0x0000, //!< Halted, ready to be freed.
89 TRUNK_CONN_INIT = 0x0001, //!< In the initial state.
90 TRUNK_CONN_CONNECTING = 0x0002, //!< Connection is connecting.
91 TRUNK_CONN_ACTIVE = 0x0004, //!< Connection is connected and ready to service requests.
92 ///< This is active and not 'connected', because a connection
93 ///< can be 'connected' and 'full' or 'connected' and 'active'.
94 TRUNK_CONN_CLOSED = 0x0008, //!< Connection was closed, either explicitly or due to failure.
95 TRUNK_CONN_FULL = 0x0010, //!< Connection is full and can't accept any more requests.
96 TRUNK_CONN_INACTIVE = 0x0020, //!< Connection is inactive and can't accept any more requests.
97 TRUNK_CONN_INACTIVE_DRAINING = 0x0040, //!< Connection is inactive, can't accept any more requests,
98 ///< and will be closed once it has no more outstanding
99 ///< requests. Connections in this state can transition to
100 ///< #TRUNK_CONN_DRAINING.
101 TRUNK_CONN_DRAINING = 0x0080, //!< Connection will be closed once it has no more outstanding
102 ///< requests, if it's not reactivated.
103 TRUNK_CONN_DRAINING_TO_FREE = 0x0100, //!< Connection will be closed once it has no more outstanding
104 ///< requests.
105
107
108/** All connection states
109 *
110 */
111#define TRUNK_CONN_ALL \
112(\
113 TRUNK_CONN_INIT | \
114 TRUNK_CONN_CONNECTING | \
115 TRUNK_CONN_ACTIVE | \
116 TRUNK_CONN_CLOSED | \
117 TRUNK_CONN_FULL | \
118 TRUNK_CONN_INACTIVE | \
119 TRUNK_CONN_INACTIVE_DRAINING | \
120 TRUNK_CONN_DRAINING | \
121 TRUNK_CONN_DRAINING_TO_FREE \
122)
123
124/** States where the connection may potentially be used to send requests
125 *
126 */
127#define TRUNK_CONN_SERVICEABLE \
128(\
129 TRUNK_CONN_ACTIVE | \
130 TRUNK_CONN_INACTIVE | \
131 TRUNK_CONN_DRAINING | \
132 TRUNK_CONN_INACTIVE_DRAINING | \
133 TRUNK_CONN_DRAINING_TO_FREE \
134)
135
136/** States where the connection may be processing requests
137 *
138 */
139#define TRUNK_CONN_PROCESSING \
140(\
141 TRUNK_CONN_ACTIVE | \
142 TRUNK_CONN_FULL | \
143 TRUNK_CONN_INACTIVE | \
144 TRUNK_CONN_DRAINING | \
145 TRUNK_CONN_INACTIVE_DRAINING | \
146 TRUNK_CONN_DRAINING_TO_FREE \
147)
148
149typedef enum {
150 TRUNK_ENQUEUE_IN_BACKLOG = 1, //!< Request should be enqueued in backlog
151 TRUNK_ENQUEUE_OK = 0, //!< Operation was successful.
152 TRUNK_ENQUEUE_NO_CAPACITY = -1, //!< At maximum number of connections,
153 ///< and no connection has capacity.
154 TRUNK_ENQUEUE_DST_UNAVAILABLE = -2, //!< Destination is down.
155 TRUNK_ENQUEUE_FAIL = -3 //!< General failure.
157
158/** Used for sanity checks and to simplify freeing
159 *
160 * Allows us to track which
161 */
162typedef enum {
163 TRUNK_REQUEST_STATE_INIT = 0x0000, //!< Initial state. Requests in this state
164 ///< were never assigned, and the request_t should
165 ///< not have been yielded.
166 TRUNK_REQUEST_STATE_UNASSIGNED = 0x0001, //!< Transition state - Request currently
167 ///< not assigned to any connection.
168 TRUNK_REQUEST_STATE_BACKLOG = 0x0002, //!< In the backlog.
169 TRUNK_REQUEST_STATE_PENDING = 0x0004, //!< In the queue of a connection
170 ///< and is pending writing.
171 TRUNK_REQUEST_STATE_PARTIAL = 0x0008, //!< Some of the request was written to the socket,
172 ///< more of it should be written later.
173 TRUNK_REQUEST_STATE_SENT = 0x0010, //!< Was written to a socket. Waiting for a response.
174 TRUNK_REQUEST_STATE_REAPABLE = 0x0020, //!< Request has been written, needs to persist, but we
175 ///< are not currently waiting for any response.
176 ///< This is primarily useful where the connection only
177 ///< allows a single outstanding request, and writing
178 ///< additional requests would cause the previous result
179 ///< to be lost.
180 ///< Requests in this state count towards the outstanding
181 ///< number of requests on a connection, and prevent new
182 ///< requests from being enqueued until they complete.
183 TRUNK_REQUEST_STATE_COMPLETE = 0x0040, //!< The request is complete.
184 TRUNK_REQUEST_STATE_FAILED = 0x0080, //!< The request failed.
185 TRUNK_REQUEST_STATE_CANCEL = 0x0100, //!< A request on a particular socket was cancel.
186 TRUNK_REQUEST_STATE_CANCEL_SENT = 0x0200, //!< We've informed the remote server that
187 ///< the request has been cancelled.
188 TRUNK_REQUEST_STATE_CANCEL_PARTIAL = 0x0400, //!< We partially wrote a cancellation request.
189 TRUNK_REQUEST_STATE_CANCEL_COMPLETE = 0x0800, //!< Remote server has acknowledged our cancellation.
190
192
193/** All request states
194 *
195 */
196#define TRUNK_REQUEST_STATE_ALL \
197(\
198 TRUNK_REQUEST_STATE_BACKLOG | \
199 TRUNK_REQUEST_STATE_PENDING | \
200 TRUNK_REQUEST_STATE_PARTIAL | \
201 TRUNK_REQUEST_STATE_SENT | \
202 TRUNK_REQUEST_STATE_REAPABLE | \
203 TRUNK_REQUEST_STATE_COMPLETE | \
204 TRUNK_REQUEST_STATE_FAILED | \
205 TRUNK_REQUEST_STATE_CANCEL | \
206 TRUNK_REQUEST_STATE_CANCEL_PARTIAL | \
207 TRUNK_REQUEST_STATE_CANCEL_SENT | \
208 TRUNK_REQUEST_STATE_CANCEL_COMPLETE \
209)
210
211/** All requests in various cancellation states
212 *
213 */
214#define TRUNK_REQUEST_STATE_CANCEL_ALL \
215(\
216 TRUNK_REQUEST_STATE_CANCEL | \
217 TRUNK_REQUEST_STATE_CANCEL_PARTIAL | \
218 TRUNK_REQUEST_STATE_CANCEL_SENT | \
219 TRUNK_REQUEST_STATE_CANCEL_COMPLETE \
220)
221
222/** Common configuration parameters for a trunk
223 *
224 */
225typedef struct {
226 connection_conf_t const *conn_conf; //!< Connection configuration.
227
228 uint16_t start; //!< How many connections to start.
229
230 uint16_t min; //!< Shouldn't let connections drop below this number.
231
232 uint16_t max; //!< Maximum number of connections in the trunk.
233
234 uint16_t connecting; //!< Maximum number of connections that can be in the
235 ///< connecting state. Used to throttle connection spawning.
236
237 uint32_t target_req_per_conn; //!< How many pending requests should ideally be
238 ///< running on each connection. Averaged across
239 ///< the 'active' set of connections.
240
241 uint32_t max_req_per_conn; //!< Maximum requests per connection.
242 ///< Used to determine if we need to create new connections
243 ///< and whether we can enqueue new requests.
244
245 uint32_t max_backlog; //!< Maximum number of requests that can be in the backlog.
246
247 uint64_t max_uses; //!< The maximum time a connection can be used.
248
249 fr_time_delta_t lifetime; //!< Time between reconnects.
250
251 fr_time_delta_t idle_timeout; //!< how long a connection can remain idle for
252
253 fr_time_delta_t open_delay; //!< How long we must be above target utilisation
254 ///< to spawn a new connection.
255
256 fr_time_delta_t close_delay; //!< How long we must be below target utilisation
257 ///< to close an existing connection.
258
259
260 fr_time_delta_t req_cleanup_delay; //!< How long must a request in the unassigned (free)
261 ///< list not have been used for before it's cleaned up
262 ///< and actually freed.
263
264 fr_time_delta_t manage_interval; //!< How often we run the management algorithm to
265 ///< open/close connections.
266
267 unsigned req_pool_headers; //!< How many chunk headers the talloc pool allocated
268 ///< with the treq should contain.
269
270 size_t req_pool_size; //!< The size of the talloc pool allocated with the treq.
271
272 bool always_writable; //!< Set to true if our ability to write requests to
273 ///< a connection handle is not dependent on the state
274 ///< of the underlying connection, i.e. if the library
275 ///< used to implement the connection can always receive
276 ///< and buffer new requests irrespective of the state
277 ///< of the underlying socket.
278 ///< If this is true, #trunk_connection_signal_writable
279 ///< does not need to be called, and requests will be
280 ///< enqueued as soon as they're received.
281
282 bool backlog_on_failed_conn; //!< Assign requests to the backlog when there are no
283 //!< available connections and the last connection event
284 //!< was a failure, instead of failing them immediately.
285
286 bool conn_triggers; //!< Do we run connection related triggers?
287 CONF_SECTION *conn_trigger_cs; //!< Module conf section to find connection trigger section in.
288
289 bool req_triggers; //!< Do we run request related triggers?
290 CONF_SECTION *req_trigger_cs; //!< Module conf section to find request trigger section in.
292
293/** Public fields for the trunk
294 *
295 * This saves the overhead of using accessors for commonly used fields in
296 * the trunk.
297 *
298 * Though these fields are public, they should _NOT_ be modified by clients of
299 * the trunk API.
300 */
302 /** @name Last time an event occurred
303 * @{
304 */
305 fr_time_t _CONST last_above_target; //!< Last time average utilisation went above
306 ///< the target value.
307
308 fr_time_t _CONST last_below_target; //!< Last time average utilisation went below
309 ///< the target value.
310
311 fr_time_t _CONST last_open; //!< Last time the connection management
312 ///< function opened a connection.
313
314 fr_time_t _CONST last_closed; //!< Last time the connection management
315 ///< function closed a connection.
316
317 fr_time_t _CONST last_connected; //!< Last time a connection connected.
318
319 fr_time_t _CONST last_failed; //!< Last time a connection failed.
320
321 fr_time_t _CONST last_write_success; //!< Last time we wrote to the connection
322
323 fr_time_t _CONST last_read_success; //!< Last time we read a response.
324 /** @} */
325
326 /** @name Statistics
327 * @{
328 */
329 uint64_t _CONST req_alloc; //!< The number of requests currently
330 ///< allocated that have not been freed
331 ///< or returned to the free list.
332
333 uint64_t _CONST req_alloc_new; //!< How many requests we've allocated.
334
335 uint64_t _CONST req_alloc_reused; //!< How many requests were reused.
336 /** @} */
337
338 trunk_state_t _CONST state; //!< Current state of the trunk.
339};
340
341/** Public fields for the trunk request
342 *
343 * This saves the overhead of using accessors for commonly used fields in trunk
344 * requests.
345 *
346 * Though these fields are public, they should _NOT_ be modified by clients of
347 * the trunk API.
348 */
350 trunk_request_state_t _CONST state; //!< Which list the request is now located in.
351
352 trunk_t * _CONST trunk; //!< Trunk this request belongs to.
353
354 trunk_connection_t * _CONST tconn; //!< Connection this request belongs to.
355
356 void * _CONST preq; //!< Data for the muxer to write to the connection.
357
358 void * _CONST rctx; //!< Resume ctx of the module.
359
360 request_t * _CONST request; //!< The request that we're writing the data on behalf of.
361};
362
363/** Public fields for the trunk connection
364 *
365 * This saves the overhead of using accessors for commonly used fields in trunk
366 * connections.
367 *
368 * Though these fields are public, they should _NOT_ be modified by clients of
369 * the trunk API.
370 */
372 trunk_connection_state_t _CONST state; //!< What state the connection is in.
373
374 connection_t * _CONST conn; //!< The underlying connection.
375
376 fr_time_t _CONST last_write_success; //!< Last time we wrote to the connection
377
378 fr_time_t _CONST last_read_success; //!< Last time we read from the connection
379
380 trunk_t * _CONST trunk; //!< Trunk this connection belongs to.
381};
382
383#ifndef TRUNK_TESTS
384/** Config parser definitions to populate a trunk_conf_t
385 *
386 */
387extern conf_parser_t const trunk_config[];
388#endif
389
390/** Allocate a new connection for the trunk
391 *
392 * The trunk code only interacts with underlying connections via the connection API.
393 * As a result the trunk API is shielded from the implementation details of opening
394 * and closing connections.
395 *
396 * When creating new connections, this callback is used to allocate and configure
397 * a new #connection_t, this #connection_t and the connection API is how the
398 * trunk signals the underlying connection that it should start, reconnect, and halt (stop).
399 *
400 * The trunk must be informed when the underlying connection is readable, and,
401 * if `always_writable == false`, when the connection is writable.
402 *
403 * When the connection is readable, a read I/O handler installed by the init()
404 * callback of the #connection_t must either:
405 *
406 * - If there's no underlying I/O library, call `trunk_connection_signal_readable(tconn)`
407 * immediately, relying on the trunk demux callback to perform decoding and demuxing.
408 * - If there is an underlying I/O library, feed any incoming data to that library and
409 * then call #trunk_connection_signal_readable if the underlying I/O library
410 * indicates complete responses are ready for processing.
411 *
412 * When the connection is writable a write I/O handler installed by the open() callback
413 * of the #connection_t must either:
414 *
415 * - If `always_writable == true` - Inform the underlying I/O library that the connection
416 * is writable. The trunk API does not need to be informed as it will immediately pass
417 * through any enqueued requests to the I/O library.
418 * - If `always_writable == false` and there's an underlying I/O library,
419 * call `trunk_connection_signal_writable(tconn)` to allow the trunk mux callback
420 * to pass requests to the underlying I/O library and (optionally) signal the I/O library
421 * that the connection is writable.
422 * - If `always_writable == false` and there's no underlying I/O library,
423 * call `trunk_connection_signal_writable(tconn)` to allow the trunk mux callback
424 * to encode and write requests to a socket.
425 *
426 * @param[in] tconn The trunk connection this connection will be bound to.
427 * Should be used as the context for any #connection_t
428 * allocated.
429 * @param[in] el The event list to use for I/O and timer events.
430 * @param[in] conf Configuration of the #connection_t.
431 * @param[in] log_prefix What to prefix connection log messages with.
432 * @param[in] uctx User context data passed to #trunk_alloc.
433 * @return
434 * - A new connection_t on success (should be in the halted state - the default).
435 * - NULL on error.
436 */
437typedef connection_t *(*trunk_connection_alloc_t)(trunk_connection_t *tconn, fr_event_list_t *el,
438 connection_conf_t const *conf,
439 char const *log_prefix, void *uctx);
440
441/** Inform the trunk API client which I/O events the trunk wants to receive
442 *
443 * I/O handlers installed by this callback should call one or more of the following
444 * functions to signal that an I/O event has occurred:
445 *
446 * - trunk_connection_signal_writable - Connection is now writable.
447 * - trunk_connection_signal_readable - Connection is now readable.
448 * - trunk_connection_signal_inactive - Connection is full or congested.
449 * - trunk_connection_signal_active - Connection is no longer full or congested.
450 * - trunk_connection_signal_reconnect - Connection is inviable and should be reconnected.
451 *
452 * @param[in] tconn That should be notified of I/O events.
453 * @param[in] conn The #connection_t bound to the tconn.
454 * Use conn->h to access the
455 * connection handle or file descriptor.
456 * @param[in] el to insert I/O events into.
457 * @param[in] notify_on I/O events to signal the trunk connection on.
458 * @param[in] uctx User context data passed to #trunk_alloc.
459 */
462 trunk_connection_event_t notify_on, void *uctx);
463
464/** Multiplex one or more requests into a single connection
465 *
466 * This callback should:
467 *
468 * - Pop one or more requests from the trunk connection's pending queue using
469 * #trunk_connection_pop_request.
470 * - Serialize the protocol request data contained within the trunk request's (treq's)
471 * pctx, writing it to the provided #connection_t (or underlying connection handle).
472 * - Insert the provided treq
473 * into a tracking structure associated with the #connection_t or uctx.
474 * This tracking structure will be used later in the trunk demux callback to match
475 * protocol requests with protocol responses.
476 *
477 * If working at the socket level and a write on a file descriptor indicates
478 * less data was written than was needed, the trunk API client should track the
479 * amount of data written in the protocol request (preq), and should call
480 * `trunk_request_signal_partial(treq)`.
481 * #trunk_request_signal_partial will move the request out of the pending
482 * queue, and store it in the partial slot of the trunk connection.
483 * The next time #trunk_connection_pop_request is called, the partially written
484 * treq will be returned first. The API client should continue writing the partially
485 * written request to the socket.
486 *
487 * After calling #trunk_request_signal_partial this callback *MUST NOT*
488 * call #trunk_connection_pop_request again, and should immediately return.
489 *
490 * If the request can't be written to the connection because it the connection
491 * has become unusable, this callback should call
492 * `connection_signal_reconnect(conn)` to notify the connection API that the
493 * connection is unusable. The current request will either fail, or be
494 * re-enqueued depending on the trunk configuration.
495 *
496 * After calling #connection_signal_reconnect this callback *MUST NOT*
497 * call #trunk_connection_pop_request again, and should immediately return.
498 *
499 * If the protocol request data can't be written to the connection because the
500 * data is invalid or because some other error occurred, this callback should
501 * call `trunk_request_signal_fail(treq)`, this callback may then continue
502 * popping/processing other requests.
503 *
504 * @param[in] el For timer management.
505 * @param[in] tconn The trunk connection to dequeue trunk
506 * requests from.
507 * @param[in] conn Connection to write the request to.
508 * Use conn->h to access the
509 * connection handle or file descriptor.
510 * @param[in] uctx User context data passed to #trunk_alloc.
511 */
513 trunk_connection_t *tconn, connection_t *conn, void *uctx);
514
515/** Demultiplex on or more responses, reading them from a connection, decoding them, and matching them with their requests
516 *
517 * This callback should either:
518 *
519 * - If an underlying I/O library is used, request complete responses from
520 * the I/O library, and match the responses with a treq (trunk request)
521 * using a tracking structure associated with the #connection_t or uctx.
522 * - If no underlying I/O library is used, read responses from the #connection_t,
523 * decode those responses, and match those responses with a treq using a tracking
524 * structure associated with the #connection_t or uctx.
525 *
526 * The result (positive or negative), should be written to the rctx structure.
527 *
528 * #trunk_request_signal_complete should be used to inform the trunk
529 * that the request is now complete.
530 *
531 * If a connection appears to have become unusable, this callback should call
532 * #connection_signal_reconnect and immediately return. The current
533 * treq will either fail, or be re-enqueued depending on the trunk configuration.
534 *
535 * #trunk_request_signal_fail should *NOT* be called as this function is only
536 * used for reporting failures at an I/O layer level not failures of queries or
537 * external services.
538 *
539 * @param[in] el For timer management.
540 * @param[in] tconn The trunk connection.
541 * @param[in] conn Connection to read the request from.
542 * Use conn->h to access the
543 * connection handle or file descriptor.
544 * @param[in] uctx User context data passed to #trunk_alloc.
545 */
547 trunk_connection_t *tconn, connection_t *conn, void *uctx);
548
549/** Inform a remote service like a datastore that a request should be cancelled
550 *
551 * This callback will be called any time there are one or more requests to be
552 * cancelled and a #connection_t is writable, or as soon as a request is
553 * cancelled if `always_writable == true`.
554 *
555 * For efficiency, this callback should call #trunk_connection_pop_cancellation
556 * multiple times, and process all outstanding cancellation requests.
557 *
558 * If the response (cancel ACK) from the remote service needs to be tracked,
559 * then the treq should be inserted into a tracking tree shared with the demuxer,
560 * and #trunk_request_signal_cancel_sent should be called to move the treq into
561 * the cancel_sent state.
562 *
563 * As with the main mux callback, if a cancellation request is partially written
564 * #trunk_request_signal_cancel_partial should be called, and the amount
565 * of data written should be tracked in the preq (protocol request).
566 *
567 * When the demuxer finds a matching (cancel ACK) response, the demuxer should
568 * remove the entry from the tracking tree and call
569 * #trunk_request_signal_cancel_complete.
570 *
571 * @param[in] el To insert any timers into.
572 *
573 * @param[in] tconn The trunk connection used to dequeue
574 * cancellation requests.
575 * @param[in] conn Connection to write the request to.
576 * Use conn->h to access the
577 * connection handle or file descriptor.
578 * @param[in] uctx User context data passed to #trunk_alloc.
579 */
581 trunk_connection_t *tconn, connection_t *conn, void *uctx);
582
583/** Remove an outstanding "sent" request from a tracking/matching structure
584 *
585 * If the treq (trunk request) is in the TRUNK_REQUEST_STATE_PARTIAL or
586 * TRUNK_REQUEST_STATE_SENT states, this callback will be called prior
587 * to moving the treq to a new connection, requeueing the treq or freeing
588 * the treq.
589 *
590 * The treq, and any associated resources, should be
591 * removed from the matching structure associated with the
592 * #connection_t or uctx.
593 *
594 * Which resources should be freed depends on the cancellation reason:
595 *
596 * - TRUNK_CANCEL_REASON_REQUEUE - If an encoded request can be
597 * reused, then it should be kept, otherwise it should be freed.
598 * Any resources like ID allocations bound to that request should
599 * also be freed.
600 * #trunk_request_conn_release_t callback will not be called in this
601 * instance and cannot be used as an alternative.
602 * - TRUNK_CANCEL_REASON_MOVE - If an encoded request can be reused
603 * it should be kept. The trunk mux callback should be aware that
604 * an encoded request may already be associated with a preq and use
605 * that instead of re-encoding the preq.
606 * If the encoded request cannot be reused it should be freed, and
607 * any fields in the preq that were modified during the last mux call
608 * (other than perhaps counters) should be reset to their initial values.
609 * Alternatively the #trunk_request_conn_release_t callback can be used for
610 * the same purpose, as that will be called before the request is moved.
611 * - TRUNK_CANCEL_REASON_SIGNAL - The encoded request and any I/O library
612 * request handled may be freed though that may (optionally) be left to
613 * another callback like #trunk_request_conn_release_t, as that will be
614 * called as the treq is removed from the conn.
615 * Note that the #trunk_request_complete_t and
616 * #trunk_request_fail_t callbacks will not be called in this
617 * instance.
618 *
619 * After this callback is complete one of several actions will be taken:
620 *
621 * - If the cancellation reason was TRUNK_CANCEL_REASON_REQUEUE the
622 * treq will be placed back into the pending list of the connection it
623 * was previously associated with.
624 * - If the cancellation reason was TRUNK_CANCEL_REASON_MOVE, the treq
625 * will move to the unassigned state, and then either be placed in the
626 * trunk backlog, or immediately enqueued on another trunk connection.
627 * - If the reason was TRUNK_CANCEL_SIGNAL
628 * - ...and a request_cancel_mux callback was provided, the
629 * the request_cancel_mux callback will be called when the connection
630 * is next writable (or immediately if `always_writable == true`) and
631 * the request_cancel_mux callback will send an explicit cancellation
632 * request to terminate any outstanding queries on remote datastores.
633 * - ...and no request_cancel_mux callback was provided, the
634 * treq will enter the unassigned state and then be freed.
635 *
636 * @note TRUNK_CANCEL_REASON_MOVE will only be set if the underlying
637 * connection is bad. A 'sent' treq will never be moved due to load
638 * balancing.
639 *
640 * @note There is no need to signal request state changes in the cancellation
641 * function. The trunk will move the request into the correct state.
642 * This callback is only to allow the API client to cleanup the preq in
643 * preparation for the cancellation event.
644 *
645 * @note Cancellation requests to a remote datastore should not be made
646 * here. If that is required, a cancel_mux function should be provided.
647 *
648 * @param[in] conn to remove request from.
649 * @param[in] preq_to_reset Preq to reset.
650 * @param[in] reason Why the request was cancelled.
651 * @param[in] uctx User context data passed to #trunk_alloc.
652 */
653typedef void (*trunk_request_cancel_t)(connection_t *conn, void *preq_to_reset,
654 trunk_cancel_reason_t reason, void *uctx);
655
656/** Free connection specific resources from a treq, as the treq is being removed from a connection
657 *
658 * Any connection specific resources that the treq currently holds must be
659 * released. Examples are connection-specific handles, ID allocations,
660 * and connection specific packets.
661 *
662 * The treq may be about to be freed or it may be being re-assigned to a new connection.
663 *
664 * @param[in] conn request will be removed from.
665 * @param[in] preq_to_reset Preq to remove connection specified resources
666 * from.
667 * @param[in] uctx User context data passed to #trunk_alloc.
668 */
669typedef void (*trunk_request_conn_release_t)(connection_t *conn, void *preq_to_reset,
670 void *uctx);
671
672/** Write a successful result to the rctx so that the trunk API client is aware of the result
673 *
674 * The rctx should be modified in such a way that indicates to the trunk API client
675 * that the request was sent using the trunk and a response was received.
676 *
677 * This function should not free any resources associated with the preq. That should
678 * be done in the request_free callback. This function should only be used to translate
679 * the contents of the preq into a result, and write it to the rctx.
680 *
681 * After this callback is complete, the request_free callback will be called if provided.
682 */
683typedef void (*trunk_request_complete_t)(request_t *request, void *preq, void *rctx, void *uctx);
684
685/** Write a failure result to the rctx so that the trunk API client is aware that the request failed
686 *
687 * The rctx should be modified in such a way that indicates to the trunk API client
688 * that the request could not be sent using the trunk.
689 *
690 * This function should not free any resources associated with the preq. That should
691 * be done in the request_free callback. This function should only be used to write
692 * a "canned" failure to the rctx.
693 *
694 * @note If a cancel function is provided, the cancel function should be used to remove
695 * active requests from any request/response matching, not the fail function.
696 * Both the cancel and fail functions will be called for a request that has been
697 * sent or partially sent.
698 *
699 * After this callback is complete, the request_free callback will be called if provided.
700 */
701typedef void (*trunk_request_fail_t)(request_t *request, void *preq, void *rctx,
702 trunk_request_state_t state, void *uctx);
703
704/** Free resources associated with a trunk request
705 *
706 * The trunk request is complete. If there's a request still associated with the
707 * trunk request, that will be provided so that it can be marked runnable, but
708 * be aware that the request_t * value will be NULL if the request was cancelled due
709 * to a signal.
710 *
711 * The preq and any associated data such as encoded packets or I/O library request
712 * handled *SHOULD* be explicitly freed by this function.
713 * The exception to this is if the preq is parented by the treq, in which case the
714 * preq will be explicitly freed when the treq is returned to the free list.
715 *
716 * @param[in] request to mark as runnable if no further processing is required.
717 * @param[in] preq_to_free As per the name.
718 * @param[in] uctx User context data passed to #trunk_alloc.
719 */
720typedef void (*trunk_request_free_t)(request_t *request, void *preq_to_free, void *uctx);
721
722/** Receive a notification when a trunk enters a particular state
723 *
724 * @param[in] trunk Being watched.
725 * @param[in] prev State we came from.
726 * @param[in] state State that was entered (the current state)
727 * @param[in] uctx that was passed to trunk_add_watch_*.
728 */
729typedef void(*trunk_watch_t)(trunk_t *trunk,
730 trunk_state_t prev, trunk_state_t state, void *uctx);
731
733
734/** I/O functions to pass to trunk_alloc
735 *
736 */
737typedef struct {
738 trunk_connection_alloc_t connection_alloc; //!< Allocate a new connection_t.
739
740 trunk_connection_notify_t connection_notify; //!< Update the I/O event registrations for
741
742 fr_heap_cmp_t connection_prioritise; //!< Ordering function for connections.
743
744 fr_heap_cmp_t request_prioritise; //!< Ordering function for requests. Controls
745 ///< where in the outbound queues they're inserted.
746
747 trunk_request_mux_t request_mux; ///!< Write one or more requests to a connection.
748
749 trunk_request_demux_t request_demux; ///!< Read one or more requests from a connection.
750
751 trunk_request_cancel_mux_t request_cancel_mux; //!< Inform an external resource that we no longer
752 ///< care about the result of any queries we
753 ///< issued for this request.
754
755 trunk_request_cancel_t request_cancel; //!< Request should be removed from tracking
756 ///< and should be reset to its initial state.
757
758 trunk_request_conn_release_t request_conn_release; //!< Any connection specific resources should be
759 ///< removed from the treq as it's about to be
760 ///< moved or freed.
761
762 trunk_request_complete_t request_complete; //!< Request is complete, interpret the response
763 ///< contained in preq.
764
765 trunk_request_fail_t request_fail; //!< Request failed, write out a canned response.
766
767 trunk_request_free_t request_free; //!< Free the preq and any resources it holds and
768 ///< provide a chance to mark the request as runnable.
770
771/** @name Statistics
772 * @{
773 */
774uint16_t trunk_connection_count_by_state(trunk_t *trunk, int conn_state) CC_HINT(nonnull);
775
776uint32_t trunk_request_count_by_connection(trunk_connection_t const *tconn, int req_state) CC_HINT(nonnull);
777
778uint64_t trunk_request_count_by_state(trunk_t *trunk, int conn_state, int req_state) CC_HINT(nonnull);
779/** @} */
780
781/** @name Request state signalling
782 * @{
783 */
785
787
789
791
793
795
797
799
801/** @} */
802
803/** @name (R)enqueue and alloc requests
804 * @{
805 */
806uint64_t trunk_connection_requests_requeue(trunk_connection_t *tconn, int states, uint64_t max,
807 bool fail_bound) CC_HINT(nonnull);
808
810
811trunk_request_t *trunk_request_alloc(trunk_t *trunk, request_t *request) CC_HINT(nonnull(1));
812
814 void *preq, void *rctx) CC_HINT(nonnull(2));
815
817
819 request_t *request, void *preq, void *rctx,
820 bool ignore_limits) CC_HINT(nonnull(2));
821
822#ifndef NDEBUG
823void trunk_request_state_log(fr_log_t const *log, fr_log_type_t log_type, char const *file, int line,
824 trunk_request_t const *treq);
825#endif
826/** @} */
827
828/** @name Dequeue protocol requests and cancellations
829 * @{
830 */
832
834/** @} */
835
836/** @name Connection state signalling
837 *
838 * The following states are signalled from I/O event handlers:
839 *
840 * - writable - The connection is writable (the muxer will be called).
841 * - readable - The connection is readable (the demuxer will be called).
842 * - reconnect - The connection is likely bad and should be reconnected.
843 * If the code signalling has access to the conn, connection_signal_reconnect
844 * can be used instead of trunk_connection_signal_reconnect.
845 *
846 * The following states are signalled to control whether a connection may be
847 * assigned new requests:
848 *
849 * - inactive - The connection cannot accept any new requests. Either due to
850 * congestion or some other administrative reason.
851 * - active - The connection can, once again, accept new requests.
852 *
853 * Note: In normal operation a connection will automatically transition between
854 * the active and inactive states if conf->max_req_per_conn is specified and the
855 * number of pending requests on that connection are equal to that number.
856 * If however, the connection has previously been signalled inactive, it will not
857 * automatically be reactivated once the number of requests drops below
858 * max_req_per_conn.
859 *
860 * For other connection states the trunk API should not be signalled directly.
861 * It will be informed by "watch" callbacks inserted into the #connection_t as
862 * to when the connection changes state.
863 *
864 * #trunk_connection_signal_active does not need to be called in any of the
865 * #connection_t state callbacks. It is only used to activate a connection
866 * which has been previously marked inactive using
867 * #trunk_connection_signal_inactive.
868 *
869 * If #trunk_connection_signal_inactive is being used to remove a congested
870 * connection from the active list (i.e. on receipt of an explicit protocol level
871 * congestion notification), consider calling #trunk_connection_requests_requeue
872 * with the TRUNK_REQUEST_STATE_PENDING state to redistribute that connection's
873 * backlog to other connections in the trunk.
874 *
875 * @{
876 */
878
880
882
884
886
887bool trunk_connection_in_state(trunk_connection_t *tconn, int state);
888/** @} */
889
890/** @name Connection Callbacks
891 * @{
892 */
893void trunk_connection_callback_writable(fr_event_list_t *el, int fd, int flags, void *uctx);
894
895void trunk_connection_callback_readable(fr_event_list_t *el, int fd, int flags, void *uctx);
896/** @} */
897
898/** @name Connection management
899 * @{
900 */
901void trunk_reconnect(trunk_t *trunk, int state, connection_reason_t reason) CC_HINT(nonnull);
902/** @} */
903
904/** @name Trunk allocation
905 * @{
906 */
907int trunk_start(trunk_t *trunk) CC_HINT(nonnull);
908
909void trunk_connection_manage_start(trunk_t *trunk) CC_HINT(nonnull);
910
911void trunk_connection_manage_stop(trunk_t *trunk) CC_HINT(nonnull);
912
914
915trunk_t *trunk_alloc(TALLOC_CTX *ctx, fr_event_list_t *el,
916 trunk_io_funcs_t const *funcs, trunk_conf_t const *conf,
917 char const *log_prefix, void const *uctx, bool delay_start,
918 fr_pair_list_t *trigger_args) CC_HINT(nonnull(2, 3, 4));
919/** @} */
920
921/** @name Watchers
922 * @{
923 */
925 trunk_watch_t watch, bool oneshot, void const *uctx) CC_HINT(nonnull(1));
926
927int trunk_del_watch(trunk_t *trunk, trunk_state_t state, trunk_watch_t watch);
928/** @} */
929
930#ifndef TALLOC_GET_TYPE_ABORT_NOOP
931void CC_HINT(nonnull(1)) trunk_verify(char const *file, int line, trunk_t *trunk);
932void CC_HINT(nonnull(1)) trunk_connection_verify(char const *file, int line, trunk_connection_t *tconn);
933void CC_HINT(nonnull(1)) trunk_request_verify(char const *file, int line, trunk_request_t *treq);
934
935# define TRUNK_VERIFY(_trunk) trunk_verify(__FILE__, __LINE__, _trunk)
936# define TRUNK_CONNECTION_VERIFY(_tconn) trunk_connection_verify(__FILE__, __LINE__, _tconn)
937# define TRUNK_REQUEST_VERIFY(_treq) trunk_request_verify(__FILE__, __LINE__, _treq)
938#elif !defined(NDEBUG)
939# define TRUNK_VERIFY(_trunk) fr_assert(_trunk)
940# define TRUNK_CONNECTION_VERIFY(_tconn) fr_assert(_tconn)
941# define TRUNK_REQUEST_VERIFY(_treq) fr_assert(_treq)
942#else
943# define TRUNK_VERIFY(_trunk)
944# define TRUNK_CONNECTION_VERIFY(_tconn)
945# define TRUNK_REQUEST_VERIFY(_treq)
946#endif
947
948bool trunk_search(trunk_t *trunk, void *ptr);
949bool trunk_connection_search(trunk_connection_t *tconn, void *ptr);
950bool trunk_request_search(trunk_request_t *treq, void *ptr);
951
952#undef _CONST
953
954/** Helper macro for building generic trunk notify callback
955 *
956 * @param _name of the callback function to build
957 * @param _type of the conn->h handle. Needs to contain an fd element.
958 */
959#define TRUNK_NOTIFY_FUNC(_name, _type) \
960static void _conn_writeable(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx) \
961{ \
962 trunk_connection_t *tconn = talloc_get_type_abort(uctx, trunk_connection_t); \
963 trunk_connection_signal_writable(tconn); \
964} \
965static void _conn_readable(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx) \
966{ \
967 trunk_connection_t *tconn = talloc_get_type_abort(uctx, trunk_connection_t); \
968 trunk_connection_signal_readable(tconn); \
969} \
970static void _conn_error(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, int fd_errno, void *uctx) \
971{ \
972 trunk_connection_t *tconn = talloc_get_type_abort(uctx, trunk_connection_t); \
973 if (fd_errno) ERROR("%s - Connection failed: %s", tconn->conn->name, fr_syserror(fd_errno)); \
974 connection_signal_reconnect(tconn->conn, CONNECTION_FAILED); \
975} \
976CC_NO_UBSAN(function) /* UBSAN: false positive - public vs private connection_t trips --fsanitize=function*/ \
977static void _name(trunk_connection_t *tconn, connection_t *conn, \
978 fr_event_list_t *el, trunk_connection_event_t notify_on, UNUSED void *uctx) \
979{ \
980 _type *c = talloc_get_type_abort(conn->h, _type); \
981 fr_event_fd_cb_t read_fn = NULL, write_fn = NULL; \
982 switch (notify_on) { \
983 case TRUNK_CONN_EVENT_NONE: \
984 fr_event_fd_delete(el, c->fd, FR_EVENT_FILTER_IO); \
985 return; \
986 case TRUNK_CONN_EVENT_READ: \
987 read_fn = _conn_readable; \
988 break; \
989 case TRUNK_CONN_EVENT_WRITE: \
990 write_fn = _conn_writeable; \
991 break; \
992 case TRUNK_CONN_EVENT_BOTH: \
993 read_fn = _conn_readable; \
994 write_fn = _conn_writeable; \
995 break; \
996 } \
997 if (fr_event_fd_insert(c, NULL, el, c->fd, read_fn, write_fn, _conn_error, tconn) <0) { \
998 PERROR("Failed inserting FD event"); \
999 trunk_connection_signal_reconnect(tconn, CONNECTION_FAILED); \
1000 } \
1001}
1002
1003#ifdef __cplusplus
1004}
1005#endif
int const char * file
Definition acutest.h:702
int const char int line
Definition acutest.h:702
#define RCSIDH(h, id)
Definition build.h:507
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
connection_reason_t
Definition connection.h:84
int8_t(* fr_heap_cmp_t)(void const *a, void const *b)
Comparator to order heap elements.
Definition heap.h:54
Stores all information relating to an event list.
Definition event.c:377
fr_log_type_t
Definition log.h:51
unsigned short uint16_t
unsigned int uint32_t
static rs_t * conf
Definition radsniff.c:52
Definition log.h:93
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
"server local" time.
Definition time.h:69
Associates request queues with a connection.
Definition trunk.c:133
Wraps a normal request.
Definition trunk.c:99
Main trunk management handle.
Definition trunk.c:215
An entry in a trunk watch function list.
Definition trunk.c:185
bool trunk_search(trunk_t *trunk, void *ptr)
Definition trunk.c:5235
trunk_request_complete_t request_complete
Request is complete, interpret the response contained in preq.
Definition trunk.h:762
void trunk_request_free(trunk_request_t **treq)
If the trunk request is freed then update the target requests.
Definition trunk.c:2362
trunk_connection_notify_t connection_notify
Update the I/O event registrations for.
Definition trunk.h:740
int trunk_connection_pop_cancellation(trunk_request_t **treq_out, trunk_connection_t *tconn)
Pop a cancellation request off a connection's cancellation queue.
Definition trunk.c:3882
int trunk_connection_manage_schedule(trunk_t *trunk)
Schedule a trunk management event for the next time the event loop is executed.
Definition trunk.c:4877
trunk_enqueue_t trunk_request_enqueue(trunk_request_t **treq, trunk_t *trunk, request_t *request, void *preq, void *rctx))
Enqueue a request that needs data written to the trunk.
Definition trunk.c:2633
uint16_t max
Maximum number of connections in the trunk.
Definition trunk.h:232
uint32_t max_req_per_conn
Maximum requests per connection.
Definition trunk.h:241
void trunk_verify(char const *file, int line, trunk_t *trunk)
Verify a trunk.
Definition trunk.c:5103
fr_time_t _CONST last_write_success
Last time we wrote to the connection.
Definition trunk.h:321
trunk_t *_CONST trunk
Trunk this request belongs to.
Definition trunk.h:352
int trunk_start(trunk_t *trunk)
Start the trunk running.
Definition trunk.c:4812
bool backlog_on_failed_conn
Assign requests to the backlog when there are no available connections and the last connection event ...
Definition trunk.h:282
void(* trunk_connection_notify_t)(trunk_connection_t *tconn, connection_t *conn, fr_event_list_t *el, trunk_connection_event_t notify_on, void *uctx)
Inform the trunk API client which I/O events the trunk wants to receive.
Definition trunk.h:460
void trunk_request_signal_partial(trunk_request_t *treq)
Signal a partial write.
Definition trunk.c:2069
void trunk_request_signal_fail(trunk_request_t *treq)
Signal that a trunk request failed.
Definition trunk.c:2172
void trunk_request_signal_cancel_sent(trunk_request_t *treq)
Signal that a remote server has been notified of the cancellation.
Definition trunk.c:2300
void trunk_connection_signal_readable(trunk_connection_t *tconn)
Signal that a trunk connection is readable.
Definition trunk.c:3968
uint16_t min
Shouldn't let connections drop below this number.
Definition trunk.h:230
void *_CONST rctx
Resume ctx of the module.
Definition trunk.h:358
trunk_t *_CONST trunk
Trunk this connection belongs to.
Definition trunk.h:380
fr_heap_cmp_t connection_prioritise
Ordering function for connections.
Definition trunk.h:742
uint32_t trunk_request_count_by_connection(trunk_connection_t const *tconn, int req_state)
Return the count number of requests associated with a trunk connection.
Definition trunk.c:2926
trunk_connection_state_t
Used for sanity checks and to track which list the connection is in.
Definition trunk.h:87
@ TRUNK_CONN_FULL
Connection is full and can't accept any more requests.
Definition trunk.h:95
@ TRUNK_CONN_CONNECTING
Connection is connecting.
Definition trunk.h:90
@ TRUNK_CONN_DRAINING
Connection will be closed once it has no more outstanding requests, if it's not reactivated.
Definition trunk.h:101
@ TRUNK_CONN_INACTIVE_DRAINING
Connection is inactive, can't accept any more requests, and will be closed once it has no more outsta...
Definition trunk.h:97
@ TRUNK_CONN_INACTIVE
Connection is inactive and can't accept any more requests.
Definition trunk.h:96
@ TRUNK_CONN_HALTED
Halted, ready to be freed.
Definition trunk.h:88
@ TRUNK_CONN_CLOSED
Connection was closed, either explicitly or due to failure.
Definition trunk.h:94
@ TRUNK_CONN_INIT
In the initial state.
Definition trunk.h:89
@ TRUNK_CONN_DRAINING_TO_FREE
Connection will be closed once it has no more outstanding requests.
Definition trunk.h:103
@ TRUNK_CONN_ACTIVE
Connection is connected and ready to service requests.
Definition trunk.h:91
trunk_t * trunk_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, trunk_io_funcs_t const *funcs, trunk_conf_t const *conf, char const *log_prefix, void const *uctx, bool delay_start, fr_pair_list_t *trigger_args))
Allocate a new collection of connections.
Definition trunk.c:4995
unsigned req_pool_headers
How many chunk headers the talloc pool allocated with the treq should contain.
Definition trunk.h:267
void(* trunk_request_mux_t)(fr_event_list_t *el, trunk_connection_t *tconn, connection_t *conn, void *uctx)
Multiplex one or more requests into a single connection.
Definition trunk.h:512
request_t *_CONST request
The request that we're writing the data on behalf of.
Definition trunk.h:360
uint64_t trunk_connection_requests_requeue(trunk_connection_t *tconn, int states, uint64_t max, bool fail_bound)
Move requests off of a connection and requeue elsewhere.
Definition trunk.c:2050
fr_time_t _CONST last_open
Last time the connection management function opened a connection.
Definition trunk.h:311
void trunk_connection_callback_readable(fr_event_list_t *el, int fd, int flags, void *uctx)
fr_time_delta_t idle_timeout
how long a connection can remain idle for
Definition trunk.h:251
trunk_connection_state_t _CONST state
What state the connection is in.
Definition trunk.h:372
size_t req_pool_size
The size of the talloc pool allocated with the treq.
Definition trunk.h:270
void trunk_reconnect(trunk_t *trunk, int state, connection_reason_t reason)
Force the trunk to re-establish its connections.
Definition trunk.c:4773
trunk_enqueue_t trunk_request_requeue(trunk_request_t *treq)
Re-enqueue a request on the same connection.
Definition trunk.c:2722
uint64_t max_uses
The maximum time a connection can be used.
Definition trunk.h:247
fr_time_delta_t lifetime
Time between reconnects.
Definition trunk.h:249
uint16_t connecting
Maximum number of connections that can be in the connecting state.
Definition trunk.h:234
trunk_request_fail_t request_fail
Request failed, write out a canned response.
Definition trunk.h:765
uint64_t _CONST req_alloc_reused
How many requests were reused.
Definition trunk.h:335
uint32_t max_backlog
Maximum number of requests that can be in the backlog.
Definition trunk.h:245
void trunk_request_signal_cancel_complete(trunk_request_t *treq)
Signal that a remote server acked our cancellation.
Definition trunk.c:2324
bool conn_triggers
Do we run connection related triggers?
Definition trunk.h:286
fr_time_t _CONST last_failed
Last time a connection failed.
Definition trunk.h:319
void(* trunk_request_complete_t)(request_t *request, void *preq, void *rctx, void *uctx)
Write a successful result to the rctx so that the trunk API client is aware of the result.
Definition trunk.h:683
int trunk_connection_pop_request(trunk_request_t **treq_out, trunk_connection_t *tconn)
Pop a request off a connection's pending queue.
Definition trunk.c:3930
void trunk_request_signal_cancel(trunk_request_t *treq)
Cancel a trunk request.
Definition trunk.c:2192
int trunk_del_watch(trunk_t *trunk, trunk_state_t state, trunk_watch_t watch)
Remove a watch function from a trunk state list.
Definition trunk.c:869
void(* trunk_request_fail_t)(request_t *request, void *preq, void *rctx, trunk_request_state_t state, void *uctx)
Write a failure result to the rctx so that the trunk API client is aware that the request failed.
Definition trunk.h:701
uint16_t trunk_connection_count_by_state(trunk_t *trunk, int conn_state)
Return the count number of connections in the specified states.
Definition trunk.c:2902
connection_conf_t const * conn_conf
Connection configuration.
Definition trunk.h:226
trunk_enqueue_t trunk_request_enqueue_on_conn(trunk_request_t **treq_out, trunk_connection_t *tconn, request_t *request, void *preq, void *rctx, bool ignore_limits))
Enqueue additional requests on a specific connection.
Definition trunk.c:2787
trunk_request_free_t request_free
Free the preq and any resources it holds and provide a chance to mark the request as runnable.
Definition trunk.h:767
void(* trunk_request_cancel_t)(connection_t *conn, void *preq_to_reset, trunk_cancel_reason_t reason, void *uctx)
Remove an outstanding "sent" request from a tracking/matching structure.
Definition trunk.h:653
trunk_request_state_t _CONST state
Which list the request is now located in.
Definition trunk.h:350
fr_time_t _CONST last_write_success
Last time we wrote to the connection.
Definition trunk.h:376
trunk_connection_t *_CONST tconn
Connection this request belongs to.
Definition trunk.h:354
void(* trunk_request_demux_t)(fr_event_list_t *el, trunk_connection_t *tconn, connection_t *conn, void *uctx)
Demultiplex on or more responses, reading them from a connection, decoding them, and matching them wi...
Definition trunk.h:546
trunk_connection_alloc_t connection_alloc
Allocate a new connection_t.
Definition trunk.h:738
fr_time_t _CONST last_read_success
Last time we read a response.
Definition trunk.h:323
fr_time_t _CONST last_below_target
Last time average utilisation went below the target value.
Definition trunk.h:308
conf_parser_t const trunk_config[]
Config parser definitions to populate a trunk_conf_t.
Definition trunk.c:341
fr_time_t _CONST last_read_success
Last time we read from the connection.
Definition trunk.h:378
#define _CONST
Definition trunk.h:47
fr_time_delta_t close_delay
How long we must be below target utilisation to close an existing connection.
Definition trunk.h:256
uint16_t start
How many connections to start.
Definition trunk.h:228
fr_time_delta_t req_cleanup_delay
How long must a request in the unassigned (free) list not have been used for before it's cleaned up a...
Definition trunk.h:260
trunk_request_mux_t request_mux
Definition trunk.h:747
bool always_writable
Set to true if our ability to write requests to a connection handle is not dependent on the state of ...
Definition trunk.h:272
trunk_request_conn_release_t request_conn_release
Any connection specific resources should be removed from the treq as it's about to be moved or freed.
Definition trunk.h:758
trunk_connection_event_t
What type of I/O events the trunk connection is currently interested in receiving.
Definition trunk.h:72
@ TRUNK_CONN_EVENT_BOTH
Trunk should be notified if a connection is readable or writable.
Definition trunk.h:79
@ TRUNK_CONN_EVENT_WRITE
Trunk should be notified if a connection is writable.
Definition trunk.h:77
@ TRUNK_CONN_EVENT_NONE
Don't notify the trunk on connection state changes.
Definition trunk.h:73
@ TRUNK_CONN_EVENT_READ
Trunk should be notified if a connection is readable.
Definition trunk.h:75
trunk_request_cancel_t request_cancel
Request should be removed from tracking and should be reset to its initial state.
Definition trunk.h:755
void trunk_connection_manage_stop(trunk_t *trunk)
Stop the trunk from opening and closing connections in response to load.
Definition trunk.c:4867
void trunk_connection_signal_active(trunk_connection_t *tconn)
Signal a trunk connection is no longer full.
Definition trunk.c:4007
fr_heap_cmp_t request_prioritise
Ordering function for requests.
Definition trunk.h:744
CONF_SECTION * req_trigger_cs
Module conf section to find request trigger section in.
Definition trunk.h:290
uint64_t _CONST req_alloc
The number of requests currently allocated that have not been freed or returned to the free list.
Definition trunk.h:329
trunk_cancel_reason_t
Reasons for a request being cancelled.
Definition trunk.h:55
@ TRUNK_CANCEL_REASON_NONE
Request has not been cancelled.
Definition trunk.h:56
@ TRUNK_CANCEL_REASON_SIGNAL
Request cancelled due to a signal.
Definition trunk.h:57
@ TRUNK_CANCEL_REASON_REQUEUE
A previously sent request is being requeued.
Definition trunk.h:59
@ TRUNK_CANCEL_REASON_MOVE
Request cancelled because it's being moved.
Definition trunk.h:58
bool req_triggers
Do we run request related triggers?
Definition trunk.h:289
uint64_t _CONST req_alloc_new
How many requests we've allocated.
Definition trunk.h:333
fr_time_delta_t open_delay
How long we must be above target utilisation to spawn a new connection.
Definition trunk.h:253
connection_t *_CONST conn
The underlying connection.
Definition trunk.h:374
trunk_state_t
Definition trunk.h:62
@ TRUNK_STATE_MAX
Definition trunk.h:66
@ TRUNK_STATE_PENDING
Trunk has connections, but none are active.
Definition trunk.h:65
@ TRUNK_STATE_ACTIVE
Trunk has active connections.
Definition trunk.h:64
@ TRUNK_STATE_IDLE
Trunk has no connections.
Definition trunk.h:63
trunk_request_demux_t request_demux
!< Write one or more requests to a connection.
Definition trunk.h:749
fr_time_t _CONST last_closed
Last time the connection management function closed a connection.
Definition trunk.h:314
void(* trunk_watch_t)(trunk_t *trunk, trunk_state_t prev, trunk_state_t state, void *uctx)
Receive a notification when a trunk enters a particular state.
Definition trunk.h:729
fr_time_delta_t manage_interval
How often we run the management algorithm to open/close connections.
Definition trunk.h:264
void trunk_connection_manage_start(trunk_t *trunk)
Allow the trunk to open and close connections in response to load.
Definition trunk.c:4856
void trunk_connection_signal_inactive(trunk_connection_t *tconn)
Signal a trunk connection cannot accept more requests.
Definition trunk.c:3984
void trunk_connection_verify(char const *file, int line, trunk_connection_t *tconn)
Definition trunk.c:5164
connection_t *(* trunk_connection_alloc_t)(trunk_connection_t *tconn, fr_event_list_t *el, connection_conf_t const *conf, char const *log_prefix, void *uctx)
Allocate a new connection for the trunk.
Definition trunk.h:437
trunk_enqueue_t
Definition trunk.h:149
@ TRUNK_ENQUEUE_DST_UNAVAILABLE
Destination is down.
Definition trunk.h:154
@ TRUNK_ENQUEUE_FAIL
General failure.
Definition trunk.h:155
@ TRUNK_ENQUEUE_OK
Operation was successful.
Definition trunk.h:151
@ TRUNK_ENQUEUE_NO_CAPACITY
At maximum number of connections, and no connection has capacity.
Definition trunk.h:152
@ TRUNK_ENQUEUE_IN_BACKLOG
Request should be enqueued in backlog.
Definition trunk.h:150
void trunk_request_verify(char const *file, int line, trunk_request_t *treq)
Definition trunk.c:5224
uint64_t trunk_request_count_by_state(trunk_t *trunk, int conn_state, int req_state)
Return a count of requests on a connection in a specific state.
Definition trunk.c:4570
void trunk_request_signal_cancel_partial(trunk_request_t *treq)
Signal a partial cancel write.
Definition trunk.c:2276
void trunk_request_signal_sent(trunk_request_t *treq)
Signal that the request was written to a connection successfully.
Definition trunk.c:2090
void *_CONST preq
Data for the muxer to write to the connection.
Definition trunk.h:356
bool trunk_connection_search(trunk_connection_t *tconn, void *ptr)
Definition trunk.c:5280
uint32_t target_req_per_conn
How many pending requests should ideally be running on each connection.
Definition trunk.h:237
void trunk_request_signal_complete(trunk_request_t *treq)
Signal that a trunk request is complete.
Definition trunk.c:2134
void trunk_connection_signal_reconnect(trunk_connection_t *tconn, connection_reason_t reason)
Signal a trunk connection is no longer viable.
Definition trunk.c:4046
fr_time_t _CONST last_connected
Last time a connection connected.
Definition trunk.h:317
void(* trunk_request_cancel_mux_t)(fr_event_list_t *el, trunk_connection_t *tconn, connection_t *conn, void *uctx)
Inform a remote service like a datastore that a request should be cancelled.
Definition trunk.h:580
void trunk_connection_signal_writable(trunk_connection_t *tconn)
Signal that a trunk connection is writable.
Definition trunk.c:3950
trunk_request_cancel_mux_t request_cancel_mux
!< Read one or more requests from a connection.
Definition trunk.h:751
bool trunk_request_search(trunk_request_t *treq, void *ptr)
Definition trunk.c:5338
trunk_request_t * trunk_request_alloc(trunk_t *trunk, request_t *request))
(Pre-)Allocate a new trunk request
Definition trunk.c:2518
void(* trunk_request_conn_release_t)(connection_t *conn, void *preq_to_reset, void *uctx)
Free connection specific resources from a treq, as the treq is being removed from a connection.
Definition trunk.h:669
void trunk_connection_callback_writable(fr_event_list_t *el, int fd, int flags, void *uctx)
trunk_request_state_t
Used for sanity checks and to simplify freeing.
Definition trunk.h:162
@ TRUNK_REQUEST_STATE_PARTIAL
Some of the request was written to the socket, more of it should be written later.
Definition trunk.h:171
@ TRUNK_REQUEST_STATE_REAPABLE
Request has been written, needs to persist, but we are not currently waiting for any response.
Definition trunk.h:174
@ TRUNK_REQUEST_STATE_UNASSIGNED
Transition state - Request currently not assigned to any connection.
Definition trunk.h:166
@ TRUNK_REQUEST_STATE_INIT
Initial state.
Definition trunk.h:163
@ TRUNK_REQUEST_STATE_CANCEL_SENT
We've informed the remote server that the request has been cancelled.
Definition trunk.h:186
@ TRUNK_REQUEST_STATE_COMPLETE
The request is complete.
Definition trunk.h:183
@ TRUNK_REQUEST_STATE_FAILED
The request failed.
Definition trunk.h:184
@ TRUNK_REQUEST_STATE_CANCEL
A request on a particular socket was cancel.
Definition trunk.h:185
@ TRUNK_REQUEST_STATE_CANCEL_PARTIAL
We partially wrote a cancellation request.
Definition trunk.h:188
@ TRUNK_REQUEST_STATE_BACKLOG
In the backlog.
Definition trunk.h:168
@ TRUNK_REQUEST_STATE_CANCEL_COMPLETE
Remote server has acknowledged our cancellation.
Definition trunk.h:189
@ TRUNK_REQUEST_STATE_PENDING
In the queue of a connection and is pending writing.
Definition trunk.h:169
@ TRUNK_REQUEST_STATE_SENT
Was written to a socket. Waiting for a response.
Definition trunk.h:173
void(* trunk_request_free_t)(request_t *request, void *preq_to_free, void *uctx)
Free resources associated with a trunk request.
Definition trunk.h:720
trunk_state_t _CONST state
Current state of the trunk.
Definition trunk.h:338
void trunk_request_state_log(fr_log_t const *log, fr_log_type_t log_type, char const *file, int line, trunk_request_t const *treq)
Definition trunk.c:2875
bool trunk_connection_in_state(trunk_connection_t *tconn, int state)
Returns true if the trunk connection is in one of the specified states.
Definition trunk.c:4094
void trunk_request_signal_reapable(trunk_request_t *treq)
Signal that the request was written to a connection successfully, but no response is expected.
Definition trunk.c:2112
trunk_watch_entry_t * trunk_add_watch(trunk_t *trunk, trunk_state_t state, trunk_watch_t watch, bool oneshot, void const *uctx))
Add a watch entry to the trunk state list.
Definition trunk.c:903
CONF_SECTION * conn_trigger_cs
Module conf section to find connection trigger section in.
Definition trunk.h:287
fr_time_t _CONST last_above_target
Last time average utilisation went above the target value.
Definition trunk.h:305
Common configuration parameters for a trunk.
Definition trunk.h:225
Public fields for the trunk connection.
Definition trunk.h:371
I/O functions to pass to trunk_alloc.
Definition trunk.h:737
Public fields for the trunk.
Definition trunk.h:301
Public fields for the trunk request.
Definition trunk.h:349
static fr_event_list_t * el
int nonnull(2, 5))