The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
#include <freeradius-devel/server/connection.h>
#include <freeradius-devel/server/request.h>
#include <freeradius-devel/server/cf_parse.h>
Go to the source code of this file.
Data Structures | |
struct | trunk_conf_t |
Common configuration parameters for a trunk. More... | |
struct | trunk_connection_pub_s |
Public fields for the trunk connection. More... | |
struct | trunk_io_funcs_t |
I/O functions to pass to trunk_alloc. More... | |
struct | trunk_pub_s |
Public fields for the trunk. More... | |
struct | trunk_request_pub_s |
Public fields for the trunk request. More... | |
Macros | |
#define | _CONST const |
#define | TRUNK_CONN_ALL |
All connection states. | |
#define | TRUNK_CONN_PROCESSING |
States where the connection may be processing requests. | |
#define | TRUNK_CONN_SERVICEABLE |
States where the connection may potentially be used to send requests. | |
#define | TRUNK_CONNECTION_VERIFY(_tconn) trunk_connection_verify(__FILE__, __LINE__, _tconn) |
#define | TRUNK_NOTIFY_FUNC(_name, _type) |
Helper macro for building generic trunk notify callback. | |
#define | TRUNK_REQUEST_STATE_ALL |
All request states. | |
#define | TRUNK_REQUEST_STATE_CANCEL_ALL |
All requests in various cancellation states. | |
#define | TRUNK_REQUEST_VERIFY(_treq) trunk_request_verify(__FILE__, __LINE__, _treq) |
#define | TRUNK_VERIFY(_trunk) trunk_verify(__FILE__, __LINE__, _trunk) |
Typedefs | |
typedef 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. | |
typedef 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. | |
typedef struct trunk_connection_pub_s | trunk_connection_t |
typedef 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. | |
typedef 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. | |
typedef 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. | |
typedef 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. | |
typedef 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 with their requests. | |
typedef 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. | |
typedef void(* | trunk_request_free_t) (request_t *request, void *preq_to_free, void *uctx) |
Free resources associated with a trunk request. | |
typedef 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. | |
typedef struct trunk_request_pub_s | trunk_request_t |
typedef struct trunk_pub_s | trunk_t |
typedef struct trunk_watch_entry_s | trunk_watch_entry_t |
typedef 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. | |
Functions | |
bool | trunk_connection_search (trunk_connection_t *tconn, void *ptr) |
void | trunk_connection_verify (char const *file, int line, trunk_connection_t *tconn) |
bool | trunk_request_search (trunk_request_t *treq, void *ptr) |
void | trunk_request_verify (char const *file, int line, trunk_request_t *treq) |
bool | trunk_search (trunk_t *trunk, void *ptr) |
void | trunk_verify (char const *file, int line, trunk_t *trunk) |
Verify a trunk. | |
Variables | |
conf_parser_t const | trunk_config [] |
Config parser definitions to populate a trunk_conf_t. | |
Statistics | |
uint16_t | trunk_connection_count_by_state (trunk_t *trunk, int conn_state) |
Return the count number of connections in the specified states. | |
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. | |
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. | |
Request state signalling | |
void | trunk_request_signal_cancel (trunk_request_t *treq) |
Cancel a trunk request. | |
void | trunk_request_signal_cancel_complete (trunk_request_t *treq) |
Signal that a remote server acked our cancellation. | |
void | trunk_request_signal_cancel_partial (trunk_request_t *treq) |
Signal a partial cancel write. | |
void | trunk_request_signal_cancel_sent (trunk_request_t *treq) |
Signal that a remote server has been notified of the cancellation. | |
void | trunk_request_signal_complete (trunk_request_t *treq) |
Signal that a trunk request is complete. | |
void | trunk_request_signal_fail (trunk_request_t *treq) |
Signal that a trunk request failed. | |
void | trunk_request_signal_partial (trunk_request_t *treq) |
Signal a partial write. | |
void | trunk_request_signal_reapable (trunk_request_t *treq) |
Signal that the request was written to a connection successfully, but no response is expected. | |
void | trunk_request_signal_sent (trunk_request_t *treq) |
Signal that the request was written to a connection successfully. | |
(R)enqueue and alloc requests | |
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. | |
trunk_request_t * | trunk_request_alloc (trunk_t *trunk, request_t *request)) |
(Pre-)Allocate a new trunk request | |
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. | |
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. | |
void | trunk_request_free (trunk_request_t **treq) |
If the trunk request is freed then update the target requests. | |
trunk_enqueue_t | trunk_request_requeue (trunk_request_t *treq) |
Re-enqueue a request on the same connection. | |
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) |
Dequeue protocol requests and cancellations | |
int | trunk_connection_pop_cancellation (trunk_request_t **treq_out, trunk_connection_t *tconn) |
Pop a cancellation request off a connection's cancellation queue. | |
int | trunk_connection_pop_request (trunk_request_t **treq_out, trunk_connection_t *tconn) |
Pop a request off a connection's pending queue. | |
Connection state signalling | |
The following states are signalled from I/O event handlers:
The following states are signalled to control whether a connection may be assigned new requests:
Note: In normal operation a connection will automatically transition between the active and inactive states if conf->max_req_per_conn is specified and the number of pending requests on that connection are equal to that number. If however, the connection has previously been signalled inactive, it will not automatically be reactivated once the number of requests drops below max_req_per_conn. For other connection states the trunk API should not be signalled directly. It will be informed by "watch" callbacks inserted into the connection_t as to when the connection changes state. trunk_connection_signal_active does not need to be called in any of the connection_t state callbacks. It is only used to activate a connection which has been previously marked inactive using trunk_connection_signal_inactive. If trunk_connection_signal_inactive is being used to remove a congested connection from the active list (i.e. on receipt of an explicit protocol level congestion notification), consider calling trunk_connection_requests_requeue with the TRUNK_REQUEST_STATE_PENDING state to redistribute that connection's backlog to other connections in the trunk. | |
bool | trunk_connection_in_state (trunk_connection_t *tconn, int state) |
Returns true if the trunk connection is in one of the specified states. | |
void | trunk_connection_signal_active (trunk_connection_t *tconn) |
Signal a trunk connection is no longer full. | |
void | trunk_connection_signal_inactive (trunk_connection_t *tconn) |
Signal a trunk connection cannot accept more requests. | |
void | trunk_connection_signal_readable (trunk_connection_t *tconn) |
Signal that a trunk connection is readable. | |
void | trunk_connection_signal_reconnect (trunk_connection_t *tconn, connection_reason_t reason) |
Signal a trunk connection is no longer viable. | |
void | trunk_connection_signal_writable (trunk_connection_t *tconn) |
Signal that a trunk connection is writable. | |
Connection Callbacks | |
void | trunk_connection_callback_readable (fr_event_list_t *el, int fd, int flags, void *uctx) |
void | trunk_connection_callback_writable (fr_event_list_t *el, int fd, int flags, void *uctx) |
Connection management | |
void | trunk_reconnect (trunk_t *trunk, int state, connection_reason_t reason) |
Force the trunk to re-establish its connections. | |
Trunk allocation | |
trunk_t * | trunk_alloc (TALLOC_CTX *ctx, fr_event_list_t *el, trunk_io_funcs_t const *funcs, trunk_conf_t const *conf, char const *log_prefix, void const *uctx, bool delay_start)) |
Allocate a new collection of connections. | |
int | trunk_connection_manage_schedule (trunk_t *trunk) |
Schedule a trunk management event for the next time the event loop is executed. | |
void | trunk_connection_manage_start (trunk_t *trunk) |
Allow the trunk to open and close connections in response to load. | |
void | trunk_connection_manage_stop (trunk_t *trunk) |
Stop the trunk from opening and closing connections in response to load. | |
int | trunk_start (trunk_t *trunk) |
Start the trunk running. | |
Watchers | |
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. | |
int | trunk_del_watch (trunk_t *trunk, trunk_state_t state, trunk_watch_t watch) |
Remove a watch function from a trunk state list. | |
struct trunk_conf_t |
Data Fields | ||
---|---|---|
bool | always_writable |
Set to true if our ability to write requests to a connection handle is not dependent on the state of the underlying connection, i.e. if the library used to implement the connection can always receive and buffer new requests irrespective of the state of the underlying socket. If this is true, trunk_connection_signal_writable does not need to be called, and requests will be enqueued as soon as they're received. |
bool | backlog_on_failed_conn | Assign requests to the backlog when there are no available connections and the last connection event was a failure, instead of failing them immediately. |
fr_time_delta_t | close_delay | How long we must be below target utilisation to close an existing connection. |
connection_conf_t const * | conn_conf | Connection configuration. |
uint16_t | connecting |
Maximum number of connections that can be in the connecting state. Used to throttle connection spawning. |
fr_time_delta_t | idle_timeout | how long a connection can remain idle for |
fr_time_delta_t | lifetime | Time between reconnects. |
fr_time_delta_t | manage_interval | How often we run the management algorithm to open/close connections. |
uint16_t | max | Maximum number of connections in the trunk. |
uint32_t | max_backlog | Maximum number of requests that can be in the backlog. |
uint32_t | max_req_per_conn |
Maximum requests per connection. Used to determine if we need to create new connections and whether we can enqueue new requests. |
uint64_t | max_uses | The maximum time a connection can be used. |
uint16_t | min | Shouldn't let connections drop below this number. |
fr_time_delta_t | open_delay | How long we must be above target utilisation to spawn a new connection. |
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 and actually freed. |
unsigned | req_pool_headers | How many chunk headers the talloc pool allocated with the treq should contain. |
size_t | req_pool_size | The size of the talloc pool allocated with the treq. |
uint16_t | start | How many connections to start. |
uint32_t | target_req_per_conn |
How many pending requests should ideally be running on each connection. Averaged across the 'active' set of connections. |
struct trunk_connection_pub_s |
Public fields for the trunk connection.
This saves the overhead of using accessors for commonly used fields in trunk connections.
Though these fields are public, they should NOT be modified by clients of the trunk API.
Data Fields | ||
---|---|---|
connection_t *_CONST | conn | The underlying connection. |
fr_time_t _CONST | last_read_success | Last time we read from the connection. |
fr_time_t _CONST | last_write_success | Last time we wrote to the connection. |
trunk_connection_state_t _CONST | state | What state the connection is in. |
trunk_t *_CONST | trunk | Trunk this connection belongs to. |
struct trunk_io_funcs_t |
Data Fields | ||
---|---|---|
trunk_connection_alloc_t | connection_alloc | Allocate a new connection_t. |
trunk_connection_notify_t | connection_notify | Update the I/O event registrations for. |
fr_heap_cmp_t | connection_prioritise | Ordering function for connections. |
trunk_request_cancel_t | request_cancel | Request should be removed from tracking and should be reset to its initial state. |
trunk_request_cancel_mux_t | request_cancel_mux |
!< Read one or more requests from a connection. Inform an external resource that we no longer care about the result of any queries we issued for this request. |
trunk_request_complete_t | request_complete | Request is complete, interpret the response contained in preq. |
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. |
trunk_request_demux_t | request_demux | !< Write one or more requests to a connection. |
trunk_request_fail_t | request_fail | Request failed, write out a canned response. |
trunk_request_free_t | request_free | Free the preq and any resources it holds and provide a chance to mark the request as runnable. |
trunk_request_mux_t | request_mux | |
fr_heap_cmp_t | request_prioritise |
Ordering function for requests. Controls where in the outbound queues they're inserted. |
struct trunk_pub_s |
Public fields for the trunk.
This saves the overhead of using accessors for commonly used fields in the trunk.
Though these fields are public, they should NOT be modified by clients of the trunk API.
Data Fields | ||
---|---|---|
fr_time_t _CONST | last_above_target | Last time average utilisation went above the target value. |
fr_time_t _CONST | last_below_target | Last time average utilisation went below the target value. |
fr_time_t _CONST | last_closed | Last time the connection management function closed a connection. |
fr_time_t _CONST | last_connected | Last time a connection connected. |
fr_time_t _CONST | last_failed | Last time a connection failed. |
fr_time_t _CONST | last_open | Last time the connection management function opened a connection. |
fr_time_t _CONST | last_read_success | Last time we read a response. |
fr_time_t _CONST | last_write_success | Last time we wrote to the connection. |
uint64_t _CONST | req_alloc | The number of requests currently allocated that have not been freed or returned to the free list. |
uint64_t _CONST | req_alloc_new | How many requests we've allocated. |
uint64_t _CONST | req_alloc_reused | How many requests were reused. |
trunk_state_t _CONST | state | Current state of the trunk. |
bool _CONST | triggers | do we run the triggers? |
struct trunk_request_pub_s |
Public fields for the trunk request.
This saves the overhead of using accessors for commonly used fields in trunk requests.
Though these fields are public, they should NOT be modified by clients of the trunk API.
Data Fields | ||
---|---|---|
void *_CONST | preq | Data for the muxer to write to the connection. |
void *_CONST | rctx | Resume ctx of the module. |
request_t *_CONST | request | The request that we're writing the data on behalf of. |
trunk_request_state_t _CONST | state | Which list the request is now located in. |
trunk_connection_t *_CONST | tconn | Connection this request belongs to. |
trunk_t *_CONST | trunk | Trunk this request belongs to. |
#define TRUNK_CONN_ALL |
All connection states.
#define TRUNK_CONN_PROCESSING |
States where the connection may be processing requests.
#define TRUNK_CONN_SERVICEABLE |
States where the connection may potentially be used to send requests.
#define TRUNK_CONNECTION_VERIFY | ( | _tconn | ) | trunk_connection_verify(__FILE__, __LINE__, _tconn) |
#define TRUNK_NOTIFY_FUNC | ( | _name, | |
_type | |||
) |
#define TRUNK_REQUEST_STATE_ALL |
All request states.
#define TRUNK_REQUEST_STATE_CANCEL_ALL |
All requests in various cancellation states.
#define TRUNK_REQUEST_VERIFY | ( | _treq | ) | trunk_request_verify(__FILE__, __LINE__, _treq) |
#define TRUNK_VERIFY | ( | _trunk | ) | trunk_verify(__FILE__, __LINE__, _trunk) |
typedef 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.
The trunk code only interacts with underlying connections via the connection API. As a result the trunk API is shielded from the implementation details of opening and closing connections.
When creating new connections, this callback is used to allocate and configure a new connection_t, this connection_t and the connection API is how the trunk signals the underlying connection that it should start, reconnect, and halt (stop).
The trunk must be informed when the underlying connection is readable, and, if always_writable == false
, when the connection is writable.
When the connection is readable, a read I/O handler installed by the init() callback of the connection_t must either:
trunk_connection_signal_readable(tconn)
immediately, relying on the trunk demux callback to perform decoding and demuxing.When the connection is writable a write I/O handler installed by the open() callback of the connection_t must either:
always_writable == true
- Inform the underlying I/O library that the connection is writable. The trunk API does not need to be informed as it will immediately pass through any enqueued requests to the I/O library.always_writable == false
and there's an underlying I/O library, call trunk_connection_signal_writable(tconn)
to allow the trunk mux callback to pass requests to the underlying I/O library and (optionally) signal the I/O library that the connection is writable.always_writable == false
and there's no underlying I/O library, call trunk_connection_signal_writable(tconn)
to allow the trunk mux callback to encode and write requests to a socket.[in] | tconn | The trunk connection this connection will be bound to. Should be used as the context for any connection_t allocated. |
[in] | el | The event list to use for I/O and timer events. |
[in] | conf | Configuration of the connection_t. |
[in] | log_prefix | What to prefix connection log messages with. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef 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.
I/O handlers installed by this callback should call one or more of the following functions to signal that an I/O event has occurred:
[in] | tconn | That should be notified of I/O events. |
[in] | conn | The connection_t bound to the tconn. Use conn->h to access the connection handle or file descriptor. |
[in] | el | to insert I/O events into. |
[in] | notify_on | I/O events to signal the trunk connection on. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef struct trunk_connection_pub_s trunk_connection_t |
typedef 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.
This callback will be called any time there are one or more requests to be cancelled and a connection_t is writable, or as soon as a request is cancelled if always_writable == true
.
For efficiency, this callback should call trunk_connection_pop_cancellation multiple times, and process all outstanding cancellation requests.
If the response (cancel ACK) from the remote service needs to be tracked, then the treq should be inserted into a tracking tree shared with the demuxer, and trunk_request_signal_cancel_sent should be called to move the treq into the cancel_sent state.
As with the main mux callback, if a cancellation request is partially written trunk_request_signal_cancel_partial should be called, and the amount of data written should be tracked in the preq (protocol request).
When the demuxer finds a matching (cancel ACK) response, the demuxer should remove the entry from the tracking tree and call trunk_request_signal_cancel_complete.
[in] | el | To insert any timers into. |
[in] | tconn | The trunk connection used to dequeue cancellation requests. |
[in] | conn | Connection to write the request to. Use conn->h to access the connection handle or file descriptor. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef 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.
If the treq (trunk request) is in the TRUNK_REQUEST_STATE_PARTIAL or TRUNK_REQUEST_STATE_SENT states, this callback will be called prior to moving the treq to a new connection, requeueing the treq or freeing the treq.
The treq, and any associated resources, should be removed from the the matching structure associated with the connection_t or uctx.
Which resources should be freed depends on the cancellation reason:
After this callback is complete one of several actions will be taken:
always_writable == true
) and the request_cancel_mux callback will send an explicit cancellation request to terminate any outstanding queries on remote datastores.[in] | conn | to remove request from. |
[in] | preq_to_reset | Preq to reset. |
[in] | reason | Why the request was cancelled. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef 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.
The rctx should be modified in such a way that indicates to the trunk API client that the request was sent using the trunk and a response was received.
This function should not free any resources associated with the preq. That should be done in the request_free callback. This function should only be used to translate the contents of the preq into a result, and write it to the rctx.
After this callback is complete, the request_free callback will be called if provided.
typedef 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.
Any connection specific resources that the treq currently holds must be released. Examples are connection-specific handles, ID allocations, and connection specific packets.
The treq may be about to be freed or it may be being re-assigned to a new connection.
[in] | conn | request will be removed from. |
[in] | preq_to_reset | Preq to remove connection specified resources from. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef 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 with their requests.
This callback should either:
The result (positive or negative), should be written to the rctx structure.
trunk_request_signal_complete should be used to inform the trunk that the request is now complete.
If a connection appears to have become unusable, this callback should call connection_signal_reconnect and immediately return. The current treq will either fail, or be re-enqueued depending on the trunk configuration.
trunk_request_signal_fail should NOT be called as this function is only used for reporting failures at an I/O layer level not failures of queries or external services.
[in] | el | For timer management. |
[in] | tconn | The trunk connection. |
[in] | conn | Connection to read the request from. Use conn->h to access the connection handle or file descriptor. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef 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.
The rctx should be modified in such a way that indicates to the trunk API client that the request could not be sent using the trunk.
This function should not free any resources associated with the preq. That should be done in the request_free callback. This function should only be used to write a "canned" failure to the rctx.
After this callback is complete, the request_free callback will be called if provided.
typedef void(* trunk_request_free_t) (request_t *request, void *preq_to_free, void *uctx) |
Free resources associated with a trunk request.
The trunk request is complete. If there's a request still associated with the trunk request, that will be provided so that it can be marked runnable, but be aware that the request_t * value will be NULL if the request was cancelled due to a signal.
The preq and any associated data such as encoded packets or I/O library request handled SHOULD be explicitly freed by this function. The exception to this is if the preq is parented by the treq, in which case the preq will be explicitly freed when the treq is returned to the free list.
[in] | request | to mark as runnable if no further processing is required. |
[in] | preq_to_free | As per the name. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef 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.
This callback should:
If working at the socket level and a write on a file descriptor indicates less data was written than was needed, the trunk API client should track the amount of data written in the protocol request (preq), and should call trunk_request_signal_partial(treq)
. trunk_request_signal_partial will move the request out of the pending queue, and store it in the partial slot of the trunk connection. The next time trunk_connection_pop_request is called, the partially written treq will be returned first. The API client should continue writing the partially written request to the socket.
After calling trunk_request_signal_partial this callback MUST NOT call trunk_connection_pop_request again, and should immediately return.
If the request can't be written to the connection because it the connection has become unusable, this callback should call connection_signal_reconnect(conn)
to notify the connection API that the connection is unusable. The current request will either fail, or be re-enqueued depending on the trunk configuration.
After calling connection_signal_reconnect this callback MUST NOT call trunk_connection_pop_request again, and should immediately return.
If the protocol request data can't be written to the connection because the data is invalid or because some other error occurred, this callback should call trunk_request_signal_fail(treq)
, this callback may then continue popping/processing other requests.
[in] | el | For timer management. |
[in] | tconn | The trunk connection to dequeue trunk requests from. |
[in] | conn | Connection to write the request to. Use conn->h to access the connection handle or file descriptor. |
[in] | uctx | User context data passed to trunk_alloc. |
typedef struct trunk_request_pub_s trunk_request_t |
typedef struct trunk_pub_s trunk_t |
typedef struct trunk_watch_entry_s trunk_watch_entry_t |
typedef void(* trunk_watch_t) (trunk_t *trunk, trunk_state_t prev, trunk_state_t state, void *uctx) |
Reasons for a request being cancelled.
What type of I/O events the trunk connection is currently interested in receiving.
Used for sanity checks and to track which list the connection is in.
Enumerator | |
---|---|
TRUNK_CONN_HALTED | Halted, ready to be freed. |
TRUNK_CONN_INIT | In the initial state. |
TRUNK_CONN_CONNECTING | Connection is connecting. |
TRUNK_CONN_ACTIVE | Connection is connected and ready to service requests. This is active and not 'connected', because a connection can be 'connected' and 'full' or 'connected' and 'active'. |
TRUNK_CONN_CLOSED | Connection was closed, either explicitly or due to failure. |
TRUNK_CONN_FULL | Connection is full and can't accept any more requests. |
TRUNK_CONN_INACTIVE | Connection is inactive and can't accept any more requests. |
TRUNK_CONN_INACTIVE_DRAINING | Connection is inactive, can't accept any more requests, and will be closed once it has no more outstanding requests. Connections in this state can transition to TRUNK_CONN_DRAINING. |
TRUNK_CONN_DRAINING | Connection will be closed once it has no more outstanding requests, if it's not reactivated. |
TRUNK_CONN_DRAINING_TO_FREE | Connection will be closed once it has no more outstanding requests. |
enum trunk_enqueue_t |
Used for sanity checks and to simplify freeing.
Allows us to track which
Enumerator | |
---|---|
TRUNK_REQUEST_STATE_INIT | Initial state. Requests in this state were never assigned, and the request_t should not have been yielded. |
TRUNK_REQUEST_STATE_UNASSIGNED | Transition state - Request currently not assigned to any connection. |
TRUNK_REQUEST_STATE_BACKLOG | In the backlog. |
TRUNK_REQUEST_STATE_PENDING | In the queue of a connection and is pending writing. |
TRUNK_REQUEST_STATE_PARTIAL | Some of the request was written to the socket, more of it should be written later. |
TRUNK_REQUEST_STATE_SENT | Was written to a socket. Waiting for a response. |
TRUNK_REQUEST_STATE_REAPABLE | Request has been written, needs to persist, but we are not currently waiting for any response. This is primarily useful where the connection only allows a single outstanding request, and writing additional requests would cause the previous result to be lost. Requests in this state count towards the outstanding number of requests on a connection, and prevent new requests from being enqueued until they complete. |
TRUNK_REQUEST_STATE_COMPLETE | The request is complete. |
TRUNK_REQUEST_STATE_FAILED | The request failed. |
TRUNK_REQUEST_STATE_CANCEL | A request on a particular socket was cancel. |
TRUNK_REQUEST_STATE_CANCEL_SENT | We've informed the remote server that the request has been cancelled. |
TRUNK_REQUEST_STATE_CANCEL_PARTIAL | We partially wrote a cancellation request. |
TRUNK_REQUEST_STATE_CANCEL_COMPLETE | Remote server has acknowledged our cancellation. |
enum trunk_state_t |
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.
[in] | trunk | The trunk to add the watcher to. |
[in] | state | to watch for. |
[in] | watch | Function to add. |
[in] | oneshot | Should this watcher only be run once. |
[in] | uctx | Context to pass to function. |
Definition at line 865 of file trunk.c.
trunk_t * trunk_alloc | ( | TALLOC_CTX * | ctx, |
fr_event_list_t * | el, | ||
trunk_io_funcs_t const * | funcs, | ||
trunk_conf_t const * | conf, | ||
char const * | log_prefix, | ||
void const * | uctx, | ||
bool | delay_start | ||
) |
Allocate a new collection of connections.
This function should be called first to allocate a new trunk connection.
After the trunk has been allocated, trunk_request_alloc and trunk_request_enqueue should be used to allocate memory for trunk requests, and pass a preq (protocol request) to the trunk for processing.
The trunk will then asynchronously process the request, writing the result to a specified rctx. See trunk_request_enqueue for more details.
[in] | ctx | To use for any memory allocations. Must be thread local. |
[in] | el | to use for I/O and timer events. |
[in] | funcs | Callback functions. |
[in] | conf | Common user configurable parameters. |
[in] | log_prefix | To prepend to global messages. |
[in] | uctx | User data to pass to the alloc function. |
[in] | delay_start | If true, then we will not spawn any connections until the first request is enqueued. |
Definition at line 4945 of file trunk.c.
void trunk_connection_callback_readable | ( | fr_event_list_t * | el, |
int | fd, | ||
int | flags, | ||
void * | uctx | ||
) |
void trunk_connection_callback_writable | ( | fr_event_list_t * | el, |
int | fd, | ||
int | flags, | ||
void * | uctx | ||
) |
Return the count number of connections in the specified states.
[in] | trunk | to retrieve counts for. |
[in] | conn_state | One or more trunk_connection_state_t states or'd together. |
Definition at line 2855 of file trunk.c.
bool trunk_connection_in_state | ( | trunk_connection_t * | tconn, |
int | state | ||
) |
int trunk_connection_manage_schedule | ( | trunk_t * | trunk | ) |
void trunk_connection_manage_start | ( | trunk_t * | trunk | ) |
void trunk_connection_manage_stop | ( | trunk_t * | trunk | ) |
int trunk_connection_pop_cancellation | ( | trunk_request_t ** | treq_out, |
trunk_connection_t * | tconn | ||
) |
Pop a cancellation request off a connection's cancellation queue.
The request we return is advanced by the request moving out of the cancel state and into the cancel_sent or cancel_complete state.
One of these signalling functions must be called after the request has been popped:
[out] | treq_out | to process |
[in] | tconn | Connection to drain cancellation request from. |
Definition at line 3835 of file trunk.c.
int trunk_connection_pop_request | ( | trunk_request_t ** | treq_out, |
trunk_connection_t * | tconn | ||
) |
Pop a request off a connection's pending queue.
The request we return is advanced by the request moving out of the partial or pending states, when the mux function signals us.
If the same request is returned again and again, it means the muxer isn't actually doing anything with the request we returned, and it's and error in the muxer code.
One of these signalling functions must be used after the request has been popped:
[out] | treq_out | to process |
[in] | tconn | to pop a request from. |
Definition at line 3883 of file trunk.c.
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.
[in] | tconn | to move requests off of. |
[in] | states | Only move requests in this state. |
[in] | max | The maximum number of requests to dequeue. 0 for unlimited. |
[in] | fail_bound | If true causes any requests bound to the connection to fail. If false bound requests will not be moved. |
Definition at line 2010 of file trunk.c.
bool trunk_connection_search | ( | trunk_connection_t * | tconn, |
void * | ptr | ||
) |
void trunk_connection_signal_active | ( | trunk_connection_t * | tconn | ) |
void trunk_connection_signal_inactive | ( | trunk_connection_t * | tconn | ) |
void trunk_connection_signal_readable | ( | trunk_connection_t * | tconn | ) |
void trunk_connection_signal_reconnect | ( | trunk_connection_t * | tconn, |
connection_reason_t | reason | ||
) |
void trunk_connection_signal_writable | ( | trunk_connection_t * | tconn | ) |
void trunk_connection_verify | ( | char const * | file, |
int | line, | ||
trunk_connection_t * | tconn | ||
) |
int trunk_del_watch | ( | trunk_t * | trunk, |
trunk_state_t | state, | ||
trunk_watch_t | watch | ||
) |
Remove a watch function from a trunk state list.
[in] | trunk | The trunk to remove the watcher from. |
[in] | state | to remove the watch from. |
[in] | watch | Function to remove. |
Definition at line 831 of file trunk.c.
void trunk_reconnect | ( | trunk_t * | trunk, |
int | states, | ||
connection_reason_t | reason | ||
) |
Force the trunk to re-establish its connections.
[in] | trunk | to signal. |
[in] | states | One or more states or'd together. |
[in] | reason | Why the connections are being signalled to reconnect. |
Definition at line 4725 of file trunk.c.
trunk_request_t * trunk_request_alloc | ( | trunk_t * | trunk, |
request_t * | request | ||
) |
(Pre-)Allocate a new trunk request
If trunk->conf.req_pool_headers or trunk->conf.req_pool_size are not zero then the request will be a talloc pool, which can be used to hold the preq.
[in] | trunk | to add request to. |
[in] | request | to wrap in a trunk request (treq). |
Definition at line 2474 of file trunk.c.
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.
[in] | tconn | to return request count for. |
[in] | req_state | One or more request states or'd together. |
Definition at line 2879 of file trunk.c.
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.
[in] | trunk | to retrieve counts for. |
[in] | conn_state | One or more connection states or'd together. |
[in] | req_state | One or more request states or'd together. |
Definition at line 4522 of file trunk.c.
trunk_enqueue_t trunk_request_enqueue | ( | trunk_request_t ** | treq_out, |
trunk_t * | trunk, | ||
request_t * | request, | ||
void * | preq, | ||
void * | rctx | ||
) |
Enqueue a request that needs data written to the trunk.
When a request_t * needs to make an asynchronous request to an external datastore it should call this function, specifying a preq (protocol request) containing the data necessary to request information from the external datastore, and an rctx (resume ctx) used to hold the decoded response and/or any error codes.
After a treq is successfully enqueued it will either be assigned immediately to the pending queue of a connection, or if no connections are available, (depending on the trunk configuration) the treq will be placed in the trunk's global backlog.
After receiving a positive return code from this function the caller should immediately yield, to allow the various timers and I/O handlers that drive tconn (trunk connection) and treq state changes to be called.
When a tconn becomes writable (or the trunk is configured to be always writable) the trunk_request_mux_t callback will be called to dequeue, encode and send any pending requests for that tconn. The trunk_request_mux_t callback is also responsible for tracking the outbound requests to allow the trunk_request_demux_t callback to match inbound responses with the original treq. Once the trunk_request_mux_t callback is done processing the treq it signals what state the treq should enter next using one of the trunk_request_signal_* functions.
When a tconn becomes readable the user specified trunk_request_demux_t callback is called to process any responses, match them with the original treq. and signal what state they should enter next using one of the trunk_request_signal_* functions.
[in,out] | treq_out | A trunk request handle. If the memory pointed to is NULL, a new treq will be allocated. Otherwise treq should point to memory allocated with trunk_request_alloc. |
[in] | trunk | to enqueue request on. |
[in] | request | to enqueue. |
[in] | preq | Protocol request to write out. Will be freed when treq is freed. Should ideally be parented by the treq if possible. Use trunk_request_alloc for pre-allocation of the treq. |
[in] | rctx | The resume context to write any result to. |
Definition at line 2587 of file trunk.c.
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.
This may be used to create a series of requests on a single connection, or to generate in-band status checks.
[in,out] | treq_out | A trunk request handle. If the memory pointed to is NULL, a new treq will be allocated. Otherwise treq should point to memory allocated with trunk_request_alloc. |
[in] | tconn | to enqueue request on. |
[in] | request | to enqueue. |
[in] | preq | Protocol request to write out. Will be freed when treq is freed. Should ideally be parented by the treq if possible. Use trunk_request_alloc for pre-allocation of the treq. |
[in] | rctx | The resume context to write any result to. |
[in] | ignore_limits | Ignore max_req_per_conn. Useful to force status checks through even if the connection is at capacity. Will also allow enqueuing on "inactive", "draining", "draining-to-free" connections. |
Definition at line 2741 of file trunk.c.
void trunk_request_free | ( | trunk_request_t ** | treq_to_free | ) |
If the trunk request is freed then update the target requests.
gperftools showed calling the request free function directly was slightly faster than using talloc_free.
[in] | treq_to_free | request. |
Definition at line 2322 of file trunk.c.
trunk_enqueue_t trunk_request_requeue | ( | trunk_request_t * | treq | ) |
Re-enqueue a request on the same connection.
If the treq has been sent, we assume that we're being signalled to requeue because something outside of the trunk API has determined that a retransmission is required. The easiest way to perform that retransmission is to clean up any tracking information for the request, and the requeue it for transmission.
IF re-queueing fails, the request will enter the fail state. It should not be accessed if this occurs.
[in] | treq | to requeue (retransmit). |
Definition at line 2676 of file trunk.c.
bool trunk_request_search | ( | trunk_request_t * | treq, |
void * | ptr | ||
) |
void trunk_request_signal_cancel | ( | trunk_request_t * | treq | ) |
Cancel a trunk request.
treq can be in any state, but requests to cancel if the treq is not in the TRUNK_REQUEST_STATE_PARTIAL or TRUNK_REQUEST_STATE_SENT state will be ignored.
The complete or failed callbacks will not be called here, as it's assumed the request_t * is now inviable as it's being cancelled.
The free function however, is called, and that should be used to perform necessary cleanup.
[in] | treq | to signal state change for. |
Definition at line 2152 of file trunk.c.
void trunk_request_signal_cancel_complete | ( | trunk_request_t * | treq | ) |
Signal that a remote server acked our cancellation.
Called from request_demux to indicate that it got an ack for the cancellation.
[in] | treq | to signal state change for. |
Definition at line 2284 of file trunk.c.
void trunk_request_signal_cancel_partial | ( | trunk_request_t * | treq | ) |
void trunk_request_signal_cancel_sent | ( | trunk_request_t * | treq | ) |
Signal that a remote server has been notified of the cancellation.
Called from request_cancel_mux to indicate that the datastore has been informed that the response is no longer needed.
[in] | treq | to signal state change for. |
Definition at line 2260 of file trunk.c.
void trunk_request_signal_complete | ( | trunk_request_t * | treq | ) |
void trunk_request_signal_fail | ( | trunk_request_t * | treq | ) |
void trunk_request_signal_partial | ( | trunk_request_t * | treq | ) |
void trunk_request_signal_reapable | ( | trunk_request_t * | treq | ) |
void trunk_request_signal_sent | ( | trunk_request_t * | treq | ) |
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 | ||
) |
void trunk_request_verify | ( | char const * | file, |
int | line, | ||
trunk_request_t * | treq | ||
) |
int trunk_start | ( | trunk_t * | trunk | ) |
void trunk_verify | ( | char const * | file, |
int | line, | ||
trunk_t * | trunk | ||
) |
Verify a trunk.
A trunk has some number of connections, which each have some number of requests. The connections and requests are in differing kinds of containers depending on their state and how they are used, and may have fields that can only be validated by comparison with a parent. We had planned on passing a "context" down with the ancestral values, but that breaks the foo_verify() API. Each foo_verify() will only verify the foo's children.
Definition at line 5026 of file trunk.c.
|
extern |
Config parser definitions to populate a trunk_conf_t.