25 RCSID(
"$Id: 3817ea0179ccf28a89d73ff72ead270b8a4bbbec $")
27 #include <freeradius-devel/server/base.h>
28 #include <freeradius-devel/server/modpriv.h>
29 #include <freeradius-devel/unlang/xlat_func.h>
30 #include <freeradius-devel/unlang/xlat.h>
31 #include <freeradius-devel/util/time.h>
101 if (op && op->
dump) op->
dump(request, frame);
108 static __thread
char buf[256];
111 #define UNWIND_FLAG_DUMP(attrib) \
112 if (unwind & attrib) strcat(buf, #attrib" ")
114 snprintf(buf,
sizeof(buf),
"unwind=0x%x (", unwind);
121 if (buf[len - 1] ==
' ') buf[len - 1] =
'\0';
124 #undef UNWIND_FLAG_DUMP
135 for (i =
stack->depth; i >= 0; i--) {
138 RDEBUG2(
"[%d] Frame contents", i);
143 #define DUMP_STACK if (DEBUG_ENABLED5) stack_dump(request)
162 rlm_rcode_t default_rcode,
bool do_next_sibling,
bool top_frame)
170 if (
DEBUG_ENABLED5)
RDEBUG3(
"unlang_interpret_push called with instruction type \"%s\" - args %s %s",
171 instruction ? instruction->
debug_name :
"<none>",
172 do_next_sibling ?
"UNLANG_NEXT_SIBLING" :
"UNLANG_NEXT_STOP",
173 top_frame ?
"UNLANG_TOP_FRAME" :
"UNLANG_SUB_FRAME");
182 RERROR(
"Call stack is too deep");
192 memset(frame, 0,
sizeof(*frame));
196 if (do_next_sibling) {
205 frame->
result = default_rcode;
208 if (!instruction)
return 0;
223 if (
vp->
da->dict != ref->
dict)
break;
261 RDEBUG2(
"<ignoring empty subsection>");
306 static inline CC_HINT(always_inline)
310 unlang_t const *instruction = frame->instruction;
313 RDEBUG4(
"** [%i] %s - have (%s %d) module returned (%s %d)",
314 stack->depth, __FUNCTION__,
325 RDEBUG3(
"Setting rcode to '%s'",
327 request->rcode = *result;
339 if (*priority < 0) *priority = 0;
341 RDEBUG4(
"** [%i] %s - action says to return with (%s %d)",
342 stack->depth, __FUNCTION__,
345 frame->result = *result;
346 frame->priority = *priority;
355 if (*priority < 0) *priority = 0;
357 RDEBUG4(
"** [%i] %s - action says to return with (%s %d)",
358 stack->depth, __FUNCTION__,
362 frame->priority = *priority;
372 RDEBUG4(
"** [%i] %s - action says to retry with",
373 stack->depth, __FUNCTION__);
375 if (*priority < 0) *priority = 0;
383 if (!frame->retry)
goto fail;
454 RDEBUG4(
"** [%i] %s - setting priority to (%s %d)",
455 stack->depth, __FUNCTION__,
464 if (*priority > frame->priority) {
465 frame->result = *result;
466 frame->priority = *priority;
468 RDEBUG4(
"** [%i] %s - over-riding result from higher priority to (%s %d)",
469 stack->depth, __FUNCTION__,
488 RDEBUG4(
"** [%i] %s - unwinding current frame with (%s %d) - flags - stack (%i), frame (%i)",
489 stack->depth, __FUNCTION__,
491 frame->priority,
stack->unwind, frame->uflags);
504 RDEBUG4(
"** [%i] %s - unwind stop (%s %d) - flags - stack unwind (%i), frame uflags (%i)",
505 stack->depth, __FUNCTION__,
507 frame->priority,
stack->unwind, frame->uflags);
525 static inline CC_HINT(always_inline)
533 while (frame->instruction) {
534 unlang_t const *instruction = frame->instruction;
558 request->ins_count++;
560 if (request->ins_count >= request->ins_max) {
561 RERROR(
"Failing request due to maximum instruction count %" PRIu64, request->ins_max);
579 RDEBUG4(
"** [%i] %s - STOP current subsection with (%s %d)",
580 stack->depth, __FUNCTION__,
612 ua = frame->process(result, request, frame);
632 RDEBUG4(
"** [%i] %s << %s (%d)",
stack->depth, __FUNCTION__,
653 "Instruction %s returned UNLANG_ACTION_PUSHED_CHILD, "
654 "but stack depth was not increased",
657 *result = frame->result;
665 if (*priority < 0) *priority = 0;
666 frame->result = *result;
667 frame->priority = *priority;
678 "Instruction %s returned UNLANG_ACTION_YIELD, but pushed additional "
679 "frames for evaluation. Instruction should return UNLANG_ACTION_PUSHED_CHILD "
680 "instead", instruction->
name);
683 RDEBUG4(
"** [%i] %s - yielding with current (%s %d)",
stack->depth, __FUNCTION__,
733 RDEBUG2(
"} # retrying the same section");
756 RDEBUG4(
"** [%i] %s - done current subsection with (%s %d)",
757 stack->depth, __FUNCTION__,
782 stack->priority = -1;
790 fr_assert_msg(intp,
"request has no interpreter associated");
792 RDEBUG4(
"** [%i] %s - interpret entered",
stack->depth, __FUNCTION__);
798 RDEBUG4(
"** [%i] %s - frame action %s",
stack->depth, __FUNCTION__,
891 RDEBUG4(
"** [%i] %s - continuing after subsection with (%s %d)",
892 stack->depth, __FUNCTION__,
902 RDEBUG4(
"** [%i] %s - done current subsection with (%s %d)",
903 stack->depth, __FUNCTION__,
910 RDEBUG4(
"** [%i] %s - interpret yielding",
stack->depth, __FUNCTION__);
912 return stack->result;
925 RDEBUG4(
"** [%i] %s - empty section, using stack result (%s %d)",
stack->depth, __FUNCTION__,
935 RDEBUG4(
"** [%i] %s - over-riding stack->result from higher priority to (%s %d)",
936 stack->depth, __FUNCTION__,
945 RDEBUG4(
"** [%i] %s - interpret exiting, returning %s",
stack->depth, __FUNCTION__,
957 rcode =
stack->result;
971 .debug_name =
"empty-group",
1003 REDEBUG(
"Failed to find pre-compiled unlang for section %s %s { ... }",
1032 RDEBUG4(
"** [%i] %s - substack begins",
stack->depth, __FUNCTION__);
1081 switch (request->type) {
1098 static inline CC_HINT(always_inline)
1108 request->log.indent.unlang = 0;
1112 static inline CC_HINT(always_inline)
1148 (void)talloc_get_type_abort(request,
request_t);
1161 if (action == FR_SIGNAL_CANCEL) {
1162 for (i =
depth; i > limit; i--) {
1163 frame = &
stack->frame[i];
1164 if (frame->
signal) frame->
signal(request, frame, action);
1180 for (i =
depth; i > limit; i--) {
1181 frame = &
stack->frame[i];
1182 if (frame->
signal) frame->
signal(request, frame, action);
1201 case FR_SIGNAL_DETACH:
1221 case FR_SIGNAL_CANCEL:
1242 case FR_SIGNAL_DETACH:
1261 RDEBUG(
"retry timeout reached, signalling interpreter to cancel.");
1279 return stack->depth;
1294 return stack->result;
1306 stack->result = rcode;
1386 RDEBUG3(
"Not marking runnable due to%s%s",
1388 " it not being yielded " :
"", scheduled ?
" it already being scheduled" :
"");
1392 RDEBUG3(
"Interpreter - Request marked as runnable");
1408 if (frame->
state)
return (TALLOC_CTX *)frame->
state;
1415 return (TALLOC_CTX *)(frame->
state = talloc_new(request));
1437 RDEBUG2(
"Request canceled by dynamic timeout");
1492 RPERROR(
"Failed inserting cancellation event");
1498 RPERROR(
"Failed associating cancellation event with request");
1553 char const *
fmt = arg->vb_strvalue;
1561 while (*
fmt ==
'.') {
1592 if (strcmp(
fmt,
"depth") == 0) {
1593 fr_value_box_int32(vb, NULL,
depth,
false);
1600 if (strcmp(
fmt,
"module") == 0) {
1609 if (strcmp(
fmt,
"name") == 0) {
1611 strlen(instruction->
name),
false) < 0)
goto error;
1618 if (strcmp(
fmt,
"processing_stage") == 0) {
1627 if (strcmp(
fmt,
"rcode") == 0) {
1636 if (strcmp(
fmt,
"server") == 0) {
1647 if (strcmp(
fmt,
"type") == 0) {
1657 if (!instruction->
ci) {
1666 if (strcmp(
fmt,
"line") == 0) {
1667 fr_value_box_int32(vb, NULL,
cf_lineno(instruction->
ci),
false);
1675 if (strcmp(
fmt,
"filename") == 0) {
1768 if (!
stack->intp)
return NULL;
1770 return stack->intp->el;
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_UNWIND
Break out of the current group.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
@ UNLANG_ACTION_EXECUTE_NEXT
Execute the next unlang_t.
@ UNLANG_ACTION_STOP_PROCESSING
Break out of processing the current request (unwind).
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
@ UNLANG_ACTION_YIELD
Temporarily pause execution until an event occurs.
static int const char * fmt
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define L(_str)
Helper for initialising arrays of string literals.
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
CONF_SECTION * unlang_call_current(request_t *request)
Return the last virtual server that was called.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
void * cf_data_value(CONF_DATA const *cd)
Return the user assigned value of CONF_DATA.
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
#define cf_data_find(_cf, _type, _name)
fr_table_num_sorted_t const mod_rcode_table[]
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
static int fr_dcursor_insert(fr_dcursor_t *cursor, void *v)
Insert directly after the current item.
fr_dcursor_eval_t void const * uctx
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
static fr_time_delta_t timeout
#define fr_event_timer_at(...)
#define fr_event_timer_in(...)
static xlat_action_t unlang_interpret_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Get information about the interpreter state.
static size_t unlang_action_table_len
static fr_table_num_ordered_t const unlang_frame_action_table[]
static void unlang_interpret_request_detach(request_t *request)
rlm_rcode_t unlang_interpret(request_t *request)
Run the interpreter for a current request.
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
bool unlang_request_is_done(request_t const *request)
Return whether a request has been marked done.
static unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame, rlm_rcode_t *result, int *priority)
Evaluates all the unlang nodes in a section.
static unlang_group_t empty_group
void unlang_interpet_frame_discard(request_t *request)
Discard the bottom most frame on the request's stack.
static unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t *frame, rlm_rcode_t *result, int *priority)
Update the current result after each instruction, and after popping each stack frame.
int unlang_interpret_push_instruction(request_t *request, void *instruction, rlm_rcode_t default_rcode, bool top_frame)
Push an instruction onto the request stack for later interpretation.
void unlang_interpret_request_done(request_t *request)
Indicate to the caller of the interpreter that this request is complete.
unlang_interpret_t * unlang_interpret_get(request_t *request)
Get the interpreter set for a request.
void unlang_interpret_set(request_t *request, unlang_interpret_t *intp)
Set a specific interpreter for a request.
rlm_rcode_t unlang_interpret_stack_result(request_t *request)
Get the current rcode for the frame.
int unlang_interpret_stack_depth(request_t *request)
Return the depth of the request's stack.
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
static xlat_arg_parser_t const unlang_interpret_xlat_args[]
bool unlang_request_is_scheduled(request_t const *request)
Return whether a request is currently scheduled.
void unlang_frame_signal(request_t *request, fr_signal_t action, int limit)
Send a signal (usually stop) to a request.
int unlang_interpret_init_global(TALLOC_CTX *ctx)
void unlang_interpret_set_thread_default(unlang_interpret_t *intp)
Set the default interpreter for this thread.
unlang_interpret_t * unlang_interpret_init(TALLOC_CTX *ctx, fr_event_list_t *el, unlang_request_func_t *funcs, void *uctx)
Initialize a unlang compiler / interpret.
int unlang_interpret_push(request_t *request, unlang_t const *instruction, rlm_rcode_t default_rcode, bool do_next_sibling, bool top_frame)
Push a new frame onto the stack.
bool unlang_request_is_cancelled(request_t const *request)
Return whether a request has been cancelled.
static void unlang_interpret_request_stop(request_t *request)
void unlang_interpret_signal(request_t *request, fr_signal_t action)
Send a signal (usually stop) to a request.
static char * stack_unwind_flag_dump(uint8_t unwind)
static xlat_arg_parser_t const unlang_cancel_xlat_args[]
static void instruction_timeout_handler(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *ctx)
static fr_table_num_ordered_t const unlang_action_table[]
static void stack_dump(request_t *request)
static int _local_variables_free(unlang_variable_ref_t *ref)
static void instruction_dump(request_t *request, unlang_t const *instruction)
bool unlang_interpret_is_resumable(request_t *request)
Check if a request as resumable.
unlang_action_t unlang_interpret_push_children(rlm_rcode_t *p_result, request_t *request, rlm_rcode_t default_rcode, bool do_next_sibling)
Push the children of the current frame onto a new frame onto the stack.
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
int unlang_interpret_push_section(request_t *request, CONF_SECTION *cs, rlm_rcode_t default_rcode, bool top_frame)
Push a configuration section onto the request stack for later interpretation.
void unlang_interpret_stack_result_set(request_t *request, rlm_rcode_t rcode)
Overwrite the current stack rcode.
#define UNWIND_FLAG_DUMP(attrib)
static void frame_dump(request_t *request, unlang_stack_frame_t *frame)
void * unlang_interpret_stack_alloc(TALLOC_CTX *ctx)
Allocate a new unlang stack.
static xlat_action_t unlang_cancel_never_run(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, UNUSED request_t *request, UNUSED fr_value_box_list_t *in)
static xlat_action_t unlang_cancel_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args)
Allows a request to dynamically alter its own lifetime.
static size_t unlang_frame_action_table_len
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
static void unlang_cancel_event(UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
Signal the request to stop executing.
static _Thread_local unlang_interpret_t * intp_thread_default
The default interpreter instance for this thread.
unlang_request_stop_t stop
function called when a request is signalled to stop.
#define UNLANG_STACK_MAX
The maximum depth of the stack.
unlang_request_done_t done_internal
Function called when an internal request completes.
unlang_request_resume_t resume
Function called when a request is resumed.
unlang_request_done_t done_external
Function called when a external request completes.
unlang_request_init_t detach
Function called when a request is detached.
unlang_request_runnable_t mark_runnable
Function called when a request needs to be added back to the runnable queue.
unlang_request_yield_t yield
Function called when a request yields.
unlang_request_done_t done_detached
Function called when a detached request completes.
unlang_request_scheduled_t scheduled
Function to check if a request is already scheduled.
unlang_request_init_t init_internal
Function called to initialise an internal request.
struct unlang_interpret_s unlang_interpret_t
Interpreter handle.
External functions provided by the owner of the interpret.
Private declarations for the unlang interpreter.
unlang_request_func_t funcs
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define DEBUG_ENABLED5
True if global debug level 1-5 messages are enabled.
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
unlang_op_t unlang_ops[UNLANG_TYPE_MAX]
Different operations the interpreter can execute.
fr_time_t fr_event_timer_when(fr_event_timer_t const *ev)
Internal timestamp representing when the timer should fire.
Stores all information relating to an event list.
static char * stack[MAX_STACK]
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
static uint8_t depth(fr_minmax_heap_index_t i)
unlang_mod_action_t actions[RLM_MODULE_NUMCODES]
Declarations for the unlang module interface.
int fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
Declarations for the unlang "parallel" keyword.
#define RDEBUG_ENABLED2()
fr_table_num_sorted_t const rcode_table[]
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_REJECT
Immediately reject the request.
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
#define REQUEST_VERIFY(_x)
@ REQUEST_TYPE_EXTERNAL
A request received on the wire.
@ REQUEST_TYPE_INTERNAL
A request generated internally.
@ REQUEST_TYPE_DETACHED
A request that was generated internally, but is now detached (not associated with a parent request....
#define request_is_detachable(_x)
@ REQUEST_DONE
Request has completed.
@ REQUEST_STOP_PROCESSING
Request has been signalled to stop.
void * request_data_get(request_t *request, void const *unique_ptr, int unique_int)
Get opaque data from a request.
#define request_data_add(_request, _unique_ptr, _unique_int, _opaque, _free_on_replace, _free_on_parent, _persist)
Add opaque data to a request_t.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
#define fr_time()
Allow us to arbitrarily manipulate time.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in an arbitrarily ordered array of name to num mappings.
#define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_ispos(_a)
#define fr_time_delta_eq(_a, _b)
#define fr_time_add(_a, _b)
Add a time/time delta together.
static fr_time_t fr_time_from_sec(time_t when)
Convert a time_t (wallclock time) to a fr_time_t (internal time)
#define fr_time_sub(_a, _b)
Subtract one time from another.
static fr_event_list_t * el
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.
bool required
Argument must be present, and non-empty.
#define XLAT_ARGS(_list,...)
Populate local variables with value boxes from the input list.
#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 consumend by an xlat function.
#define UNWIND_FLAG_RETURN_POINT
'return' stops here.
#define unlang_frame_perf_resume(_x)
static void frame_pop(request_t *request, unlang_stack_t *stack)
Pop a stack frame, removing any associated dynamically allocated state.
unlang_t * next
Next node (executed on UNLANG_ACTION_EXECUTE_NEXT et al).
static void frame_next(unlang_stack_t *stack, unlang_stack_frame_t *frame)
Advance to the next sibling instruction.
static bool is_repeatable(unlang_stack_frame_t const *frame)
#define UNWIND_FLAG_TOP_FRAME
are we the top frame of the stack?
#define UNLANG_NEXT_SIBLING
static void repeatable_clear(unlang_stack_frame_t *frame)
unlang_signal_t signal
function to call when signalling this stack frame
char const * debug_name
Printed in log messages when the node is executed.
void * state
Stack frame specialisations.
unlang_mod_actions_t actions
Priorities, etc. for the various return codes.
static unlang_t * unlang_group_to_generic(unlang_group_t const *p)
static void frame_state_init(unlang_stack_t *stack, unlang_stack_frame_t *frame)
static unlang_group_t * unlang_generic_to_group(unlang_t const *p)
bool rcode_set
Set request->rcode to the result of this operation.
int priority
Result priority.
unlang_dump_t dump
Dump additional information about the frame state.
static unlang_action_t unwind_all(unlang_stack_t *stack)
#define UNWIND_FLAG_NO_CLEAR
Keep unwinding, don't clear the unwind flag.
#define UNWIND_FLAG_BREAK_POINT
'break' stops here.
unlang_process_t interpret
Function to interpret the keyword.
#define UNWIND_FLAG_NONE
No flags.
uint8_t uflags
Unwind markers.
int depth
of this retry structure
static void frame_cleanup(unlang_stack_frame_t *frame)
Cleanup any lingering frame state.
CONF_ITEM * ci
used to generate this item
static bool is_top_frame(unlang_stack_frame_t const *frame)
fr_event_timer_t const * ev
static void stack_unwind_break_clear(unlang_stack_t *stack)
char const * name
Unknown...
static bool is_break_point(unlang_stack_frame_t const *frame)
@ UNLANG_TYPE_GROUP
Grouping section.
unlang_t const * instruction
The unlang node we're evaluating.
bool debug_braces
Whether the operation needs to print braces in debug mode.
static bool is_yielded(unlang_stack_frame_t const *frame)
static void top_frame_set(unlang_stack_frame_t *frame)
unlang_variable_t * variables
rarely used, so we don't usually need it
rlm_rcode_t result
The result from executing the instruction.
char const * name
Name of the operation.
unlang_frame_action_t
Allows the frame evaluator to signal the interpreter.
@ UNLANG_FRAME_ACTION_POP
Pop the current frame, and check the next one further up in the stack for what to do next.
@ UNLANG_FRAME_ACTION_YIELD
Temporarily return control back to the caller on the C stack.
@ UNLANG_FRAME_ACTION_NEXT
Process the next instruction at this level.
@ UNLANG_FRAME_ACTION_RETRY
retry the current frame
static void yielded_set(unlang_stack_frame_t *frame)
static void yielded_clear(unlang_stack_frame_t *frame)
#define unlang_frame_perf_yield(_x)
#define unlang_frame_perf_cleanup(_x)
unlang_t const * next
The next unlang node we will evaluate.
static void stack_unwind_return_clear(unlang_stack_t *stack)
fr_dict_t * dict
our dictionary
static bool is_return_point(unlang_stack_frame_t const *frame)
unlang_type_t type
The specialisation of this node.
unlang_t * children
Children beneath this group.
static void stack_unwind_top_frame_clear(unlang_stack_t *stack)
Generic representation of a grouping.
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
An unlang stack associated with a request.
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
uint32_t mrc
Maximum retransmission count.
@ FR_RETRY_MRC
reached maximum retransmission count
@ FR_RETRY_MRD
reached maximum retransmission duration
fr_time_delta_t mrd
Maximum retransmission duration.
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.
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
static size_t char ** out
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
xlat_t * xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function.