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