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 | fr_trunk_conf_t |
Common configuration parameters for a trunk. More... | |
struct | fr_trunk_connection_pub_s |
Public fields for the trunk connection. More... | |
struct | fr_trunk_io_funcs_t |
I/O functions to pass to fr_trunk_alloc. More... | |
struct | fr_trunk_pub_s |
Public fields for the trunk. More... | |
struct | fr_trunk_request_pub_s |
Public fields for the trunk request. More... | |
Macros | |
#define | _CONST const |
#define | FR_TRUNK_CONN_ALL |
All connection states. More... | |
#define | FR_TRUNK_CONN_PROCESSING |
States where the connection may be processing requests. More... | |
#define | FR_TRUNK_CONN_SERVICEABLE |
States where the connection may potentially be used to send requests. More... | |
#define | FR_TRUNK_CONNECTION_VERIFY(_tconn) fr_trunk_connection_verify(__FILE__, __LINE__, _tconn) |
#define | FR_TRUNK_REQUEST_STATE_ALL |
All request states. More... | |
#define | FR_TRUNK_REQUEST_STATE_CANCEL_ALL |
All requests in various cancellation states. More... | |
#define | FR_TRUNK_REQUEST_VERIFY(_treq) fr_trunk_request_verify(__FILE__, __LINE__, _treq) |
#define | FR_TRUNK_VERIFY(_trunk) fr_trunk_verify(__FILE__, __LINE__, _trunk) |
Typedefs | |
typedef fr_connection_t *(* | fr_trunk_connection_alloc_t) (fr_trunk_connection_t *tconn, fr_event_list_t *el, fr_connection_conf_t const *conf, char const *log_prefix, void *uctx) |
Allocate a new connection for the trunk. More... | |
typedef void(* | fr_trunk_connection_notify_t) (fr_trunk_connection_t *tconn, fr_connection_t *conn, fr_event_list_t *el, fr_trunk_connection_event_t notify_on, void *uctx) |
Inform the trunk API client which I/O events the trunk wants to receive. More... | |
typedef struct fr_trunk_connection_pub_s | fr_trunk_connection_t |
typedef void(* | fr_trunk_request_cancel_mux_t) (fr_event_list_t *el, fr_trunk_connection_t *tconn, fr_connection_t *conn, void *uctx) |
Inform a remote service like a datastore that a request should be cancelled. More... | |
typedef void(* | fr_trunk_request_cancel_t) (fr_connection_t *conn, void *preq_to_reset, fr_trunk_cancel_reason_t reason, void *uctx) |
Remove an outstanding "sent" request from a tracking/matching structure. More... | |
typedef void(* | fr_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. More... | |
typedef void(* | fr_trunk_request_conn_release_t) (fr_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. More... | |
typedef void(* | fr_trunk_request_demux_t) (fr_event_list_t *el, fr_trunk_connection_t *tconn, fr_connection_t *conn, void *uctx) |
Demultiplex on or more responses, reading them from a connection, decoding them, and matching them with their requests. More... | |
typedef void(* | fr_trunk_request_fail_t) (request_t *request, void *preq, void *rctx, fr_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. More... | |
typedef void(* | fr_trunk_request_free_t) (request_t *request, void *preq_to_free, void *uctx) |
Free resources associated with a trunk request. More... | |
typedef void(* | fr_trunk_request_mux_t) (fr_event_list_t *el, fr_trunk_connection_t *tconn, fr_connection_t *conn, void *uctx) |
Multiplex one or more requests into a single connection. More... | |
typedef struct fr_trunk_request_pub_s | fr_trunk_request_t |
typedef struct fr_trunk_pub_s | fr_trunk_t |
typedef struct fr_trunk_watch_entry_s | fr_trunk_watch_entry_t |
typedef void(* | fr_trunk_watch_t) (fr_trunk_t *trunk, fr_trunk_state_t prev, fr_trunk_state_t state, void *uctx) |
Receive a notification when a trunk enters a particular state. More... | |
Functions | |
bool | fr_trunk_connection_search (fr_trunk_connection_t *tconn, void *ptr) |
void | fr_trunk_connection_verify (char const *file, int line, fr_trunk_connection_t *tconn) |
bool | fr_trunk_request_search (fr_trunk_request_t *treq, void *ptr) |
void | fr_trunk_request_verify (char const *file, int line, fr_trunk_request_t *treq) |
bool | fr_trunk_search (fr_trunk_t *trunk, void *ptr) |
void | fr_trunk_verify (char const *file, int line, fr_trunk_t *trunk) |
Verify a trunk. More... | |
Variables | |
conf_parser_t const | fr_trunk_config [] |
Config parser definitions to populate a fr_trunk_conf_t. More... | |
Statistics | |
uint16_t | fr_trunk_connection_count_by_state (fr_trunk_t *trunk, int conn_state) |
Return the count number of connections in the specified states. More... | |
uint32_t | fr_trunk_request_count_by_connection (fr_trunk_connection_t const *tconn, int req_state) |
Return the count number of requests associated with a trunk connection. More... | |
uint64_t | fr_trunk_request_count_by_state (fr_trunk_t *trunk, int conn_state, int req_state) |
Return a count of requests on a connection in a specific state. More... | |
Request state signalling | |
void | fr_trunk_request_signal_cancel (fr_trunk_request_t *treq) |
Cancel a trunk request. More... | |
void | fr_trunk_request_signal_cancel_complete (fr_trunk_request_t *treq) |
Signal that a remote server acked our cancellation. More... | |
void | fr_trunk_request_signal_cancel_partial (fr_trunk_request_t *treq) |
Signal a partial cancel write. More... | |
void | fr_trunk_request_signal_cancel_sent (fr_trunk_request_t *treq) |
Signal that a remote server has been notified of the cancellation. More... | |
void | fr_trunk_request_signal_complete (fr_trunk_request_t *treq) |
Signal that a trunk request is complete. More... | |
void | fr_trunk_request_signal_fail (fr_trunk_request_t *treq) |
Signal that a trunk request failed. More... | |
void | fr_trunk_request_signal_partial (fr_trunk_request_t *treq) |
Signal a partial write. More... | |
void | fr_trunk_request_signal_sent (fr_trunk_request_t *treq) |
Signal that the request was written to a connection successfully. More... | |
(R)enqueue and alloc requests | |
uint64_t | fr_trunk_connection_requests_requeue (fr_trunk_connection_t *tconn, int states, uint64_t max, bool fail_bound) |
Move requests off of a connection and requeue elsewhere. More... | |
fr_trunk_request_t * | fr_trunk_request_alloc (fr_trunk_t *trunk, request_t *request)) |
(Pre-)Allocate a new trunk request More... | |
fr_trunk_enqueue_t | fr_trunk_request_enqueue (fr_trunk_request_t **treq, fr_trunk_t *trunk, request_t *request, void *preq, void *rctx)) |
Enqueue a request that needs data written to the trunk. More... | |
fr_trunk_enqueue_t | fr_trunk_request_enqueue_on_conn (fr_trunk_request_t **treq_out, fr_trunk_connection_t *tconn, request_t *request, void *preq, void *rctx, bool ignore_limits)) |
Enqueue additional requests on a specific connection. More... | |
void | fr_trunk_request_free (fr_trunk_request_t **treq) |
If the trunk request is freed then update the target requests. More... | |
fr_trunk_enqueue_t | fr_trunk_request_requeue (fr_trunk_request_t *treq) |
Re-enqueue a request on the same connection. More... | |
void | fr_trunk_request_state_log (fr_log_t const *log, fr_log_type_t log_type, char const *file, int line, fr_trunk_request_t const *treq) |
Dequeue protocol requests and cancellations | |
int | fr_trunk_connection_pop_cancellation (fr_trunk_request_t **treq_out, fr_trunk_connection_t *tconn) |
Pop a cancellation request off a connection's cancellation queue. More... | |
int | fr_trunk_connection_pop_request (fr_trunk_request_t **treq_out, fr_trunk_connection_t *tconn) |
Pop a request off a connection's pending queue. More... | |
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 fr_connection_t as to when the connection changes state. fr_trunk_connection_signal_active does not need to be called in any of the fr_connection_t state callbacks. It is only used to activate a connection which has been previously marked inactive using fr_trunk_connection_signal_inactive. If fr_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 fr_trunk_connection_requests_requeue with the FR_TRUNK_REQUEST_STATE_PENDING state to redistribute that connection's backlog to other connections in the trunk. | |
bool | fr_trunk_connection_in_state (fr_trunk_connection_t *tconn, int state) |
Returns true if the trunk connection is in one of the specified states. More... | |
void | fr_trunk_connection_signal_active (fr_trunk_connection_t *tconn) |
Signal a trunk connection is no longer full. More... | |
void | fr_trunk_connection_signal_inactive (fr_trunk_connection_t *tconn) |
Signal a trunk connection cannot accept more requests. More... | |
void | fr_trunk_connection_signal_readable (fr_trunk_connection_t *tconn) |
Signal that a trunk connection is readable. More... | |
void | fr_trunk_connection_signal_reconnect (fr_trunk_connection_t *tconn, fr_connection_reason_t reason) |
Signal a trunk connection is no longer viable. More... | |
void | fr_trunk_connection_signal_writable (fr_trunk_connection_t *tconn) |
Signal that a trunk connection is writable. More... | |
Connection Callbacks | |
void | fr_trunk_connection_callback_readable (fr_event_list_t *el, int fd, int flags, void *uctx) |
void | fr_trunk_connection_callback_writable (fr_event_list_t *el, int fd, int flags, void *uctx) |
Connection management | |
void | fr_trunk_reconnect (fr_trunk_t *trunk, int state, fr_connection_reason_t reason) |
Force the trunk to re-establish its connections. More... | |
Trunk allocation | |
fr_trunk_t * | fr_trunk_alloc (TALLOC_CTX *ctx, fr_event_list_t *el, fr_trunk_io_funcs_t const *funcs, fr_trunk_conf_t const *conf, char const *log_prefix, void const *uctx, bool delay_start)) |
Allocate a new collection of connections. More... | |
int | fr_trunk_connection_manage_schedule (fr_trunk_t *trunk) |
Schedule a trunk management event for the next time the event loop is executed. More... | |
void | fr_trunk_connection_manage_start (fr_trunk_t *trunk) |
Allow the trunk to open and close connections in response to load. More... | |
void | fr_trunk_connection_manage_stop (fr_trunk_t *trunk) |
Stop the trunk from opening and closing connections in response to load. More... | |
int | fr_trunk_start (fr_trunk_t *trunk) |
Start the trunk running. More... | |
Watchers | |
fr_trunk_watch_entry_t * | fr_trunk_add_watch (fr_trunk_t *trunk, fr_trunk_state_t state, fr_trunk_watch_t watch, bool oneshot, void const *uctx)) |
Add a watch entry to the trunk state list. More... | |
int | fr_trunk_del_watch (fr_trunk_t *trunk, fr_trunk_state_t state, fr_trunk_watch_t watch) |
Remove a watch function from a trunk state list. More... | |
struct fr_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, fr_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. |
fr_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 | 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_req_per_conn |
Maximum connections per request. 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 fr_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 | ||
---|---|---|
fr_connection_t *_CONST | conn | The underlying connection. |
fr_trunk_connection_state_t _CONST | state | What state the connection is in. |
fr_trunk_t *_CONST | trunk | Trunk this connection belongs to. |
struct fr_trunk_io_funcs_t |
Data Fields | ||
---|---|---|
fr_trunk_connection_alloc_t | connection_alloc | Allocate a new fr_connection_t. |
fr_trunk_connection_notify_t | connection_notify | Update the I/O event registrations for. |
fr_heap_cmp_t | connection_prioritise | Ordering function for connections. |
fr_trunk_request_cancel_t | request_cancel | Request should be removed from tracking and should be reset to its initial state. |
fr_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. |
fr_trunk_request_complete_t | request_complete | Request is complete, interpret the response contained in preq. |
fr_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. |
fr_trunk_request_demux_t | request_demux | !< Write one or more requests to a connection. |
fr_trunk_request_fail_t | request_fail | Request failed, write out a canned response. |
fr_trunk_request_free_t | request_free | Free the preq and any resources it holds and provide a chance to mark the request as runnable. |
fr_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 fr_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. |
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. |
fr_trunk_state_t _CONST | state | Current state of the trunk. |
bool _CONST | triggers | do we run the triggers? |
struct fr_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. |
fr_trunk_request_state_t _CONST | state | Which list the request is now located in. |
fr_trunk_connection_t *_CONST | tconn | Connection this request belongs to. |
fr_trunk_t *_CONST | trunk | Trunk this request belongs to. |
#define FR_TRUNK_CONN_ALL |
#define FR_TRUNK_CONN_PROCESSING |
#define FR_TRUNK_CONN_SERVICEABLE |
#define FR_TRUNK_CONNECTION_VERIFY | ( | _tconn | ) | fr_trunk_connection_verify(__FILE__, __LINE__, _tconn) |
#define FR_TRUNK_REQUEST_STATE_ALL |
All request states.
#define FR_TRUNK_REQUEST_STATE_CANCEL_ALL |
#define FR_TRUNK_REQUEST_VERIFY | ( | _treq | ) | fr_trunk_request_verify(__FILE__, __LINE__, _treq) |
#define FR_TRUNK_VERIFY | ( | _trunk | ) | fr_trunk_verify(__FILE__, __LINE__, _trunk) |
typedef fr_connection_t*(* fr_trunk_connection_alloc_t) (fr_trunk_connection_t *tconn, fr_event_list_t *el, fr_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 fr_connection_t, this fr_connection_t and the fr_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 fr_connection_t must either:
fr_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 fr_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 fr_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 fr_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 fr_connection_t allocated. |
[in] | el | The event list to use for I/O and timer events. |
[in] | conf | Configuration of the fr_connection_t. |
[in] | log_prefix | What to prefix connection log messages with. |
[in] | uctx | User context data passed to fr_trunk_alloc. |
typedef void(* fr_trunk_connection_notify_t) (fr_trunk_connection_t *tconn, fr_connection_t *conn, fr_event_list_t *el, fr_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 fr_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 fr_trunk_alloc. |
typedef struct fr_trunk_connection_pub_s fr_trunk_connection_t |
typedef void(* fr_trunk_request_cancel_mux_t) (fr_event_list_t *el, fr_trunk_connection_t *tconn, fr_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 fr_connection_t is writable, or as soon as a request is cancelled if always_writable == true
.
For efficiency, this callback should call fr_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 fr_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 fr_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 fr_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 fr_trunk_alloc. |
typedef void(* fr_trunk_request_cancel_t) (fr_connection_t *conn, void *preq_to_reset, fr_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 FR_TRUNK_REQUEST_STATE_PARTIAL or FR_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 fr_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 fr_trunk_alloc. |
typedef void(* fr_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(* fr_trunk_request_conn_release_t) (fr_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 fr_trunk_alloc. |
typedef void(* fr_trunk_request_demux_t) (fr_event_list_t *el, fr_trunk_connection_t *tconn, fr_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.
fr_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 fr_connection_signal_reconnect and immediately return. The current treq will either fail, or be re-enqueued depending on the trunk configuration.
fr_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 fr_trunk_alloc. |
typedef void(* fr_trunk_request_fail_t) (request_t *request, void *preq, void *rctx, fr_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(* fr_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 fr_trunk_alloc. |
typedef void(* fr_trunk_request_mux_t) (fr_event_list_t *el, fr_trunk_connection_t *tconn, fr_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 fr_trunk_request_signal_partial(treq)
. fr_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 fr_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 fr_trunk_request_signal_partial this callback MUST NOT call fr_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 fr_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 fr_connection_signal_reconnect this callback MUST NOT call fr_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 fr_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 fr_trunk_alloc. |
typedef struct fr_trunk_request_pub_s fr_trunk_request_t |
typedef struct fr_trunk_pub_s fr_trunk_t |
typedef struct fr_trunk_watch_entry_s fr_trunk_watch_entry_t |
typedef void(* fr_trunk_watch_t) (fr_trunk_t *trunk, fr_trunk_state_t prev, fr_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 | |
---|---|
FR_TRUNK_CONN_HALTED | Halted, ready to be freed. |
FR_TRUNK_CONN_INIT | In the initial state. |
FR_TRUNK_CONN_CONNECTING | Connection is connecting. |
FR_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'. |
FR_TRUNK_CONN_CLOSED | Connection was closed, either explicitly or due to failure. |
FR_TRUNK_CONN_FULL | Connection is full and can't accept any more requests. |
FR_TRUNK_CONN_INACTIVE | Connection is inactive and can't accept any more requests. |
FR_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 FR_TRUNK_CONN_DRAINING. |
FR_TRUNK_CONN_DRAINING | Connection will be closed once it has no more outstanding requests, if it's not reactivated. |
FR_TRUNK_CONN_DRAINING_TO_FREE | Connection will be closed once it has no more outstanding requests. |
enum fr_trunk_enqueue_t |
Used for sanity checks and to simplify freeing.
Allows us to track which
Enumerator | |
---|---|
FR_TRUNK_REQUEST_STATE_INIT | Initial state. Requests in this state were never assigned, and the request_t should not have been yielded. |
FR_TRUNK_REQUEST_STATE_UNASSIGNED | Transition state - Request currently not assigned to any connection. |
FR_TRUNK_REQUEST_STATE_BACKLOG | In the backlog. |
FR_TRUNK_REQUEST_STATE_PENDING | In the queue of a connection and is pending writing. |
FR_TRUNK_REQUEST_STATE_PARTIAL | Some of the request was written to the socket, more of it should be written later. |
FR_TRUNK_REQUEST_STATE_SENT | Was written to a socket. Waiting for a response. |
FR_TRUNK_REQUEST_STATE_COMPLETE | The request is complete. |
FR_TRUNK_REQUEST_STATE_FAILED | The request failed. |
FR_TRUNK_REQUEST_STATE_CANCEL | A request on a particular socket was cancel. |
FR_TRUNK_REQUEST_STATE_CANCEL_SENT | We've informed the remote server that the request has been cancelled. |
FR_TRUNK_REQUEST_STATE_CANCEL_PARTIAL | We partially wrote a cancellation request. |
FR_TRUNK_REQUEST_STATE_CANCEL_COMPLETE | Remote server has acknowledged our cancellation. |
enum fr_trunk_state_t |
fr_trunk_watch_entry_t* fr_trunk_add_watch | ( | fr_trunk_t * | trunk, |
fr_trunk_state_t | state, | ||
fr_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 846 of file trunk.c.
fr_trunk_t* fr_trunk_alloc | ( | TALLOC_CTX * | ctx, |
fr_event_list_t * | el, | ||
fr_trunk_io_funcs_t const * | funcs, | ||
fr_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, fr_trunk_request_alloc and fr_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 fr_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 4767 of file trunk.c.
void fr_trunk_connection_callback_readable | ( | fr_event_list_t * | el, |
int | fd, | ||
int | flags, | ||
void * | uctx | ||
) |
void fr_trunk_connection_callback_writable | ( | fr_event_list_t * | el, |
int | fd, | ||
int | flags, | ||
void * | uctx | ||
) |
uint16_t fr_trunk_connection_count_by_state | ( | fr_trunk_t * | trunk, |
int | conn_state | ||
) |
Return the count number of connections in the specified states.
[in] | trunk | to retrieve counts for. |
[in] | conn_state | One or more fr_trunk_connection_state_t states or'd together. |
Definition at line 2743 of file trunk.c.
bool fr_trunk_connection_in_state | ( | fr_trunk_connection_t * | tconn, |
int | state | ||
) |
int fr_trunk_connection_manage_schedule | ( | fr_trunk_t * | trunk | ) |
void fr_trunk_connection_manage_start | ( | fr_trunk_t * | trunk | ) |
void fr_trunk_connection_manage_stop | ( | fr_trunk_t * | trunk | ) |
int fr_trunk_connection_pop_cancellation | ( | fr_trunk_request_t ** | treq_out, |
fr_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 3708 of file trunk.c.
int fr_trunk_connection_pop_request | ( | fr_trunk_request_t ** | treq_out, |
fr_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 3756 of file trunk.c.
uint64_t fr_trunk_connection_requests_requeue | ( | fr_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 1933 of file trunk.c.
bool fr_trunk_connection_search | ( | fr_trunk_connection_t * | tconn, |
void * | ptr | ||
) |
void fr_trunk_connection_signal_active | ( | fr_trunk_connection_t * | tconn | ) |
void fr_trunk_connection_signal_inactive | ( | fr_trunk_connection_t * | tconn | ) |
void fr_trunk_connection_signal_readable | ( | fr_trunk_connection_t * | tconn | ) |
void fr_trunk_connection_signal_reconnect | ( | fr_trunk_connection_t * | tconn, |
fr_connection_reason_t | reason | ||
) |
void fr_trunk_connection_signal_writable | ( | fr_trunk_connection_t * | tconn | ) |
void fr_trunk_connection_verify | ( | char const * | file, |
int | line, | ||
fr_trunk_connection_t * | tconn | ||
) |
int fr_trunk_del_watch | ( | fr_trunk_t * | trunk, |
fr_trunk_state_t | state, | ||
fr_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 812 of file trunk.c.
void fr_trunk_reconnect | ( | fr_trunk_t * | trunk, |
int | states, | ||
fr_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 4557 of file trunk.c.
fr_trunk_request_t* fr_trunk_request_alloc | ( | fr_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 2369 of file trunk.c.
uint32_t fr_trunk_request_count_by_connection | ( | fr_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 2767 of file trunk.c.
uint64_t fr_trunk_request_count_by_state | ( | fr_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 4354 of file trunk.c.
fr_trunk_enqueue_t fr_trunk_request_enqueue | ( | fr_trunk_request_t ** | treq_out, |
fr_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 fr_trunk_request_mux_t callback will be called to dequeue, encode and send any pending requests for that tconn. The fr_trunk_request_mux_t callback is also responsible for tracking the outbound requests to allow the fr_trunk_request_demux_t callback to match inbound responses with the original treq. Once the fr_trunk_request_mux_t callback is done processing the treq it signals what state the treq should enter next using one of the fr_trunk_request_signal_* functions.
When a tconn becomes readable the user specified fr_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 fr_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 fr_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 fr_trunk_request_alloc for pre-allocation of the treq. |
[in] | rctx | The resume context to write any result to. |
Definition at line 2481 of file trunk.c.
fr_trunk_enqueue_t fr_trunk_request_enqueue_on_conn | ( | fr_trunk_request_t ** | treq_out, |
fr_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 fr_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 fr_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 2629 of file trunk.c.
void fr_trunk_request_free | ( | fr_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 2217 of file trunk.c.
fr_trunk_enqueue_t fr_trunk_request_requeue | ( | fr_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 2568 of file trunk.c.
bool fr_trunk_request_search | ( | fr_trunk_request_t * | treq, |
void * | ptr | ||
) |
void fr_trunk_request_signal_cancel | ( | fr_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 FR_TRUNK_REQUEST_STATE_PARTIAL or FR_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 2047 of file trunk.c.
void fr_trunk_request_signal_cancel_complete | ( | fr_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 2179 of file trunk.c.
void fr_trunk_request_signal_cancel_partial | ( | fr_trunk_request_t * | treq | ) |
void fr_trunk_request_signal_cancel_sent | ( | fr_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 2155 of file trunk.c.
void fr_trunk_request_signal_complete | ( | fr_trunk_request_t * | treq | ) |
void fr_trunk_request_signal_fail | ( | fr_trunk_request_t * | treq | ) |
void fr_trunk_request_signal_partial | ( | fr_trunk_request_t * | treq | ) |
void fr_trunk_request_signal_sent | ( | fr_trunk_request_t * | treq | ) |
void fr_trunk_request_state_log | ( | fr_log_t const * | log, |
fr_log_type_t | log_type, | ||
char const * | file, | ||
int | line, | ||
fr_trunk_request_t const * | treq | ||
) |
void fr_trunk_request_verify | ( | char const * | file, |
int | line, | ||
fr_trunk_request_t * | treq | ||
) |
bool fr_trunk_search | ( | fr_trunk_t * | trunk, |
void * | ptr | ||
) |
int fr_trunk_start | ( | fr_trunk_t * | trunk | ) |
void fr_trunk_verify | ( | char const * | file, |
int | line, | ||
fr_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 4848 of file trunk.c.
|
extern |
Config parser definitions to populate a fr_trunk_conf_t.