The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
interpret.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18/**
19 * $Id: 7aba85df02a62f03ee54f418fcf554f536228794 $
20 *
21 * @file unlang/interpret.h
22 * @brief Declarations for the unlang interpreter.
23 *
24 * @copyright 2019 The FreeRADIUS server project
25 */
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include <freeradius-devel/server/cf_util.h>
32#include <freeradius-devel/server/request.h>
33#include <freeradius-devel/unlang/mod_action.h>
34#include <freeradius-devel/unlang/action.h>
35
36#define UNLANG_TOP_FRAME (true)
37#define UNLANG_SUB_FRAME (false)
38
39#define UNLANG_FRAME_SIZE (152) //!< size of one stack frame, see radsizes
40#define UNLANG_STACK_MAX (64) //!< The maximum depth of the stack.
41#define UNLANG_STACK_SIZE (9744) //!< size of the unlang stack
42#define UNLANG_FRAME_STATE (128) //!< guess at per-frame state
43#define UNLANG_FRAME_POOL_SIZE (UNLANG_STACK_MAX * UNLANG_FRAME_STATE) //!< total size of all frame states
44#define UNLANG_STACK_POOL_SIZE (UNLANG_STACK_SIZE + UNLANG_FRAME_POOL_SIZE) //!< total size of all stack objects
45#define UNLANG_STACK_NUM_OBJECTS (1 + UNLANG_STACK_MAX) //!< number of stack-allocated objects, i.e. number of talloc headers
46
47#define UNLANG_REQUEST_RUNNING (true)
48#define UNLANG_REQUEST_RESUME (false)
49
50/** Interpreter handle
51 *
52 */
54
55/** Signal the owner of the interpreter that this request should be initialised and executed
56 *
57 * This is called once per request, when it's about to start executing.
58 */
59typedef void (*unlang_request_init_t)(request_t *request, void *uctx);
60
61/** Signal the owner of the interpreter that this request completed processing
62 *
63 * This is called once per request, when the interpret is about to stop processing it.
64 */
65typedef void (*unlang_request_done_t)(request_t *request, rlm_rcode_t rcode, void *uctx);
66
67/** Stop a request from running
68 *
69 * This is called whenever a request has been signalled to stop
70 */
71typedef void (*unlang_request_stop_t)(request_t *request, void *uctx);
72
73/** Signal the owner of the interpreter that a request has yielded
74 *
75 * This is called whenever a request has given control back to the interpreter.
76 */
77typedef void (*unlang_request_yield_t)(request_t *request, void *uctx);
78
79/** Signal the owner of the interpreter that a request is ready to be resumed
80 *
81 * This is called any time a yielded request has resumed.
82 */
83typedef void (*unlang_request_resume_t)(request_t *request, void *uctx);
84
85/** Signal the owner of the interpreter that a request is now runnable
86 *
87 * This is called any time a yielded request has been marked runnable.
88 */
89typedef void (*unlang_request_runnable_t)(request_t *request, void *uctx);
90
91/** Signal the owner of the interpreter that a request is now runnable
92 *
93 * This is called any time a yielded request has been marked runnable.
94 */
95typedef bool (*unlang_request_scheduled_t)(request_t const *request, void *uctx);
96
97/** Re-prioritise the request in the runnable queue
98 *
99 * The new priority will be available in request->async->priority.
100 */
101typedef void (*unlang_request_prioritise_t)(request_t *request, void *uctx);
102
103/** External functions provided by the owner of the interpret
104 *
105 * These functions allow the event loop to signal the caller when a given
106 * request is ready to run for the first time, and when it should be resumed
107 * and passed back to #unlang_interpret to continue execution.
108 *
109 * This is the cleanest way to separate the interpret and the code that's
110 * managing requests.
111 *
112 * Test harnesses (for example) need to perform far less initialisation and
113 * request management than FreeRADIUS worker threads.
114 */
115typedef struct {
116 /*
117 * There's no init_external as this is done
118 * before the external request is handed off
119 * to the interpreter.
120 */
121 unlang_request_init_t init_internal; //!< Function called to initialise an internal request.
122
123 unlang_request_done_t done_external; //!< Function called when a external request completes.
124 unlang_request_done_t done_internal; //!< Function called when an internal request completes.
125 unlang_request_done_t done_detached; //!< Function called when a detached request completes.
126
127 unlang_request_init_t detach; //!< Function called when a request is detached.
128 unlang_request_yield_t yield; //!< Function called when a request yields.
129 unlang_request_resume_t resume; //!< Function called when a request is resumed.
130 unlang_request_runnable_t mark_runnable; //!< Function called when a request needs to be
131 ///< added back to the runnable queue.
132 unlang_request_scheduled_t scheduled; //!< Function to check if a request is already
133 ///< scheduled.
134 unlang_request_prioritise_t prioritise; //!< Function to re-prioritise a request in the
135 ///< runnable queue.
137
138typedef struct {
139 rlm_rcode_t rcode; //!< The current rcode, from executing the instruction
140 ///< or merging the result from a frame.
141 unlang_mod_action_t priority; //!< The priority or action for that rcode.
143
144#define UNLANG_RESULT_NOT_SET ((unlang_result_t) { .rcode = RLM_MODULE_NOT_SET, .priority = MOD_ACTION_NOT_SET })
145#define UNLANG_RESULT_RCODE(_x) ((unlang_result_t) { .rcode = (_x), .priority = MOD_ACTION_NOT_SET })
146
147/** Configuration structure to make it easier to pass configuration options to initialise the frame with
148 */
149typedef struct {
150 bool top_frame; //!< Is this the top frame?
151 unlang_result_t default_result; //!< The default result for the frame.
152 ///< This needs to be specified separately
153 ///< from p_result, because we may be passing
154 ///< in NULL for p_result.
156
157#define FRAME_CONF(_default_rcode, _top_frame) \
158 &(unlang_frame_conf_t){ \
159 .top_frame = (_top_frame), \
160 .default_result = UNLANG_RESULT_RCODE(_default_rcode), \
161 }
162
163/*
164 * Forward definition of the instruction for type safety.
165 */
166typedef struct unlang_s unlang_t;
167
170 CC_HINT(warn_unused_result);
171
173 void *instruction, unlang_frame_conf_t const *conf)
174 CC_HINT(warn_unused_result);
175
177 fr_event_list_t *el, unlang_request_func_t *func, void *uctx);
178
180
182
184
186
188
190
191int unlang_interpret_set_timeout(request_t *request, fr_time_delta_t timeout) CC_HINT(nonnull);
192
193rlm_rcode_t unlang_interpret(request_t *request, bool running) CC_HINT(hot);
194
196
197void *unlang_interpret_stack_alloc(TALLOC_CTX *ctx);
198
199bool unlang_request_is_scheduled(request_t const *request);
200
201bool unlang_request_is_cancelled(request_t const *request);
202
203bool unlang_request_is_done(request_t const *request);
204
206
208
210
212
214
215void unlang_interpret_signal(request_t *request, fr_signal_t action);
216
218
220
222
224
225TALLOC_CTX *unlang_interpret_frame_talloc_ctx(request_t *request);
226
228
229int unlang_interpret_force_result(unlang_t const *instruction, unlang_result_t *p_result,
230 fr_timer_list_t *tl, fr_time_delta_t expire) CC_HINT(nonnull(1));
231
232int unlang_interpret_init_global(TALLOC_CTX *ctx);
233#ifdef __cplusplus
234}
235#endif
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
void unlang_interpret_request_prioritise(request_t *request, uint32_t priority)
Definition interpret.c:1657
rlm_rcode_t unlang_interpret(request_t *request, bool running)
Run the interpreter for a current request.
Definition interpret.c:1291
unlang_result_t default_result
The default result for the frame.
Definition interpret.h:151
bool unlang_request_is_done(request_t const *request)
Return whether a request has been marked done.
Definition interpret.c:1960
unlang_request_prioritise_t prioritise
Function to re-prioritise a request in the runnable queue.
Definition interpret.h:134
unlang_mod_action_t priority
The priority or action for that rcode.
Definition interpret.h:141
unlang_result_t * unlang_interpret_result(request_t *request)
Get the last instruction result OR the last frame that was popped.
Definition interpret.c:1935
void unlang_interpet_frame_discard(request_t *request)
Discard the bottom most frame on the request's stack.
Definition interpret.c:2384
int unlang_interpret_set_timeout(request_t *request, fr_time_delta_t timeout)
Set a timeout for a request.
Definition interpret.c:1878
void unlang_interpret_request_done(request_t *request)
Indicate to the caller of the interpreter that this request is complete.
Definition interpret.c:1612
void unlang_interpret_set(request_t *request, unlang_interpret_t *intp)
Set a specific interpreter for a request.
Definition interpret.c:2392
unlang_interpret_t * unlang_interpret_get(request_t *request)
Get the interpreter set for a request.
Definition interpret.c:2401
unlang_request_done_t done_internal
Function called when an internal request completes.
Definition interpret.h:124
int unlang_interpret_stack_depth(request_t *request)
Return the depth of the request's stack.
Definition interpret.c:1903
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition interpret.c:1990
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:2035
unlang_interpret_t * unlang_interpret_init(TALLOC_CTX *ctx, fr_event_list_t *el, unlang_request_func_t *func, void *uctx)
Initialize a unlang compiler / interpret.
Definition interpret.c:2351
bool unlang_request_is_scheduled(request_t const *request)
Return whether a request is currently scheduled.
Definition interpret.c:1943
int unlang_interpret_init_global(TALLOC_CTX *ctx)
Definition interpret.c:2441
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
Definition interpret.c:2434
int unlang_interpret_force_result(unlang_t const *instruction, unlang_result_t *p_result, fr_timer_list_t *tl, fr_time_delta_t expire))
Set (or clear) a forced result.
Definition interpret.c:344
unlang_request_resume_t resume
Function called when a request is resumed.
Definition interpret.h:129
void * unlang_interpret_stack_alloc(TALLOC_CTX *ctx)
Allocate a new unlang stack.
Definition interpret.c:1575
bool top_frame
Is this the top frame?
Definition interpret.h:150
bool(* unlang_request_scheduled_t)(request_t const *request, void *uctx)
Signal the owner of the interpreter that a request is now runnable.
Definition interpret.h:95
unlang_request_done_t done_external
Function called when a external request completes.
Definition interpret.h:123
unlang_t const * unlang_interpret_instruction(request_t *request)
Get the current instruction.
Definition interpret.c:321
void unlang_interpret_set_thread_default(unlang_interpret_t *intp)
Set the default interpreter for this thread.
Definition interpret.c:2423
unlang_request_init_t detach
Function called when a request is detached.
Definition interpret.h:127
unlang_mod_action_t unlang_interpret_priority(request_t *request)
Get the last instruction priority OR the last frame that was popped.
Definition interpret.c:1925
unlang_request_runnable_t mark_runnable
Function called when a request needs to be added back to the runnable queue.
Definition interpret.h:130
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
Definition interpret.h:139
bool unlang_request_is_cancelled(request_t const *request)
Return whether a request has been cancelled.
Definition interpret.c:1953
int unlang_interpret_push_instruction(unlang_result_t *p_result, request_t *request, void *instruction, unlang_frame_conf_t const *conf)
Push an instruction onto the request stack for later interpretation.
Definition interpret.c:1547
unlang_request_yield_t yield
Function called when a request yields.
Definition interpret.h:128
void unlang_interpret_signal(request_t *request, fr_signal_t action)
Send a signal (usually stop) to a request.
Definition interpret.c:1771
void(* unlang_request_done_t)(request_t *request, rlm_rcode_t rcode, void *uctx)
Signal the owner of the interpreter that this request completed processing.
Definition interpret.h:65
void(* unlang_request_prioritise_t)(request_t *request, void *uctx)
Re-prioritise the request in the runnable queue.
Definition interpret.h:101
int unlang_interpret_push_section(unlang_result_t *p_result, request_t *request, CONF_SECTION *cs, unlang_frame_conf_t const *conf)
Push a configuration section onto the request stack for later interpretation.
Definition interpret.c:1524
void(* unlang_request_resume_t)(request_t *request, void *uctx)
Signal the owner of the interpreter that a request is ready to be resumed.
Definition interpret.h:83
unlang_request_done_t done_detached
Function called when a detached request completes.
Definition interpret.h:125
void(* unlang_request_yield_t)(request_t *request, void *uctx)
Signal the owner of the interpreter that a request has yielded.
Definition interpret.h:77
bool unlang_interpret_is_resumable(request_t *request)
Check if a request as resumable.
Definition interpret.c:1972
rlm_rcode_t unlang_interpret_synchronous(fr_event_list_t *el, request_t *request)
Execute an unlang section synchronously.
void(* unlang_request_init_t)(request_t *request, void *uctx)
Signal the owner of the interpreter that this request should be initialised and executed.
Definition interpret.h:59
unlang_request_scheduled_t scheduled
Function to check if a request is already scheduled.
Definition interpret.h:132
void(* unlang_request_stop_t)(request_t *request, void *uctx)
Stop a request from running.
Definition interpret.h:71
void(* unlang_request_runnable_t)(request_t *request, void *uctx)
Signal the owner of the interpreter that a request is now runnable.
Definition interpret.h:89
void unlang_interpret_request_cancel_retry(request_t *request)
Cancel any pending retry.
Definition interpret.c:1675
rlm_rcode_t unlang_interpret_rcode(request_t *request)
Get the last instruction result OR the last frame that was popped.
Definition interpret.c:1915
unlang_request_init_t init_internal
Function called to initialise an internal request.
Definition interpret.h:121
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
Definition interpret.c:2411
Configuration structure to make it easier to pass configuration options to initialise the frame with.
Definition interpret.h:149
External functions provided by the owner of the interpret.
Definition interpret.h:115
Stores all information relating to an event list.
Definition event.c:377
unsigned int uint32_t
unsigned char bool
unlang_mod_action_t
Definition mod_action.h:37
static rs_t * conf
Definition radsniff.c:52
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
fr_signal_t
Signals that can be generated/processed by request signal handlers.
Definition signal.h:38
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
An event timer list.
Definition timer.c:49
static fr_event_list_t * el
A node in a graph of unlang_op_t (s) that we execute.
int nonnull(2, 5))