29RCSID(
"$Id: 70cbd7a47e71cd61840e791f9c878659b03cd0a5 $")
34#include <freeradius-devel/redis/base.h>
35#include <freeradius-devel/redis/cluster_async.h>
37#include <freeradius-devel/server/modpriv.h>
38#include <freeradius-devel/server/module_rlm.h>
39#include <freeradius-devel/io/coord_pair.h>
41#include <freeradius-devel/unlang/xlat_func.h>
43#include <freeradius-devel/util/base16.h>
44#include <freeradius-devel/util/debug.h>
45#include <freeradius-devel/util/types.h>
122#define REDIS_XLAT_CMD_SETUP(_cmds, _argc, _argv, _arg_len, _rctx, _read_only, _func) \
124 (fr_redis_command_literal_add(_cmds, "READONLY", redis_xlat_status_check, _rctx) != FR_REDIS_PIPELINE_OK)) \
125 return XLAT_ACTION_FAIL; \
126if (fr_redis_command_argv_add(_cmds, _argc, _argv, _arg_len, _func, _rctx) != FR_REDIS_PIPELINE_OK) \
127 return XLAT_ACTION_FAIL; \
129 (fr_redis_command_literal_add(_cmds, "READWRITE", redis_xlat_status_check, _rctx) != FR_REDIS_PIPELINE_OK)) \
130 return XLAT_ACTION_FAIL
178 body = *((
char **)
out);
196 if (reply->type != REDIS_REPLY_STATUS) {
197 RWARN(
"Did not receive expected redis status reply");
202 if (strcmp(reply->str,
"OK") != 0) {
214 if (reply->type != REDIS_REPLY_STATUS) {
215 RWARN(
"Did not receive expected redis status reply");
219 if (strcmp(reply->str,
"PONG") != 0) {
233 RDEBUG2(
"Forcibly cancelling pending redis command");
244 RPERROR(
"PING after cluter remap failed");
281 if (!
inst->conf.use_cluster_map) {
282 RWARN(
"Cluster map not in use");
288 RPEDEBUG(
"Failed to initiate cluster remap");
344 unsigned long idx = 0;
348 if (idx_vb) idx = idx_vb->vb_uint32;
359 RDEBUG2(
"No node available for this key slot");
365 REDEBUG(
"Failed retrieving node information");
389 RDEBUG2(
"Forcibly cancelling pending redis lua command");
406 RPERROR(
"Failed loading lua script");
427 if (reply->type != REDIS_REPLY_STRING) {
428 REDEBUG(
"Unexpected reply type after loading function");
432 if (strcmp(reply->str, xlat_rctx->
func->
digest) == 0) {
438 REDEBUG(
"Function digest %s, does not match calculated digest %s", reply->str, xlat_rctx->
func->
digest);
456 while ((child_vb = fr_value_box_list_pop_head(&vb->vb_group))) fr_value_box_list_insert_tail(&xlat_rctx->
out, child_vb);
459 fr_value_box_list_insert_tail(&xlat_rctx->
out, vb);
481 inst->coord_pair_reg,
false);
494 PERROR(
"Server returned error");
506 MEM(argv = talloc_array(cmds,
char const *, 3));
507 MEM(argv_len = talloc_array(cmds,
size_t, 3));
510 argv_len[0] =
sizeof(
"SCRIPT") - 1;
512 argv_len[1] =
sizeof(
"LOAD") - 1;
528 RPERROR(
"Failed executing lua script");
561 argc = fr_value_box_list_num_elements(
in);
563 REDEBUG(
"Too many arguments (%ld)", argc);
572 fr_value_box_list_init(&rctx->
out);
577 MEM(argv = talloc_array(cmds,
char const *, argc));
578 MEM(arg_len = talloc_array(cmds,
size_t, argc));
584 arg_len[0] =
sizeof(
"EVALSHA") - 1;
586 arg_len[1] =
sizeof(func->
digest) - 1;
593 RPERROR(
"Failed converting key count to string");
612 arg_len[argc++] = vb->vb_length;
620 key = (
uint8_t const *)argv[3];
621 key_len = arg_len[3];
668 while ((child_vb = fr_value_box_list_pop_head(&vb->vb_group))) fr_value_box_list_insert_tail(&xlat_rctx->
out, child_vb);
671 fr_value_box_list_insert_tail(&xlat_rctx->
out, vb);
689 inst->coord_pair_reg,
false);
704 RPERROR(
"Server returned error");
712 RPERROR(
"Failed executing Redis command");
752 fr_value_box_list_init(&rctx->
out);
764 RDEBUG3(
"Overriding node selection");
768 AF_UNSPEC,
true,
true) < 0) {
769 RPEDEBUG(
"Failed parsing node address");
779 RPEDEBUG(
"Failed locating cluster node");
783 fr_value_box_list_talloc_free_head(
in);
790 argc = fr_value_box_list_num_elements(
in);
791 MEM(argv = talloc_array(cmds,
char const *, argc));
792 MEM(arg_len = talloc_array(cmds,
size_t, argc));
803 argv[argc] =
talloc_strndup(argv, vb->vb_strvalue + 1, vb->vb_length - 1);
804 arg_len[argc] = vb->vb_length - 1;
806 argv[argc] =
talloc_strndup(argv, vb->vb_strvalue, vb->vb_length);
807 arg_len[argc] = vb->vb_length;
820 key = (
uint8_t const *)argv[1];
821 key_len = arg_len[1];
836 UNUSED redisReply *reply,
void *rctx)
839 DEBUG2(
"Loaded lua function \"%s\" onto node", func->
name);
853 MEM(argv = talloc_array(cmds,
char const *, 3));
854 MEM(argv_len = talloc_array(cmds,
size_t, 3));
857 argv_len[0] =
sizeof(
"SCRIPT") - 1;
859 argv_len[1] =
sizeof(
"LOAD") - 1;
860 argv[2] = func->body;
871 ERROR(
"Failed to enqueue lua function loading");
882 if (talloc_array_length(
inst->lua.funcs) == 0) {
898 if (!
inst->conf.use_cluster_map)
return 0;
903 ERROR(
"Failed to attach to coordinator");
919 inst->conf.module_name = mctx->
mi->module->
name;
922 if (
inst->conf.use_tls) {
925 if (!
inst->tls_conf) {
931 if (!
inst->conf.use_cluster_map)
return 0;
933 if (
inst->conf.database) {
934 cf_log_err(mctx->
mi->
conf,
"Cannot set Redis database number when cluster in use");
940 .worker_cb = worker_pair_callbacks,
941 .cb_id = REDIS_COORD_PAIR_CALLBACK_ID,
946 if (!
inst->coord_pair_reg)
return -1;
952 .coord_cb = coord_callbacks,
953 .worker_cb = worker_callbacks,
957 if (!
inst->coord_reg)
return -1;
966 if (!t->
cw)
return 0;
977 if (!
inst->conf.use_cluster_map)
return 0;
#define fr_base16_encode(_out, _in)
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM *ci, conf_parser_t const *rule)
Parses a CONF_PAIR into a C data type.
#define CONF_PARSER_TERMINATOR
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
#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_SUBSECTION_ALLOC(_name, _type, _flags, _struct, _field, _subcs)
A conf_parser_t multi-subsection.
char const * name2
Second identifier for CONF_SECTION.
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
@ CONF_FLAG_MULTI
CONF_PAIR can have multiple copies.
@ CONF_FLAG_OK_MISSING
OK if it's missing.
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Defines a CONF_PAIR to C data type mapping.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
#define cf_log_err(_cf, _fmt,...)
#define cf_log_debug(_cf, _fmt,...)
int fr_redis_ct_map_bootstrap(fr_redis_ct_t *rtcluster, fr_coord_worker_t *cw, fr_coord_pair_reg_t *coord_pair_reg)
Initiate bootstrapping of the cluster map.
fr_redis_async_cmd_t * fr_redis_async_cmd_start(TALLOC_CTX *ctx, request_t *request, fr_redis_async_rcode_t *rcode, fr_redis_ct_t *rtcluster, uint8_t const *key, size_t key_len, fr_redis_command_set_t *cmds, bool read_only, fr_redis_ct_node_t *node)
Start running a command set on an async redis cluster.
fr_redis_async_rcode_t fr_redis_ct_map_get(fr_redis_ct_t *rtcluster, fr_coord_worker_t *cw, fr_coord_pair_reg_t *coord_pair_reg, bool force)
Initiate updating of the cluster map.
void fr_redis_async_cmd_cancel(fr_redis_async_cmd_t *cmd)
Cancel a Redis async command.
fr_redis_ct_node_t * fr_redis_ct_node_by_addr(fr_redis_ct_t *rtcluster, fr_redis_io_conf_t *ioconf)
fr_redis_async_rcode_t fr_redis_async_cmd_resend(fr_redis_async_cmd_t *cmd)
Re-submit a redis async command set.
fr_redis_ct_node_t const * fr_redis_ct_replica(fr_redis_ct_t *rtcluster, fr_redis_ct_key_slot_t const *key_slot, uint8_t replica_num)
Return the replica node that would be used for a particular key slot.
fr_redis_trunk_t * fr_redis_async_cmd_trunk(fr_redis_async_cmd_t *cmd)
Fetch the redis trunk a command is associated with.
fr_redis_ct_key_slot_t const * fr_redis_ct_slot_by_key(fr_redis_ct_t *rtcluster, request_t *request, uint8_t const *key, size_t key_len)
Resolve key to key slot.
fr_redis_async_rcode_t fr_redis_async_cmd_redirect(fr_redis_async_cmd_t *cmd)
Re-submit a redis async command set on a different node.
fr_redis_ct_t * fr_redis_ct_alloc(TALLOC_CTX *ctx, CONF_SECTION *tls_cs, fr_event_list_t *el, fr_redis_conf_t *conf, fr_redis_trunk_active_t active, void *active_uctx, bool active_oneshot)
Allocate per-thread, per-cluster instance.
int fr_redis_ct_port(uint16_t *out, fr_redis_ct_node_t const *node)
Return the port of a particular node.
fr_redis_ct_node_t const * fr_redis_ct_master(fr_redis_ct_t *rtcluster, fr_redis_ct_key_slot_t const *key_slot)
Return the master node that would be used for a particular key slot.
char const * fr_redis_ct_ipaddr(fr_redis_ct_node_t const *node)
Return the ipaddr of a particular node.
Structure for holding the state of an async redis command set.
Thread local state for a cluster.
#define REDIS_ASYNC_COORD_CALLBACKS(_thread_type)
#define REDIS_ASYNC_START_RCODE_PROCESS(_rcode, _cluster, _cw, _coord_pair_reg, _error_msg, _error_ret)
Convenience macro to reduce boilerplate.
fr_coord_reg_t * fr_coord_register(fr_coord_reg_ctx_t *reg_ctx)
Register a coordinator.
fr_coord_worker_t * fr_coord_attach(TALLOC_CTX *ctx, fr_event_list_t *el, fr_coord_reg_t *coord_reg)
Attach a worker to a coordinator.
void fr_coord_deregister(fr_coord_reg_t *coord_reg)
De-register a coordinator.
int fr_coord_detach(fr_coord_worker_t *cw, bool exiting)
Signal a coordinator that a worker wants to detach.
A coordinator registration.
The worker end of worker <-> coordinator communication.
fr_coord_pair_reg_t * fr_coord_pair_register(fr_coord_pair_reg_ctx_t *reg_ctx)
Register a set of callbacks for pair list based coordinator messages.
struct fr_coord_pair_reg_s fr_coord_pair_reg_t
#define FR_COORD_PAIR_CB_CTX_SET(_in_cb, _out_cb, _reg)
Set up ctx on pair list callbacks.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
#define DICT_AUTOLOAD_TERMINATOR
Specifies a dictionary which must be loaded/loadable for the module to function.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
static xlat_action_t redis_remap_xlat(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
Force a redis cluster remap.
static xlat_action_t redis_node_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the node that is currently servicing a particular key.
static xlat_action_t redis_xlat(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Xlat to make calls to redis.
int fr_inet_pton_port(fr_ipaddr_t *out, uint16_t *port_out, char const *value, ssize_t inlen, int af, bool resolve, bool mask)
Parses IPv4/6 address + port, to fr_ipaddr_t and integer (port)
char * fr_inet_ntop(char out[static FR_IPADDR_STRLEN], size_t outlen, fr_ipaddr_t const *addr)
Print the address portion of a fr_ipaddr_t.
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
#define RPEDEBUG(fmt,...)
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_GROUP
A grouping of other attributes.
module_instance_t const * mi
Instance of the module being instantiated.
void * thread
Thread specific instance data.
fr_event_list_t * el
Event list to register any IO handlers and timers against.
module_instance_t * mi
Module instance to detach.
void * thread
Thread instance data.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for detach calls.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
module_t common
Common fields presented by all modules.
char const * fr_redis_command_get_cmd(fr_redis_command_t *cmd)
fr_redis_async_rcode_t fr_redis_command_set_rcode(fr_redis_command_set_t *cmds)
Extract the rcode from a command set.
fr_redis_pipeline_status_t redis_command_set_enqueue(fr_redis_trunk_t *rtrunk, fr_redis_command_set_t *cmds)
Enqueue a command set on a specific trunk.
int fr_redis_command_set_reset(fr_redis_command_set_t *cmds)
Reset a command set to it's state before enqueuing.
fr_redis_command_set_t * fr_redis_command_set_alloc(TALLOC_CTX *ctx, request_t *request, fr_redis_command_set_complete_t complete, fr_redis_command_set_fail_t fail, void *rctx, bool autofree)
Allocate a new command set.
fr_redis_pipeline_status_t fr_redis_command_argv_add(fr_redis_command_set_t *cmds, size_t argc, char const **argv, size_t *argv_len, fr_redis_command_complete_t complete, void *rctx)
Add a command with arguments to the command set.
fr_redis_pipeline_status_t fr_redis_command_literal_add(fr_redis_command_set_t *cmds, char const *cmd_str, fr_redis_command_complete_t complete, void *rctx)
Add a literal command to the command set.
Represents a single command.
Represents a collection of pipelined commands.
@ FR_REDIS_PIPELINE_OK
No failure.
static const conf_parser_t config[]
int fr_redis_reply_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, redisReply *reply, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, bool box_error, bool shallow))
Convert a string or integer type to fr_value_box_t of specified type.
int redis_dict_init(void)
Load the Redis dictionaries.
#define REDIS_COMMON_CONFIG
@ REDIS_ASYNC_RCODE_MOVE
Attempt operation on an alternative node with remap.
@ REDIS_ASYNC_RCODE_ERROR
Unrecoverable error.
@ REDIS_ASYNC_RCODE_ASK
Attempt operation on an alternative node.
@ REDIS_ASYNC_RCODE_TRY_AGAIN
Try the operation again.
@ REDIS_ASYNC_RCODE_NO_SCRIPT
Script doesn't exist.
@ REDIS_ASYNC_RCODE_SUCCESS
Operation was successful.
void fr_redis_version_print(void)
Print the version of libhiredis the server was built against.
Configuration parameters for a redis connection.
static void redis_lua_xlat_results(request_t *request, fr_redis_command_t *cmd, redisReply *reply, void *rctx)
Callback to convert redis reply to value boxes.
fr_dict_autoload_t rlm_redis_dict[]
static int mod_detach(module_detach_ctx_t const *mctx)
static int mod_load(void)
fr_redis_async_cmd_t * cmd
Async command context.
rlm_redis_lua_t lua
Array of functions to register.
static void lua_script_load(fr_redis_trunk_t *rtrunk, void *uctx)
static int mod_coord_attach(module_thread_inst_ctx_t const *mctx)
static conf_parser_t module_lua[]
TALLOC_CTX * ctx
Context to allocate boxes.
redis_lua_func_t const * func
Lua function.
static void redis_xlat_ping_check(request_t *request, fr_redis_command_t *cmd, redisReply *reply, void *rctx)
Callback to check redis replied with "PONG" when expected.
TALLOC_CTX * ctx
Context to allocate boxes.
xlat_action_t action
Xlat action set in callback.
static xlat_action_t redis_xlat_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
bool read_only
Should the xlat be run read only.
fr_redis_conf_t conf
Connection parameters for the Redis server.
static xlat_action_t redis_remap_xlat_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
static int redis_lua_func_instantiate(xlat_inst_ctx_t const *xctx)
Copies the function configuration into xlat function instance data.
fr_redis_command_set_t * cmds
Command set for this xlat.
static xlat_action_t redis_lua_load_resume(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
Process the results of loading a lua script to a redis server.
fr_value_box_list_t out
List to store boxes in callback.
redis_lua_func_t ** funcs
Array of functions to register.
fr_coord_reg_t * coord_reg
Coordinator registration.
rlm_redis_t const * inst
Module instance.
char digest[(SHA1_DIGEST_LENGTH *2)+1]
pre-computed hash of lua code.
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static void redis_lua_load_results(request_t *request, UNUSED fr_redis_command_t *cmd, redisReply *reply, void *rctx)
Callback to verify reply to SCRIPT LOAD.
redis_lua_func_t * func
Function configuration.
static xlat_action_t redis_lua_func_resume(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
Process the results from calling a lua script.
static conf_parser_t module_lua_func[]
static void redis_xlat_cancel(xlat_ctx_t const *xctx, request_t *request, UNUSED fr_signal_t action)
Common cancellation for redis xlats.
char const * body
the actual lua code.
fr_redis_command_set_t * cmds
Command set for this xlat.
char const * name
Friendly name for the function. Used to register the equivalent xlat.
static fr_dict_t const * dict_redis
fr_coord_pair_reg_t * coord_pair_reg
Coord pair registration.
static void redis_lua_cancel(xlat_ctx_t const *xctx, request_t *request, UNUSED fr_signal_t action)
Cancellation of Redis Lua load / exec.
#define REDIS_XLAT_CMD_SETUP(_cmds, _argc, _argv, _arg_len, _rctx, _read_only, _func)
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
fr_coord_worker_t * cw
Coord-worker for fetching cluster map.
static xlat_arg_parser_t const redis_node_xlat_args[]
static void redis_xlat_results(request_t *request, fr_redis_command_t *cmd, redisReply *reply, void *rctx)
Callback to convert redis reply to value boxes.
fr_value_box_list_t out
List to store boxes in callback.
static void lua_script_load_results(UNUSED request_t *request, UNUSED fr_redis_command_t *cmd, UNUSED redisReply *reply, void *rctx)
bool forced_node
Was the xlat called with a specific node.
static void redis_xlat_status_check(request_t *request, fr_redis_command_t *cmd, redisReply *reply, void *rctx)
Callback to check redis replied with "OK" when expected.
static xlat_action_t redis_lua_func_xlat(TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Call a lua function on the redis server.
static xlat_arg_parser_t const redis_args[]
static int lua_func_body_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Do basic processing for a lua function body and compute its sha1 hash.
xlat_action_t action
Xlat action set in callback.
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
CONF_SECTION * tls_conf
TLS CONF_SECTION.
static int mod_instantiate(module_inst_ctx_t const *mctx)
fr_redis_async_cmd_t * cmd
Async command context.
static conf_parser_t module_config[]
fr_redis_ct_t * rtcluster
Per thread Redis cluster.
static xlat_arg_parser_t const redis_lua_func_args[]
bool read_only
Function has no side effects.
Instance of a redis lua func xlat.
A lua function or stored procedure we make available as an xlat.
Resume context for redis lua xlat.
rlm_redis module instance
Resume context for redis xlat.
bool fr_sbuff_next_if_char(fr_sbuff_t *sbuff, char c)
Return true if the current char matches, and if it does, advance.
#define FR_SBUFF_IN(_start, _len_or_end)
#define fr_sbuff_current(_sbuff_or_marker)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define FR_SBUFF_OUT(_start, _len_or_end)
int fr_schedule_worker_id(void)
Return the worker id for the current thread.
#define MODULE_THREAD_INST(_ctype)
char const * name
Instance name e.g. user_database.
CONF_SECTION * conf
Module's instance configuration.
size_t inst_size
Size of the module's instance data.
void * data
Module's instance data.
void * boot
Data allocated during the boostrap phase.
void fr_sha1_init(fr_sha1_ctx *context)
void fr_sha1_final(uint8_t digest[static SHA1_DIGEST_LENGTH], fr_sha1_ctx *context)
void fr_sha1_update(fr_sha1_ctx *context, uint8_t const *in, size_t len)
#define SHA1_DIGEST_LENGTH
fr_signal_t
Signals that can be generated/processed by request signal handlers.
@ FR_SIGNAL_CANCEL
Request has been cancelled.
static char buff[sizeof("18446744073709551615")+3]
eap_aka_sim_process_conf_t * inst
#define talloc_get_type_abort_const
#define talloc_strndup(_ctx, _str, _len)
#define talloc_foreach(_array, _iter)
Iterate over a talloced array of elements.
#define talloc_strdup(_ctx, _str)
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
xlat_action_t unlang_xlat_yield(request_t *request, xlat_func_t resume, xlat_func_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
@ XLAT_ARG_VARIADIC_EMPTY_KEEP
Empty argument groups are left alone, and either passed through as empty groups or null boxes.
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
unsigned int required
Argument must be present, and non-empty.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_FAIL
An xlat function failed.
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumed by an xlat function.
#define fr_type_is_string(_x)
int fr_value_box_asprintf(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, bool tainted, char const *fmt,...)
Print a formatted string using our internal printf wrapper and assign it to a value box.
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
static fr_slen_t fr_value_box_aprint(TALLOC_CTX *ctx, char **out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules) 1(fr_value_box_print
#define fr_box_strvalue_len(_val, _len)
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
#define fr_value_box_list_foreach(_list_head, _iter)
static size_t char ** out
void * rctx
Resume context.
void const * inst
xlat instance data.
void * uctx
Passed to the registration function.
module_ctx_t const * mctx
Synthesised module calling ctx.
void * inst
xlat instance data to populate.
An xlat instantiation ctx.
void xlat_func_flags_set(xlat_t *x, xlat_func_flags_t flags)
Specify flags that alter the xlat's behaviour.
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
#define xlat_func_instantiate_set(_xlat, _instantiate, _inst_struct, _detach, _uctx)
Set a callback for global instantiation of xlat functions.
@ XLAT_FUNC_FLAG_MODULE_STATUS