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: 6f1466b58937e07ea2f553b7f559f2f6df5ec5d3 $
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: 6f1466b58937e07ea2f553b7f559f2f6df5ec5d3 $")
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.
284
285 bool conn_triggers; //!< Do we run connection related triggers?
286 CONF_SECTION *conn_trigger_cs; //!< Module conf section to find connection trigger section in.
287
288 bool req_triggers; //!< Do we run request related triggers?
289 CONF_SECTION *req_trigger_cs; //!< Module conf section to find request trigger section in.
291
292/** Public fields for the trunk
293 *
294 * This saves the overhead of using accessors for commonly used fields in
295 * the trunk.
296 *
297 * Though these fields are public, they should _NOT_ be modified by clients of
298 * the trunk API.
299 */
301 /** @name Last time an event occurred
302 * @{
303 */
304 fr_time_t _CONST last_above_target; //!< Last time average utilisation went above
305 ///< the target value.
306
307 fr_time_t _CONST last_below_target; //!< Last time average utilisation went below
308 ///< the target value.
309
310 fr_time_t _CONST last_open; //!< Last time the connection management
311 ///< function opened a connection.
312
313 fr_time_t _CONST last_closed; //!< Last time the connection management
314 ///< function closed a connection.
315
316 fr_time_t _CONST last_connected; //!< Last time a connection connected.
317
318 fr_time_t _CONST last_failed; //!< Last time a connection failed.
319
320 fr_time_t _CONST last_write_success; //!< Last time we wrote to the connection
321
322 fr_time_t _CONST last_read_success; //!< Last time we read a response.
323 /** @} */
324
325 /** @name Statistics
326 * @{
327 */
328 uint64_t _CONST req_alloc; //!< The number of requests currently
329 ///< allocated that have not been freed
330 ///< or returned to the free list.
331
332 uint64_t _CONST req_alloc_new; //!< How many requests we've allocated.
333
334 uint64_t _CONST req_alloc_reused; //!< How many requests were reused.
335 /** @} */
336
337 trunk_state_t _CONST state; //!< Current state of the trunk.
338};
339
340/** Public fields for the trunk request
341 *
342 * This saves the overhead of using accessors for commonly used fields in trunk
343 * requests.
344 *
345 * Though these fields are public, they should _NOT_ be modified by clients of
346 * the trunk API.
347 */
349 trunk_request_state_t _CONST state; //!< Which list the request is now located in.
350
351 trunk_t * _CONST trunk; //!< Trunk this request belongs to.
352
353 trunk_connection_t * _CONST tconn; //!< Connection this request belongs to.
354
355 void * _CONST preq; //!< Data for the muxer to write to the connection.
356
357 void * _CONST rctx; //!< Resume ctx of the module.
358
359 request_t * _CONST request; //!< The request that we're writing the data on behalf of.
360};
361
362/** Public fields for the trunk connection
363 *
364 * This saves the overhead of using accessors for commonly used fields in trunk
365 * connections.
366 *
367 * Though these fields are public, they should _NOT_ be modified by clients of
368 * the trunk API.
369 */
371 trunk_connection_state_t _CONST state; //!< What state the connection is in.
372
373 connection_t * _CONST conn; //!< The underlying connection.
374
375 fr_time_t _CONST last_write_success; //!< Last time we wrote to the connection
376
377 fr_time_t _CONST last_read_success; //!< Last time we read from the connection
378
379 trunk_t * _CONST trunk; //!< Trunk this connection belongs to.
380};
381
382#ifndef TRUNK_TESTS
383/** Config parser definitions to populate a trunk_conf_t
384 *
385 */
386extern conf_parser_t const trunk_config[];
387#endif
388
389/** Allocate a new connection for the trunk
390 *
391 * The trunk code only interacts with underlying connections via the connection API.
392 * As a result the trunk API is shielded from the implementation details of opening
393 * and closing connections.
394 *
395 * When creating new connections, this callback is used to allocate and configure
396 * a new #connection_t, this #connection_t and the connection API is how the
397 * trunk signals the underlying connection that it should start, reconnect, and halt (stop).
398 *
399 * The trunk must be informed when the underlying connection is readable, and,
400 * if `always_writable == false`, when the connection is writable.
401 *
402 * When the connection is readable, a read I/O handler installed by the init()
403 * callback of the #connection_t must either:
404 *
405 * - If there's no underlying I/O library, call `trunk_connection_signal_readable(tconn)`
406 * immediately, relying on the trunk demux callback to perform decoding and demuxing.
407 * - If there is an underlying I/O library, feed any incoming data to that library and
408 * then call #trunk_connection_signal_readable if the underlying I/O library
409 * indicates complete responses are ready for processing.
410 *
411 * When the connection is writable a write I/O handler installed by the open() callback
412 * of the #connection_t must either:
413 *
414 * - If `always_writable == true` - Inform the underlying I/O library that the connection
415 * is writable. The trunk API does not need to be informed as it will immediately pass
416 * through any enqueued requests to the I/O library.
417 * - If `always_writable == false` and there's an underlying I/O library,
418 * call `trunk_connection_signal_writable(tconn)` to allow the trunk mux callback
419 * to pass requests to the underlying I/O library and (optionally) signal the I/O library
420 * that the connection is writable.
421 * - If `always_writable == false` and there's no underlying I/O library,
422 * call `trunk_connection_signal_writable(tconn)` to allow the trunk mux callback
423 * to encode and write requests to a socket.
424 *
425 * @param[in] tconn The trunk connection this connection will be bound to.
426 * Should be used as the context for any #connection_t
427 * allocated.
428 * @param[in] el The event list to use for I/O and timer events.
429 * @param[in] conf Configuration of the #connection_t.
430 * @param[in] log_prefix What to prefix connection log messages with.
431 * @param[in] uctx User context data passed to #trunk_alloc.
432 * @return
433 * - A new connection_t on success (should be in the halted state - the default).
434 * - NULL on error.
435 */
436typedef connection_t *(*trunk_connection_alloc_t)(trunk_connection_t *tconn, fr_event_list_t *el,
437 connection_conf_t const *conf,
438 char const *log_prefix, void *uctx);
439
440/** Inform the trunk API client which I/O events the trunk wants to receive
441 *
442 * I/O handlers installed by this callback should call one or more of the following
443 * functions to signal that an I/O event has occurred:
444 *
445 * - trunk_connection_signal_writable - Connection is now writable.
446 * - trunk_connection_signal_readable - Connection is now readable.
447 * - trunk_connection_signal_inactive - Connection is full or congested.
448 * - trunk_connection_signal_active - Connection is no longer full or congested.
449 * - trunk_connection_signal_reconnect - Connection is inviable and should be reconnected.
450 *
451 * @param[in] tconn That should be notified of I/O events.
452 * @param[in] conn The #connection_t bound to the tconn.
453 * Use conn->h to access the
454 * connection handle or file descriptor.
455 * @param[in] el to insert I/O events into.
456 * @param[in] notify_on I/O events to signal the trunk connection on.
457 * @param[in] uctx User context data passed to #trunk_alloc.
458 */
461 trunk_connection_event_t notify_on, void *uctx);
462
463/** Multiplex one or more requests into a single connection
464 *
465 * This callback should:
466 *
467 * - Pop one or more requests from the trunk connection's pending queue using
468 * #trunk_connection_pop_request.
469 * - Serialize the protocol request data contained within the trunk request's (treq's)
470 * pctx, writing it to the provided #connection_t (or underlying connection handle).
471 * - Insert the provided treq
472 * into a tracking structure associated with the #connection_t or uctx.
473 * This tracking structure will be used later in the trunk demux callback to match
474 * protocol requests with protocol responses.
475 *
476 * If working at the socket level and a write on a file descriptor indicates
477 * less data was written than was needed, the trunk API client should track the
478 * amount of data written in the protocol request (preq), and should call
479 * `trunk_request_signal_partial(treq)`.
480 * #trunk_request_signal_partial will move the request out of the pending
481 * queue, and store it in the partial slot of the trunk connection.
482 * The next time #trunk_connection_pop_request is called, the partially written
483 * treq will be returned first. The API client should continue writing the partially
484 * written request to the socket.
485 *
486 * After calling #trunk_request_signal_partial this callback *MUST NOT*
487 * call #trunk_connection_pop_request again, and should immediately return.
488 *
489 * If the request can't be written to the connection because it the connection
490 * has become unusable, this callback should call
491 * `connection_signal_reconnect(conn)` to notify the connection API that the
492 * connection is unusable. The current request will either fail, or be
493 * re-enqueued depending on the trunk configuration.
494 *
495 * After calling #connection_signal_reconnect this callback *MUST NOT*
496 * call #trunk_connection_pop_request again, and should immediately return.
497 *
498 * If the protocol request data can't be written to the connection because the
499 * data is invalid or because some other error occurred, this callback should
500 * call `trunk_request_signal_fail(treq)`, this callback may then continue
501 * popping/processing other requests.
502 *
503 * @param[in] el For timer management.
504 * @param[in] tconn The trunk connection to dequeue trunk
505 * requests from.
506 * @param[in] conn Connection to write the request to.
507 * Use conn->h to access the
508 * connection handle or file descriptor.
509 * @param[in] uctx User context data passed to #trunk_alloc.
510 */
512 trunk_connection_t *tconn, connection_t *conn, void *uctx);
513
514/** Demultiplex on or more responses, reading them from a connection, decoding them, and matching them with their requests
515 *
516 * This callback should either:
517 *
518 * - If an underlying I/O library is used, request complete responses from
519 * the I/O library, and match the responses with a treq (trunk request)
520 * using a tracking structure associated with the #connection_t or uctx.
521 * - If no underlying I/O library is used, read responses from the #connection_t,
522 * decode those responses, and match those responses with a treq using a tracking
523 * structure associated with the #connection_t or uctx.
524 *
525 * The result (positive or negative), should be written to the rctx structure.
526 *
527 * #trunk_request_signal_complete should be used to inform the trunk
528 * that the request is now complete.
529 *
530 * If a connection appears to have become unusable, this callback should call
531 * #connection_signal_reconnect and immediately return. The current
532 * treq will either fail, or be re-enqueued depending on the trunk configuration.
533 *
534 * #trunk_request_signal_fail should *NOT* be called as this function is only
535 * used for reporting failures at an I/O layer level not failures of queries or
536 * external services.
537 *
538 * @param[in] el For timer management.
539 * @param[in] tconn The trunk connection.
540 * @param[in] conn Connection to read the request from.
541 * Use conn->h to access the
542 * connection handle or file descriptor.
543 * @param[in] uctx User context data passed to #trunk_alloc.
544 */
546 trunk_connection_t *tconn, connection_t *conn, void *uctx);
547
548/** Inform a remote service like a datastore that a request should be cancelled
549 *
550 * This callback will be called any time there are one or more requests to be
551 * cancelled and a #connection_t is writable, or as soon as a request is
552 * cancelled if `always_writable == true`.
553 *
554 * For efficiency, this callback should call #trunk_connection_pop_cancellation
555 * multiple times, and process all outstanding cancellation requests.
556 *
557 * If the response (cancel ACK) from the remote service needs to be tracked,
558 * then the treq should be inserted into a tracking tree shared with the demuxer,
559 * and #trunk_request_signal_cancel_sent should be called to move the treq into
560 * the cancel_sent state.
561 *
562 * As with the main mux callback, if a cancellation request is partially written
563 * #trunk_request_signal_cancel_partial should be called, and the amount
564 * of data written should be tracked in the preq (protocol request).
565 *
566 * When the demuxer finds a matching (cancel ACK) response, the demuxer should
567 * remove the entry from the tracking tree and call
568 * #trunk_request_signal_cancel_complete.
569 *
570 * @param[in] el To insert any timers into.
571 *
572 * @param[in] tconn The trunk connection used to dequeue
573 * cancellation requests.
574 * @param[in] conn Connection to write the request to.
575 * Use conn->h to access the
576 * connection handle or file descriptor.
577 * @param[in] uctx User context data passed to #trunk_alloc.
578 */
580 trunk_connection_t *tconn, connection_t *conn, void *uctx);
581
582/** Remove an outstanding "sent" request from a tracking/matching structure
583 *
584 * If the treq (trunk request) is in the TRUNK_REQUEST_STATE_PARTIAL or
585 * TRUNK_REQUEST_STATE_SENT states, this callback will be called prior
586 * to moving the treq to a new connection, requeueing the treq or freeing
587 * the treq.
588 *
589 * The treq, and any associated resources, should be
590 * removed from the the matching structure associated with the
591 * #connection_t or uctx.
592 *
593 * Which resources should be freed depends on the cancellation reason:
594 *
595 * - TRUNK_CANCEL_REASON_REQUEUE - If an encoded request can be
596 * reused, then it should be kept, otherwise it should be freed.
597 * Any resources like ID allocations bound to that request should
598 * also be freed.
599 * #trunk_request_conn_release_t callback will not be called in this
600 * instance and cannot be used as an alternative.
601 * - TRUNK_CANCEL_REASON_MOVE - If an encoded request can be reused
602 * it should be kept. The trunk mux callback should be aware that
603 * an encoded request may already be associated with a preq and use
604 * that instead of re-encoding the preq.
605 * If the encoded request cannot be reused it should be freed, and
606 * any fields in the preq that were modified during the last mux call
607 * (other than perhaps counters) should be reset to their initial values.
608 * Alternatively the #trunk_request_conn_release_t callback can be used for
609 * the same purpose, as that will be called before the request is moved.
610 * - TRUNK_CANCEL_REASON_SIGNAL - The encoded request and any I/O library
611 * request handled may be freed though that may (optionally) be left to
612 * another callback like #trunk_request_conn_release_t, as that will be
613 * called as the treq is removed from the conn.
614 * Note that the #trunk_request_complete_t and
615 * #trunk_request_fail_t callbacks will not be called in this
616 * instance.
617 *
618 * After this callback is complete one of several actions will be taken:
619 *
620 * - If the cancellation reason was TRUNK_CANCEL_REASON_REQUEUE the
621 * treq will be placed back into the pending list of the connection it
622 * was previously associated with.
623 * - If the cancellation reason was TRUNK_CANCEL_REASON_MOVE, the treq
624 * will move to the unassigned state, and then either be placed in the
625 * trunk backlog, or immediately enqueued on another trunk connection.
626 * - If the reason was TRUNK_CANCEL_SIGNAL
627 * - ...and a request_cancel_mux callback was provided, the
628 * the request_cancel_mux callback will be called when the connection
629 * is next writable (or immediately if `always_writable == true`) and
630 * the request_cancel_mux callback will send an explicit cancellation
631 * request to terminate any outstanding queries on remote datastores.
632 * - ...and no request_cancel_mux callback was provided, the
633 * treq will enter the unassigned state and then be freed.
634 *
635 * @note TRUNK_CANCEL_REASON_MOVE will only be set if the underlying
636 * connection is bad. A 'sent' treq will never be moved due to load
637 * balancing.
638 *
639 * @note There is no need to signal request state changes in the cancellation
640 * function. The trunk will move the request into the correct state.
641 * This callback is only to allow the API client to cleanup the preq in
642 * preparation for the cancellation event.
643 *
644 * @note Cancellation requests to a remote datastore should not be made
645 * here. If that is required, a cancel_mux function should be provided.
646 *
647 * @param[in] conn to remove request from.
648 * @param[in] preq_to_reset Preq to reset.
649 * @param[in] reason Why the request was cancelled.
650 * @param[in] uctx User context data passed to #trunk_alloc.
651 */
652typedef void (*trunk_request_cancel_t)(connection_t *conn, void *preq_to_reset,
653 trunk_cancel_reason_t reason, void *uctx);
654
655/** Free connection specific resources from a treq, as the treq is being removed from a connection
656 *
657 * Any connection specific resources that the treq currently holds must be
658 * released. Examples are connection-specific handles, ID allocations,
659 * and connection specific packets.
660 *
661 * The treq may be about to be freed or it may be being re-assigned to a new connection.
662 *
663 * @param[in] conn request will be removed from.
664 * @param[in] preq_to_reset Preq to remove connection specified resources
665 * from.
666 * @param[in] uctx User context data passed to #trunk_alloc.
667 */
668typedef void (*trunk_request_conn_release_t)(connection_t *conn, void *preq_to_reset,
669 void *uctx);
670
671/** Write a successful result to the rctx so that the trunk API client is aware of the result
672 *
673 * The rctx should be modified in such a way that indicates to the trunk API client
674 * that the request was sent using the trunk and a response was received.
675 *
676 * This function should not free any resources associated with the preq. That should
677 * be done in the request_free callback. This function should only be used to translate
678 * the contents of the preq into a result, and write it to the rctx.
679 *
680 * After this callback is complete, the request_free callback will be called if provided.
681 */
682typedef void (*trunk_request_complete_t)(request_t *request, void *preq, void *rctx, void *uctx);
683
684/** Write a failure result to the rctx so that the trunk API client is aware that the request failed
685 *
686 * The rctx should be modified in such a way that indicates to the trunk API client
687 * that the request could not be sent using the trunk.
688 *
689 * This function should not free any resources associated with the preq. That should
690 * be done in the request_free callback. This function should only be used to write
691 * a "canned" failure to the rctx.
692 *
693 * @note If a cancel function is provided, the cancel function should be used to remove
694 * active requests from any request/response matching, not the fail function.
695 * Both the cancel and fail functions will be called for a request that has been
696 * sent or partially sent.
697 *
698 * After this callback is complete, the request_free callback will be called if provided.
699 */
700typedef void (*trunk_request_fail_t)(request_t *request, void *preq, void *rctx,
701 trunk_request_state_t state, void *uctx);
702
703/** Free resources associated with a trunk request
704 *
705 * The trunk request is complete. If there's a request still associated with the
706 * trunk request, that will be provided so that it can be marked runnable, but
707 * be aware that the request_t * value will be NULL if the request was cancelled due
708 * to a signal.
709 *
710 * The preq and any associated data such as encoded packets or I/O library request
711 * handled *SHOULD* be explicitly freed by this function.
712 * The exception to this is if the preq is parented by the treq, in which case the
713 * preq will be explicitly freed when the treq is returned to the free list.
714 *
715 * @param[in] request to mark as runnable if no further processing is required.
716 * @param[in] preq_to_free As per the name.
717 * @param[in] uctx User context data passed to #trunk_alloc.
718 */
719typedef void (*trunk_request_free_t)(request_t *request, void *preq_to_free, void *uctx);
720
721/** Receive a notification when a trunk enters a particular state
722 *
723 * @param[in] trunk Being watched.
724 * @param[in] prev State we came from.
725 * @param[in] state State that was entered (the current state)
726 * @param[in] uctx that was passed to trunk_add_watch_*.
727 */
728typedef void(*trunk_watch_t)(trunk_t *trunk,
729 trunk_state_t prev, trunk_state_t state, void *uctx);
730
732
733/** I/O functions to pass to trunk_alloc
734 *
735 */
736typedef struct {
737 trunk_connection_alloc_t connection_alloc; //!< Allocate a new connection_t.
738
739 trunk_connection_notify_t connection_notify; //!< Update the I/O event registrations for
740
741 fr_heap_cmp_t connection_prioritise; //!< Ordering function for connections.
742
743 fr_heap_cmp_t request_prioritise; //!< Ordering function for requests. Controls
744 ///< where in the outbound queues they're inserted.
745
746 trunk_request_mux_t request_mux; ///!< Write one or more requests to a connection.
747
748 trunk_request_demux_t request_demux; ///!< Read one or more requests from a connection.
749
750 trunk_request_cancel_mux_t request_cancel_mux; //!< Inform an external resource that we no longer
751 ///< care about the result of any queries we
752 ///< issued for this request.
753
754 trunk_request_cancel_t request_cancel; //!< Request should be removed from tracking
755 ///< and should be reset to its initial state.
756
757 trunk_request_conn_release_t request_conn_release; //!< Any connection specific resources should be
758 ///< removed from the treq as it's about to be
759 ///< moved or freed.
760
761 trunk_request_complete_t request_complete; //!< Request is complete, interpret the response
762 ///< contained in preq.
763
764 trunk_request_fail_t request_fail; //!< Request failed, write out a canned response.
765
766 trunk_request_free_t request_free; //!< Free the preq and any resources it holds and
767 ///< provide a chance to mark the request as runnable.
769
770/** @name Statistics
771 * @{
772 */
773uint16_t trunk_connection_count_by_state(trunk_t *trunk, int conn_state) CC_HINT(nonnull);
774
775uint32_t trunk_request_count_by_connection(trunk_connection_t const *tconn, int req_state) CC_HINT(nonnull);
776
777uint64_t trunk_request_count_by_state(trunk_t *trunk, int conn_state, int req_state) CC_HINT(nonnull);
778/** @} */
779
780/** @name Request state signalling
781 * @{
782 */
784
786
788
790
792
794
796
798
800/** @} */
801
802/** @name (R)enqueue and alloc requests
803 * @{
804 */
805uint64_t trunk_connection_requests_requeue(trunk_connection_t *tconn, int states, uint64_t max,
806 bool fail_bound) CC_HINT(nonnull);
807
809
810trunk_request_t *trunk_request_alloc(trunk_t *trunk, request_t *request) CC_HINT(nonnull(1));
811
813 void *preq, void *rctx) CC_HINT(nonnull(2));
814
816
818 request_t *request, void *preq, void *rctx,
819 bool ignore_limits) CC_HINT(nonnull(2));
820
821#ifndef NDEBUG
822void trunk_request_state_log(fr_log_t const *log, fr_log_type_t log_type, char const *file, int line,
823 trunk_request_t const *treq);
824#endif
825/** @} */
826
827/** @name Dequeue protocol requests and cancellations
828 * @{
829 */
831
833/** @} */
834
835/** @name Connection state signalling
836 *
837 * The following states are signalled from I/O event handlers:
838 *
839 * - writable - The connection is writable (the muxer will be called).
840 * - readable - The connection is readable (the demuxer will be called).
841 * - reconnect - The connection is likely bad and should be reconnected.
842 * If the code signalling has access to the conn, connection_signal_reconnect
843 * can be used instead of trunk_connection_signal_reconnect.
844 *
845 * The following states are signalled to control whether a connection may be
846 * assigned new requests:
847 *
848 * - inactive - The connection cannot accept any new requests. Either due to
849 * congestion or some other administrative reason.
850 * - active - The connection can, once again, accept new requests.
851 *
852 * Note: In normal operation a connection will automatically transition between
853 * the active and inactive states if conf->max_req_per_conn is specified and the
854 * number of pending requests on that connection are equal to that number.
855 * If however, the connection has previously been signalled inactive, it will not
856 * automatically be reactivated once the number of requests drops below
857 * max_req_per_conn.
858 *
859 * For other connection states the trunk API should not be signalled directly.
860 * It will be informed by "watch" callbacks inserted into the #connection_t as
861 * to when the connection changes state.
862 *
863 * #trunk_connection_signal_active does not need to be called in any of the
864 * #connection_t state callbacks. It is only used to activate a connection
865 * which has been previously marked inactive using
866 * #trunk_connection_signal_inactive.
867 *
868 * If #trunk_connection_signal_inactive is being used to remove a congested
869 * connection from the active list (i.e. on receipt of an explicit protocol level
870 * congestion notification), consider calling #trunk_connection_requests_requeue
871 * with the TRUNK_REQUEST_STATE_PENDING state to redistribute that connection's
872 * backlog to other connections in the trunk.
873 *
874 * @{
875 */
877
879
881
883
885
886bool trunk_connection_in_state(trunk_connection_t *tconn, int state);
887/** @} */
888
889/** @name Connection Callbacks
890 * @{
891 */
892void trunk_connection_callback_writable(fr_event_list_t *el, int fd, int flags, void *uctx);
893
894void trunk_connection_callback_readable(fr_event_list_t *el, int fd, int flags, void *uctx);
895/** @} */
896
897/** @name Connection management
898 * @{
899 */
900void trunk_reconnect(trunk_t *trunk, int state, connection_reason_t reason) CC_HINT(nonnull);
901/** @} */
902
903/** @name Trunk allocation
904 * @{
905 */
906int trunk_start(trunk_t *trunk) CC_HINT(nonnull);
907
908void trunk_connection_manage_start(trunk_t *trunk) CC_HINT(nonnull);
909
910void trunk_connection_manage_stop(trunk_t *trunk) CC_HINT(nonnull);
911
913
914trunk_t *trunk_alloc(TALLOC_CTX *ctx, fr_event_list_t *el,
915 trunk_io_funcs_t const *funcs, trunk_conf_t const *conf,
916 char const *log_prefix, void const *uctx, bool delay_start,
917 fr_pair_list_t *trigger_args) CC_HINT(nonnull(2, 3, 4));
918/** @} */
919
920/** @name Watchers
921 * @{
922 */
924 trunk_watch_t watch, bool oneshot, void const *uctx) CC_HINT(nonnull(1));
925
926int trunk_del_watch(trunk_t *trunk, trunk_state_t state, trunk_watch_t watch);
927/** @} */
928
929#ifndef TALLOC_GET_TYPE_ABORT_NOOP
930void CC_HINT(nonnull(1)) trunk_verify(char const *file, int line, trunk_t *trunk);
931void CC_HINT(nonnull(1)) trunk_connection_verify(char const *file, int line, trunk_connection_t *tconn);
932void CC_HINT(nonnull(1)) trunk_request_verify(char const *file, int line, trunk_request_t *treq);
933
934# define TRUNK_VERIFY(_trunk) trunk_verify(__FILE__, __LINE__, _trunk)
935# define TRUNK_CONNECTION_VERIFY(_tconn) trunk_connection_verify(__FILE__, __LINE__, _tconn)
936# define TRUNK_REQUEST_VERIFY(_treq) trunk_request_verify(__FILE__, __LINE__, _treq)
937#elif !defined(NDEBUG)
938# define TRUNK_VERIFY(_trunk) fr_assert(_trunk)
939# define TRUNK_CONNECTION_VERIFY(_tconn) fr_assert(_tconn)
940# define TRUNK_REQUEST_VERIFY(_treq) fr_assert(_treq)
941#else
942# define TRUNK_VERIFY(_trunk)
943# define TRUNK_CONNECTION_VERIFY(_tconn)
944# define TRUNK_REQUEST_VERIFY(_treq)
945#endif
946
947bool trunk_search(trunk_t *trunk, void *ptr);
948bool trunk_connection_search(trunk_connection_t *tconn, void *ptr);
949bool trunk_request_search(trunk_request_t *treq, void *ptr);
950
951#undef _CONST
952
953/** Helper macro for building generic trunk notify callback
954 *
955 * @param _name of the callback function to build
956 * @param _type of the conn->h handle. Needs to contain an fd element.
957 */
958#define TRUNK_NOTIFY_FUNC(_name, _type) \
959static void _conn_writeable(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_writable(tconn); \
963} \
964static void _conn_readable(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx) \
965{ \
966 trunk_connection_t *tconn = talloc_get_type_abort(uctx, trunk_connection_t); \
967 trunk_connection_signal_readable(tconn); \
968} \
969static void _conn_error(UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, int fd_errno, void *uctx) \
970{ \
971 trunk_connection_t *tconn = talloc_get_type_abort(uctx, trunk_connection_t); \
972 if (fd_errno) ERROR("%s - Connection failed: %s", tconn->conn->name, fr_syserror(fd_errno)); \
973 connection_signal_reconnect(tconn->conn, CONNECTION_FAILED); \
974} \
975CC_NO_UBSAN(function) /* UBSAN: false positive - public vs private connection_t trips --fsanitize=function*/ \
976static void _name(trunk_connection_t *tconn, connection_t *conn, \
977 fr_event_list_t *el, trunk_connection_event_t notify_on, UNUSED void *uctx) \
978{ \
979 _type *c = talloc_get_type_abort(conn->h, _type); \
980 fr_event_fd_cb_t read_fn = NULL, write_fn = NULL; \
981 switch (notify_on) { \
982 case TRUNK_CONN_EVENT_NONE: \
983 fr_event_fd_delete(el, c->fd, FR_EVENT_FILTER_IO); \
984 return; \
985 case TRUNK_CONN_EVENT_READ: \
986 read_fn = _conn_readable; \
987 break; \
988 case TRUNK_CONN_EVENT_WRITE: \
989 write_fn = _conn_writeable; \
990 break; \
991 case TRUNK_CONN_EVENT_BOTH: \
992 read_fn = _conn_readable; \
993 write_fn = _conn_writeable; \
994 break; \
995 } \
996 if (fr_event_fd_insert(c, NULL, el, c->fd, read_fn, write_fn, _conn_error, tconn) <0) { \
997 PERROR("Failed inserting FD event"); \
998 trunk_connection_signal_reconnect(tconn, CONNECTION_FAILED); \
999 } \
1000}
1001
1002#ifdef __cplusplus
1003}
1004#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:486
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:597
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
connection_reason_t
Definition connection.h:84
int8_t(* fr_heap_cmp_t)(void const *a, void const *b)
Comparator to order heap elements.
Definition heap.h:54
Stores all information relating to an event list.
Definition event.c:377
fr_log_type_t
Definition log.h: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: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:5203
trunk_request_complete_t request_complete
Request is complete, interpret the response contained in preq.
Definition trunk.h:761
void trunk_request_free(trunk_request_t **treq)
If the trunk request is freed then update the target requests.
Definition trunk.c:2338
trunk_connection_notify_t connection_notify
Update the I/O event registrations for.
Definition trunk.h:739
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:3851
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:4845
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:2603
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:5071
fr_time_t _CONST last_write_success
Last time we wrote to the connection.
Definition trunk.h:320
trunk_t *_CONST trunk
Trunk this request belongs to.
Definition trunk.h:351
int trunk_start(trunk_t *trunk)
Start the trunk running.
Definition trunk.c:4780
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:459
void trunk_request_signal_partial(trunk_request_t *treq)
Signal a partial write.
Definition trunk.c:2045
void trunk_request_signal_fail(trunk_request_t *treq)
Signal that a trunk request failed.
Definition trunk.c:2148
void trunk_request_signal_cancel_sent(trunk_request_t *treq)
Signal that a remote server has been notified of the cancellation.
Definition trunk.c:2276
void trunk_connection_signal_readable(trunk_connection_t *tconn)
Signal that a trunk connection is readable.
Definition trunk.c:3937
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:357
trunk_t *_CONST trunk
Trunk this connection belongs to.
Definition trunk.h:379
fr_heap_cmp_t connection_prioritise
Ordering function for connections.
Definition trunk.h:741
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:2895
trunk_connection_state_t
Used for sanity checks and to track which list the connection is in.
Definition trunk.h:87
@ TRUNK_CONN_FULL
Connection is full and can't accept any more requests.
Definition trunk.h:95
@ TRUNK_CONN_CONNECTING
Connection is connecting.
Definition trunk.h:90
@ TRUNK_CONN_DRAINING
Connection will be closed once it has no more outstanding requests, if it's not reactivated.
Definition trunk.h:101
@ TRUNK_CONN_INACTIVE_DRAINING
Connection is inactive, can't accept any more requests, and will be closed once it has no more outsta...
Definition trunk.h:97
@ TRUNK_CONN_INACTIVE
Connection is inactive and can't accept any more requests.
Definition trunk.h:96
@ TRUNK_CONN_HALTED
Halted, ready to be freed.
Definition trunk.h:88
@ TRUNK_CONN_CLOSED
Connection was closed, either explicitly or due to failure.
Definition trunk.h:94
@ TRUNK_CONN_INIT
In the initial state.
Definition trunk.h:89
@ TRUNK_CONN_DRAINING_TO_FREE
Connection will be closed once it has no more outstanding requests.
Definition trunk.h:103
@ TRUNK_CONN_ACTIVE
Connection is connected and ready to service requests.
Definition trunk.h:91
trunk_t * trunk_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, trunk_io_funcs_t const *funcs, trunk_conf_t const *conf, char const *log_prefix, void const *uctx, bool delay_start, fr_pair_list_t *trigger_args))
Allocate a new collection of connections.
Definition trunk.c:4963
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:511
request_t *_CONST request
The request that we're writing the data on behalf of.
Definition trunk.h:359
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:2026
fr_time_t _CONST last_open
Last time the connection management function opened a connection.
Definition trunk.h:310
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:371
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:4741
trunk_enqueue_t trunk_request_requeue(trunk_request_t *treq)
Re-enqueue a request on the same connection.
Definition trunk.c:2692
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:764
uint64_t _CONST req_alloc_reused
How many requests were reused.
Definition trunk.h:334
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:2300
bool conn_triggers
Do we run connection related triggers?
Definition trunk.h:285
fr_time_t _CONST last_failed
Last time a connection failed.
Definition trunk.h:318
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:682
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:3899
void trunk_request_signal_cancel(trunk_request_t *treq)
Cancel a trunk request.
Definition trunk.c:2168
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:845
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:700
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:2871
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:2757
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:766
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:652
trunk_request_state_t _CONST state
Which list the request is now located in.
Definition trunk.h:349
fr_time_t _CONST last_write_success
Last time we wrote to the connection.
Definition trunk.h:375
trunk_connection_t *_CONST tconn
Connection this request belongs to.
Definition trunk.h:353
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:545
trunk_connection_alloc_t connection_alloc
Allocate a new connection_t.
Definition trunk.h:737
fr_time_t _CONST last_read_success
Last time we read a response.
Definition trunk.h:322
fr_time_t _CONST last_below_target
Last time average utilisation went below the target value.
Definition trunk.h:307
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:377
#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:746
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:757
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:754
void trunk_connection_manage_stop(trunk_t *trunk)
Stop the trunk from opening and closing connections in response to load.
Definition trunk.c:4835
void trunk_connection_signal_active(trunk_connection_t *tconn)
Signal a trunk connection is no longer full.
Definition trunk.c:3976
fr_heap_cmp_t request_prioritise
Ordering function for requests.
Definition trunk.h:743
CONF_SECTION * req_trigger_cs
Module conf section to find request trigger section in.
Definition trunk.h:289
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:328
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:288
uint64_t _CONST req_alloc_new
How many requests we've allocated.
Definition trunk.h:332
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:373
trunk_state_t
Definition trunk.h:62
@ TRUNK_STATE_MAX
Definition trunk.h:66
@ TRUNK_STATE_PENDING
Trunk has connections, but none are active.
Definition trunk.h:65
@ TRUNK_STATE_ACTIVE
Trunk has active connections.
Definition trunk.h:64
@ TRUNK_STATE_IDLE
Trunk has no connections.
Definition trunk.h:63
trunk_request_demux_t request_demux
!< Write one or more requests to a connection.
Definition trunk.h:748
fr_time_t _CONST last_closed
Last time the connection management function closed a connection.
Definition trunk.h:313
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:728
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:4824
void trunk_connection_signal_inactive(trunk_connection_t *tconn)
Signal a trunk connection cannot accept more requests.
Definition trunk.c:3953
void trunk_connection_verify(char const *file, int line, trunk_connection_t *tconn)
Definition trunk.c:5132
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:436
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:5192
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:4538
void trunk_request_signal_cancel_partial(trunk_request_t *treq)
Signal a partial cancel write.
Definition trunk.c:2252
void trunk_request_signal_sent(trunk_request_t *treq)
Signal that the request was written to a connection successfully.
Definition trunk.c:2066
void *_CONST preq
Data for the muxer to write to the connection.
Definition trunk.h:355
bool trunk_connection_search(trunk_connection_t *tconn, void *ptr)
Definition trunk.c:5248
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:2110
void trunk_connection_signal_reconnect(trunk_connection_t *tconn, connection_reason_t reason)
Signal a trunk connection is no longer viable.
Definition trunk.c:4015
fr_time_t _CONST last_connected
Last time a connection connected.
Definition trunk.h:316
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:579
void trunk_connection_signal_writable(trunk_connection_t *tconn)
Signal that a trunk connection is writable.
Definition trunk.c:3919
trunk_request_cancel_mux_t request_cancel_mux
!< Read one or more requests from a connection.
Definition trunk.h:750
bool trunk_request_search(trunk_request_t *treq, void *ptr)
Definition trunk.c:5306
trunk_request_t * trunk_request_alloc(trunk_t *trunk, request_t *request))
(Pre-)Allocate a new trunk request
Definition trunk.c:2490
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:668
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:719
trunk_state_t _CONST state
Current state of the trunk.
Definition trunk.h:337
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:2844
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:4063
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:2088
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:879
CONF_SECTION * conn_trigger_cs
Module conf section to find connection trigger section in.
Definition trunk.h:286
fr_time_t _CONST last_above_target
Last time average utilisation went above the target value.
Definition trunk.h:304
Common configuration parameters for a trunk.
Definition trunk.h:224
Public fields for the trunk connection.
Definition trunk.h:370
I/O functions to pass to trunk_alloc.
Definition trunk.h:736
Public fields for the trunk.
Definition trunk.h:300
Public fields for the trunk request.
Definition trunk.h:348
static fr_event_list_t * el
int nonnull(2, 5))