27RCSID(
"$Id: b0506e50062474c4fb542cdcfffe4cba1a4d0ce4 $")
31#include <freeradius-devel/util/debug.h>
33#define LOG_PREFIX handle_config->name
35#include <freeradius-devel/server/base.h>
36#include <freeradius-devel/ldap/base.h>
37#include <freeradius-devel/unlang/function.h>
70 {
L(
"base"), LDAP_SCOPE_BASE },
71 {
L(
"children"), LDAP_SCOPE_CHILDREN },
72 {
L(
"one"), LDAP_SCOPE_ONE },
73 {
L(
"sub"), LDAP_SCOPE_SUB }
78 {
L(
"allow"), LDAP_OPT_X_TLS_ALLOW },
79 {
L(
"demand"), LDAP_OPT_X_TLS_DEMAND },
80 {
L(
"hard"), LDAP_OPT_X_TLS_HARD },
81 {
L(
"never"), LDAP_OPT_X_TLS_NEVER },
82 {
L(
"try"), LDAP_OPT_X_TLS_TRY }
87 {
L(
"always"), LDAP_DEREF_ALWAYS },
88 {
L(
"finding"), LDAP_DEREF_FINDING },
89 {
L(
"never"), LDAP_DEREF_NEVER },
90 {
L(
"searching"), LDAP_DEREF_SEARCHING }
155 struct timeval *net = NULL, *client = NULL;
161 if (ldap_get_option(conn->
handle, LDAP_OPT_NETWORK_TIMEOUT, &net) != LDAP_OPT_SUCCESS) {
165 if (ldap_get_option(conn->
handle, LDAP_OPT_TIMEOUT, &client) != LDAP_OPT_SUCCESS) {
169 if (ldap_get_option(conn->
handle, LDAP_OPT_TIMELIMIT, &server) != LDAP_OPT_SUCCESS) {
182 if (client && (client->tv_sec != -1)) {
190 if (net && (net->tv_sec != -1)) {
213 ldap_get_option(conn->
handle, LDAP_OPT_RESULT_CODE, &lib_errno);
214 if (lib_errno == LDAP_SUCCESS) {
218 return ldap_err2string(lib_errno);
237 int lib_errno = LDAP_SUCCESS;
238 int srv_errno = LDAP_SUCCESS;
240 char *part_dn = NULL;
241 char *srv_err = NULL;
245 if (ctrls) *ctrls = NULL;
248 ldap_get_option(conn->
handle, LDAP_OPT_RESULT_CODE, &lib_errno);
249 if (lib_errno != LDAP_SUCCESS)
goto process_error;
255 msg_type = ldap_msgtype(
msg);
260 case LDAP_RES_SEARCH_RESULT:
262 case LDAP_RES_EXTENDED:
263 case LDAP_RES_MODIFY:
264 lib_errno = ldap_parse_result(conn->
handle,
msg,
265 &srv_errno, &part_dn, &srv_err,
273 case LDAP_RES_SEARCH_ENTRY:
274 if (ctrls) lib_errno = ldap_get_entry_controls(conn->
handle,
msg, ctrls);
280 case LDAP_RES_SEARCH_REFERENCE:
281 if (ctrls) lib_errno = ldap_parse_reference(conn->
handle,
msg, NULL, ctrls, 0);
287 case LDAP_RES_INTERMEDIATE:
288 lib_errno = ldap_parse_intermediate(conn->
handle,
msg, NULL, NULL, ctrls, 0);
301 if (lib_errno != LDAP_SUCCESS) {
303 ldap_get_option(conn->
handle, LDAP_OPT_RESULT_CODE, &lib_errno);
307 if ((lib_errno == LDAP_SUCCESS) && (srv_errno != LDAP_SUCCESS)) {
308 lib_errno = srv_errno;
309 }
else if ((lib_errno != LDAP_SUCCESS) && (srv_errno == LDAP_SUCCESS)) {
310 srv_errno = lib_errno;
323 case LDAP_SASL_BIND_IN_PROGRESS:
328 case LDAP_NO_SUCH_OBJECT:
351 case LDAP_INSUFFICIENT_ACCESS:
352 fr_strerror_const(
"Insufficient access. Check the identity and password configuration directives");
356 case LDAP_UNWILLING_TO_PERFORM:
361 case LDAP_FILTER_ERROR:
371 case LDAP_TIMELIMIT_EXCEEDED:
376 case LDAP_SYNC_REFRESH_REQUIRED:
382 case LDAP_UNAVAILABLE:
383 case LDAP_SERVER_DOWN:
387 case LDAP_INVALID_CREDENTIALS:
388 case LDAP_CONSTRAINT_VIOLATION:
392 case LDAP_OPERATIONS_ERROR:
394 "See the ldap module configuration for details");
401 if (lib_errno == srv_errno) {
405 ldap_err2string(lib_errno), lib_errno,
406 ldap_err2string(srv_errno), srv_errno);
417 if (srv_err) ldap_memfree(srv_err);
418 if (part_dn) ldap_memfree(part_dn);
459 LDAPMessage *tmp_msg = NULL, *
msg;
460 LDAPMessage **result_p = result;
462 if (result) *result = NULL;
463 if (ctrls) *ctrls = NULL;
468 if (!result) result_p = &tmp_msg;
473 ldap_get_option(conn->
handle, LDAP_OPT_RESULT_CODE, &lib_errno);
485 lib_errno = LDAP_TIMEOUT;
496 for (
msg = ldap_first_message(conn->
handle, *result_p);
503 if (*result_p && (!result)) {
504 ldap_msgfree(*result_p);
531 char const *dn,
int scope,
char const *filter,
char const *
const *attrs,
532 LDAPControl **serverctrls, LDAPControl **clientctrls)
544 pconn, serverctrls, clientctrls);
556 memcpy(&search_attrs, &attrs,
sizeof(attrs));
566 if (ldap_search_ext(pconn->
handle, dn, scope, filter, search_attrs,
567 0, our_serverctrls, our_clientctrls, NULL, 0, msgid) != LDAP_SUCCESS) {
579 LDAPMessage *message;
580 char const *
const *attr;
582 struct berval **values;
587 message = ldap_first_entry(ld, query->
result);
590 dn = ldap_get_dn(ld, message);
593 attr = query->search.attrs;
594 if (!attr)
goto next;
597 values = ldap_get_values_len(ld, message, *attr);
599 RDEBUG3(
"Attribute \"%s\" not found", *attr);
601 count = ldap_count_values_len(values);
604 ldap_value_free_len(values);
622 switch (query->
ret) {
651 if (!query->
treq)
return;
660 switch (query->
treq->state) {
667 talloc_steal(query->
treq, query);
683#define SET_LDAP_CTRLS(_dest, _src) \
687 for (i = 0; i < LDAP_MAX_CONTROLS; i++) { \
688 if (!(_src[i])) break; \
689 _dest[i].control = _src[i]; \
711 char const *base_dn,
int scope,
char const *filter,
char const *
const *attrs,
712 LDAPControl **serverctrls, LDAPControl **clientctrls)
757 char const *dn, LDAPMod *mods[],
758 LDAPControl **serverctrls, LDAPControl **clientctrls)
802 char const *dn, LDAPMod *mods[],
803 LDAPControl **serverctrls, LDAPControl **clientctrls)
811 pconn, serverctrls, clientctrls);
817 RDEBUG2(
"Modifying object with DN \"%s\"", dn);
818 if(ldap_modify_ext(pconn->
handle, dn, mods, our_serverctrls, our_clientctrls, msgid) != LDAP_SUCCESS) {
843 LDAPControl **serverctrls, LDAPControl **clientctrls)
851 pconn, serverctrls, clientctrls);
857 RDEBUG2(
"Deleting object with DN \"%s\"", dn);
858 if(ldap_delete_ext(pconn->
handle, dn, our_serverctrls, our_clientctrls, msgid) != LDAP_SUCCESS) {
884 char const *reqoid,
struct berval *reqdata,
885 LDAPControl **serverctrls, LDAPControl **clientctrls)
926 char const *reqoid,
struct berval *reqdata)
930 RDEBUG2(
"Requesting extended operation with OID %s", reqoid);
931 if (ldap_extended_operation(pconn->
handle, reqoid, reqdata, NULL, NULL, msgid)) {
933 RPERROR(
"Failed requesting extended operation");
1003static inline CC_HINT(always_inline)
1028 char const *base_dn,
int scope,
char const *filter,
char const *
const * attrs,
1029 LDAPControl **serverctrls, LDAPControl **clientctrls)
1034 query->
dn = base_dn;
1035 query->search.scope = scope;
1036 query->search.filter = filter;
1037 query->search.attrs =
UNCONST(
char const **, attrs);
1054 LDAPMod *mods[], LDAPControl **serverctrls, LDAPControl **clientctrls)
1077 LDAPControl **serverctrls, LDAPControl **clientctrls)
1082 query->extended.reqoid = reqoid;
1083 query->extended.reqdata = reqdata;
1092 if (ldap_unbind_ext_s(handle, NULL, NULL) < 0)
return -1;
1111 ldap_initialize(&handle,
"");
1128 static bool done_config;
1131 if (done_config)
return 0;
1133#define do_ldap_global_option(_option, _name, _value) \
1134 if (ldap_set_option(NULL, _option, _value) != LDAP_OPT_SUCCESS) do { \
1136 ldap_get_option(NULL, LDAP_OPT_RESULT_CODE, &_ldap_errno); \
1137 ERROR("Failed setting global option %s: %s", _name, \
1138 (_ldap_errno != LDAP_SUCCESS) ? ldap_err2string(_ldap_errno) : "Unknown error"); \
1142#define maybe_ldap_global_option(_option, _name, _value) \
1143 if (_value) do_ldap_global_option(_option, _name, _value)
1168 static LDAPAPIInfo info = { .ldapai_info_version = LDAP_API_INFO_VERSION };
1180 ERROR(
"Failed initialising global LDAP handle");
1184 ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info);
1185 if (ldap_errno == LDAP_OPT_SUCCESS) {
1193 if (strcasestr(info.ldapai_vendor_name, LDAP_VENDOR_NAME) == NULL) {
1194 WARN(
"ldap - libldap vendor changed since the server was built");
1195 WARN(
"ldap - linked: %s, built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME);
1198 if (info.ldapai_vendor_version < LDAP_VENDOR_VERSION) {
1199 WARN(
"ldap - libldap older than the version the server was built against");
1200 WARN(
"ldap - linked: %i, built: %i",
1201 info.ldapai_vendor_version, LDAP_VENDOR_VERSION);
1204 INFO(
"ldap - libldap vendor: %s, version: %i", info.ldapai_vendor_name,
1205 info.ldapai_vendor_version);
1207 if (info.ldapai_extensions) {
1210 for (p = info.ldapai_extensions; *p != NULL; p++) {
1211 INFO(
"ldap - extension: %s", *p);
1215 ldap_memfree(info.ldapai_extensions);
1218 ldap_memfree(info.ldapai_vendor_name);
1221 DEBUG(
"ldap - Falling back to build time libldap version info. Query for LDAP_OPT_API_INFO "
1222 "returned: %i", ldap_errno);
1223 INFO(
"ldap - libldap vendor: %s, version: %i.%i.%i", LDAP_VENDOR_NAME,
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
#define fr_atexit_thread_local(_name, _free, _uctx)
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define USES_APPLE_DEPRECATED_API
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
@ CONF_FLAG_FILE_EXISTS
File matching value must exist.
Defines a CONF_PAIR to C data type mapping.
static char const * spaces
static void * fr_dlist_remove(fr_dlist_head_t *list_head, void *ptr)
Remove an item from the list.
static void fr_dlist_talloc_free(fr_dlist_head_t *head)
Free all items in a doubly linked list (with talloc)
static unsigned int fr_dlist_num_elements(fr_dlist_head_t const *head)
Return the number of elements in the dlist.
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
char const * name
Name of library and section within global config.
Structure to define how to initialise libraries with global configuration.
fr_ldap_control_t serverctrls[LDAP_MAX_CONTROLS]
Server controls specific to this query.
fr_time_delta_t res_timeout
How long we wait for results.
char ** referral_urls
Referral results to follow.
size_t fr_ldap_common_dn(char const *full, char const *part)
Find the place at which the two DN strings diverge.
LDAP * handle
libldap handle.
char const * dn
Base DN for searches, DN for modifications.
void fr_ldap_control_merge(LDAPControl *serverctrls_out[], LDAPControl *clientctrls_out[], size_t serverctrls_len, size_t clientctrls_len, fr_ldap_connection_t *conn, LDAPControl *serverctrls_in[], LDAPControl *clientctrls_in[])
Merge connection and call specific client and server controls.
fr_dlist_head_t referrals
List of parsed referrals.
fr_ldap_result_code_t ret
Result code.
bool freeit
Whether the control should be freed after we've finished using it.
fr_rb_tree_t * queries
Outstanding queries on this connection.
@ FR_LDAP_STATE_ERROR
Connection is in an error state.
@ FR_LDAP_STATE_BIND
Connection is being bound.
@ FR_LDAP_STATE_START_TLS
TLS is being negotiated.
@ FR_LDAP_STATE_RUN
Connection is muxing/demuxing requests.
@ FR_LDAP_STATE_INIT
Connection uninitialised.
trunk_request_t * treq
Trunk request this query is associated with.
fr_dlist_head_t refs
Replied to queries still referencing this connection.
fr_ldap_config_t const * config
rlm_ldap connection configuration.
fr_ldap_control_t clientctrls[LDAP_MAX_CONTROLS]
Client controls specific to this query.
char const * tls_random_file
Path to the ramdon file if /dev/random and /dev/urandom are unavailable.
fr_ldap_request_type_t
Types of LDAP requests.
@ LDAP_REQUEST_MODIFY
A modification to an LDAP entity.
@ LDAP_REQUEST_SEARCH
A lookup in an LDAP directory.
@ LDAP_REQUEST_EXTENDED
An extended LDAP operation.
fr_ldap_connection_t * ldap_conn
LDAP connection this query is running on.
@ LDAP_RESULT_SUCCESS
Successfully got LDAP results.
@ LDAP_RESULT_PENDING
Result not yet returned.
@ LDAP_RESULT_NO_RESULT
No results returned.
@ LDAP_RESULT_BAD_DN
The requested DN does not exist.
#define LDAP_MAX_CONTROLS
Maximum number of client/server controls.
char const * name
Name of the module that created this connection.
LDAPMessage * result
Head of LDAP results list.
LDAPControl * control
LDAP control.
#define LDAP_VENDOR_VERSION_PATCH
trunk_t * trunk
Connection trunk.
connection_t * conn
Connection state handle.
uint32_t ldap_debug
LDAP debug level.
@ LDAP_EXT_BINDPW
Specifies the password for an LDAP bind.
@ LDAP_EXT_BINDNAME
Specifies the user DN or name for an LDAP bind.
fr_ldap_request_type_t type
What type of query this is.
fr_ldap_rcode_t
Codes returned by fr_ldap internal functions.
@ LDAP_PROC_CONTINUE
Operation is in progress.
@ LDAP_PROC_SUCCESS
Operation was successful.
@ LDAP_PROC_REFERRAL
LDAP server returned referral URLs.
@ LDAP_PROC_TIMEOUT
Operation timed out.
@ LDAP_PROC_ERROR
Unrecoverable library/server error.
@ LDAP_PROC_BAD_CONN
Transitory error, caller should retry the operation with a new connection.
@ LDAP_PROC_NOT_PERMITTED
Operation was not permitted, either current user was locked out in the case of binds,...
@ LDAP_PROC_REJECT
Bind failed, user was rejected.
@ LDAP_PROC_REFRESH_REQUIRED
Don't continue with the current refresh phase, exit, and retry the operation with a NULL cookie.
@ LDAP_PROC_BAD_DN
Specified an invalid object in a bind or search DN.
@ LDAP_PROC_NO_RESULT
Got no results.
LDAPURLDesc * ldap_url
parsed URL for current query if the source of the query was a URL.
Connection configuration.
Tracks the state of a libldap connection handle.
Thread LDAP trunk structure.
libldap global configuration data
static fr_libldap_global_config_t libldap_global_config
static unlang_action_t ldap_trunk_query_results(rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
Handle the return code from parsed LDAP results to set the module rcode.
#define do_ldap_global_option(_option, _name, _value)
fr_ldap_rcode_t fr_ldap_error_check(LDAPControl ***ctrls, fr_ldap_connection_t const *conn, LDAPMessage *msg, char const *dn)
Perform basic parsing of multiple types of messages, checking for error conditions.
LDAP * ldap_global_handle
Hack for OpenLDAP libldap global initialisation.
#define maybe_ldap_global_option(_option, _name, _value)
size_t fr_ldap_dereference_len
static int _ldap_query_free(fr_ldap_query_t *query)
Free any libldap structures when an fr_ldap_query_t is freed.
fr_ldap_rcode_t fr_ldap_search_async(int *msgid, request_t *request, fr_ldap_connection_t *pconn, char const *dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Search for something in the LDAP directory.
char const * fr_ldap_error_str(fr_ldap_connection_t const *conn)
Return the error string associated with a handle.
static fr_ldap_config_t ldap_global_handle_config
Used to set the global log prefix for functions which don't operate on connections.
LDAP * fr_ldap_handle_thread_local(void)
Get a thread local dummy LDAP handle.
static void ldap_trunk_search_results_debug(request_t *request, fr_ldap_query_t *query)
fr_table_num_sorted_t const fr_ldap_supported_extensions[]
int fr_ldap_global_config(int debug_level, char const *tls_random_file)
Change settings global to libldap.
global_lib_autoinst_t fr_libldap_global_config
static conf_parser_t const ldap_global_config[]
fr_ldap_rcode_t fr_ldap_result(LDAPMessage **result, LDAPControl ***ctrls, fr_ldap_connection_t const *conn, int msgid, int all, char const *dn, fr_time_delta_t timeout)
Parse response from LDAP server dealing with any errors.
unlang_action_t fr_ldap_trunk_modify(TALLOC_CTX *ctx, fr_ldap_query_t **out, request_t *request, fr_ldap_thread_trunk_t *ttrunk, char const *dn, LDAPMod *mods[], LDAPControl **serverctrls, LDAPControl **clientctrls)
Run an async modification LDAP query on a trunk connection.
size_t fr_ldap_supported_extensions_len
size_t fr_ldap_connection_states_len
fr_table_num_sorted_t const fr_ldap_connection_states[]
static void libldap_free(void)
Free any global libldap resources.
fr_ldap_rcode_t fr_ldap_modify_async(int *msgid, request_t *request, fr_ldap_connection_t *pconn, char const *dn, LDAPMod *mods[], LDAPControl **serverctrls, LDAPControl **clientctrls)
Modify something in the LDAP directory.
fr_table_num_sorted_t const fr_ldap_tls_require_cert[]
fr_table_num_sorted_t const fr_ldap_dereference[]
fr_ldap_rcode_t fr_ldap_extended_async(int *msgid, request_t *request, fr_ldap_connection_t *pconn, char const *reqoid, struct berval *reqdata)
Initiate an LDAP extended operation.
static void ldap_trunk_query_cancel(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
Signal an LDAP query running on a trunk connection to cancel.
fr_ldap_rcode_t fr_ldap_delete_async(int *msgid, request_t *request, fr_ldap_connection_t *pconn, char const *dn, LDAPControl **serverctrls, LDAPControl **clientctrls)
Modify something in the LDAP directory.
static int _ldap_handle_thread_local_free(void *handle)
#define SET_LDAP_CTRLS(_dest, _src)
fr_ldap_query_t * fr_ldap_modify_alloc(TALLOC_CTX *ctx, char const *dn, LDAPMod *mods[], LDAPControl **serverctrls, LDAPControl **clientctrls)
Allocate a new LDAP modify object.
fr_ldap_query_t * fr_ldap_search_alloc(TALLOC_CTX *ctx, char const *base_dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Allocate a new search object.
static fr_ldap_query_t * ldap_query_alloc(TALLOC_CTX *ctx, fr_ldap_request_type_t type)
Allocate an fr_ldap_query_t, setting the talloc destructor.
unlang_action_t fr_ldap_trunk_extended(TALLOC_CTX *ctx, fr_ldap_query_t **out, request_t *request, fr_ldap_thread_trunk_t *ttrunk, char const *reqoid, struct berval *reqdata, LDAPControl **serverctrls, LDAPControl **clientctrls)
Run an async LDAP "extended operation" query on a trunk connection.
unlang_action_t fr_ldap_trunk_search(TALLOC_CTX *ctx, fr_ldap_query_t **out, request_t *request, fr_ldap_thread_trunk_t *ttrunk, char const *base_dn, int scope, char const *filter, char const *const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls)
Run an async search LDAP query on a trunk connection.
void fr_ldap_timeout_debug(request_t *request, fr_ldap_connection_t const *conn, fr_time_delta_t timeout, char const *prefix)
Prints information to the debug log on the current timeout settings.
fr_ldap_query_t * fr_ldap_extended_alloc(TALLOC_CTX *ctx, char const *reqoid, struct berval *reqdata, LDAPControl **serverctrls, LDAPControl **clientctrls)
Allocate a new LDAP extended operations object.
size_t fr_ldap_tls_require_cert_len
fr_table_num_sorted_t const fr_ldap_scope[]
static int libldap_init(void)
Initialise libldap library and set global options.
static _Thread_local LDAP * ldap_thread_local_handle
Hack for functions which require an ldap handle.
int fr_ldap_init(void)
Initialise libldap and check library versions.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
#define DEBUG_ENABLED4
True if global debug level 1-3 messages are enabled.
#define RPEDEBUG(fmt,...)
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
#define RDEBUG_ENABLED4
True if request debug level 1-4 messages are enabled.
#define RINDENT()
Indent R* messages by one level.
void fr_canonicalize_error(TALLOC_CTX *ctx, char **sp, char **text, ssize_t slen, char const *fmt)
Canonicalize error strings, removing tabs, and generate spaces for error marker.
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
#define RETURN_MODULE_FAIL
rlm_rcode_t
Return codes indicating the result of the module call.
#define RETURN_MODULE_NOTFOUND
fr_signal_t
Signals that can be generated/processed by request signal handlers.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in a lexicographically sorted array of name to num mappings.
#define fr_time_delta_wrap(_time)
#define fr_time_delta_ispos(_a)
#define fr_time_delta_to_timeval(_delta)
Convert a delta to a timeval.
static fr_time_delta_t fr_time_delta_from_timeval(struct timeval const *tv)
A time delta, a difference in time measured in nanoseconds.
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.
void trunk_request_signal_cancel(trunk_request_t *treq)
Cancel a trunk request.
@ TRUNK_ENQUEUE_OK
Operation was successful.
@ TRUNK_ENQUEUE_IN_BACKLOG
Request should be enqueued in backlog.
@ TRUNK_REQUEST_STATE_PARTIAL
Some of the request was written to the socket, more of it should be written later.
@ TRUNK_REQUEST_STATE_CANCEL_SENT
We've informed the remote server that the request has been cancelled.
@ TRUNK_REQUEST_STATE_CANCEL
A request on a particular socket was cancel.
@ TRUNK_REQUEST_STATE_CANCEL_PARTIAL
We partially wrote a cancellation request.
@ TRUNK_REQUEST_STATE_CANCEL_COMPLETE
Remote server has acknowledged our cancellation.
@ TRUNK_REQUEST_STATE_SENT
Was written to a socket. Waiting for a response.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
#define fr_box_time_delta(_val)
static size_t char ** out