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