The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
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: a55766738fa7fab42c493b865de7b1ad2f4e9b0e $
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/** Check whether a request is already scheduled to run
92 *
93 * This is called to determine whether a yielded request has already been
94 * marked runnable / added to the runnable queue.
95 */
96typedef bool (*unlang_request_scheduled_t)(request_t const *request, void *uctx);
97
98/** Re-prioritise the request in the runnable queue
99 *
100 * The new priority will be available in request->async->priority.
101 */
102typedef void (*unlang_request_prioritise_t)(request_t *request, void *uctx);
103
104/** External functions provided by the owner of the interpret
105 *
106 * These functions allow the event loop to signal the caller when a given
107 * request is ready to run for the first time, and when it should be resumed
108 * and passed back to #unlang_interpret to continue execution.
109 *
110 * This is the cleanest way to separate the interpret and the code that's
111 * managing requests.
112 *
113 * Test harnesses (for example) need to perform far less initialisation and
114 * request management than FreeRADIUS worker threads.
115 */
116typedef struct {
117 /*
118 * There's no init_external as this is done
119 * before the external request is handed off
120 * to the interpreter.
121 */
122 unlang_request_init_t init_internal; //!< Function called to initialise an internal request.
123
124 unlang_request_done_t done_external; //!< Function called when a external request completes.
125 unlang_request_done_t done_internal; //!< Function called when an internal request completes.
126 unlang_request_done_t done_detached; //!< Function called when a detached request completes.
127
128 unlang_request_init_t detach; //!< Function called when a request is detached.
129 unlang_request_yield_t yield; //!< Function called when a request yields.
130 unlang_request_resume_t resume; //!< Function called when a request is resumed.
131 unlang_request_runnable_t mark_runnable; //!< Function called when a request needs to be
132 ///< added back to the runnable queue.
133 unlang_request_scheduled_t scheduled; //!< Function to check if a request is already
134 ///< scheduled.
135 unlang_request_prioritise_t prioritise; //!< Function to re-prioritise a request in the
136 ///< runnable queue.
138
139typedef struct {
140 rlm_rcode_t rcode; //!< The current rcode, from executing the instruction
141 ///< or merging the result from a frame.
142 unlang_mod_action_t priority; //!< The priority or action for that rcode.
144
145#define UNLANG_RESULT_NOT_SET ((unlang_result_t) { .rcode = RLM_MODULE_NOT_SET, .priority = MOD_ACTION_NOT_SET })
146#define UNLANG_RESULT_RCODE(_x) ((unlang_result_t) { .rcode = (_x), .priority = MOD_ACTION_NOT_SET })
147
148/** Configuration structure to make it easier to pass configuration options to initialise the frame with
149 */
150typedef struct {
151 bool top_frame; //!< Is this the top frame?
152 unlang_result_t default_result; //!< The default result for the frame.
153 ///< This needs to be specified separately
154 ///< from p_result, because we may be passing
155 ///< in NULL for p_result.
157
158#define FRAME_CONF(_default_rcode, _top_frame) \
159 &(unlang_frame_conf_t){ \
160 .top_frame = (_top_frame), \
161 .default_result = UNLANG_RESULT_RCODE(_default_rcode), \
162 }
163
164/*
165 * Forward definition of the instruction for type safety.
166 */
167typedef struct unlang_s unlang_t;
168
171 CC_HINT(warn_unused_result);
172
174 void *instruction, unlang_frame_conf_t const *conf)
175 CC_HINT(warn_unused_result);
176
178 fr_event_list_t *el, unlang_request_func_t *func, void *uctx);
179
181
183
185
187
189
191
192int unlang_interpret_set_timeout(request_t *request, fr_time_delta_t timeout) CC_HINT(nonnull);
193
194rlm_rcode_t unlang_interpret(request_t *request, bool running) CC_HINT(hot);
195
197
198void *unlang_interpret_stack_alloc(TALLOC_CTX *ctx);
199
200bool unlang_request_is_scheduled(request_t const *request);
201
202bool unlang_request_is_cancelled(request_t const *request);
203
204bool unlang_request_is_done(request_t const *request);
205
207
209
211
213
215
216void unlang_interpret_signal(request_t *request, fr_signal_t action);
217
219
221
223
225
226TALLOC_CTX *unlang_interpret_frame_talloc_ctx(request_t *request);
227
229
230int unlang_interpret_force_result(unlang_t const *instruction, unlang_result_t *p_result,
231 fr_timer_list_t *tl, fr_time_delta_t expire) CC_HINT(nonnull(1));
232
233int unlang_interpret_init_global(TALLOC_CTX *ctx);
234#ifdef __cplusplus
235}
236#endif
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:106
void unlang_interpret_request_prioritise(request_t *request, uint32_t priority)
Definition interpret.c:1669
rlm_rcode_t unlang_interpret(request_t *request, bool running)
Run the interpreter for a current request.
Definition interpret.c:1296
unlang_result_t default_result
The default result for the frame.
Definition interpret.h:152
bool unlang_request_is_done(request_t const *request)
Return whether a request has been marked done.
Definition interpret.c:1972
unlang_request_prioritise_t prioritise
Function to re-prioritise a request in the runnable queue.
Definition interpret.h:135
unlang_mod_action_t priority
The priority or action for that rcode.
Definition interpret.h:142
unlang_result_t * unlang_interpret_result(request_t *request)
Get the last instruction result OR the last frame that was popped.
Definition interpret.c:1947
void unlang_interpet_frame_discard(request_t *request)
Discard the bottom most frame on the request's stack.
Definition interpret.c:2396
int unlang_interpret_set_timeout(request_t *request, fr_time_delta_t timeout)
Set a timeout for a request.
Definition interpret.c:1890
void unlang_interpret_request_done(request_t *request)
Indicate to the caller of the interpreter that this request is complete.
Definition interpret.c:1624
void unlang_interpret_set(request_t *request, unlang_interpret_t *intp)
Set a specific interpreter for a request.
Definition interpret.c:2404
unlang_interpret_t * unlang_interpret_get(request_t *request)
Get the interpreter set for a request.
Definition interpret.c:2413
unlang_request_done_t done_internal
Function called when an internal request completes.
Definition interpret.h:125
int unlang_interpret_stack_depth(request_t *request)
Return the depth of the request's stack.
Definition interpret.c:1915
void unlang_interpret_mark_runnable(request_t *request)
Mark a request as resumable.
Definition interpret.c:2002
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:2047
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:2363
bool unlang_request_is_scheduled(request_t const *request)
Return whether a request is currently scheduled.
Definition interpret.c:1955
int unlang_interpret_init_global(TALLOC_CTX *ctx)
Definition interpret.c:2453
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
Definition interpret.c:2446
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:349
unlang_request_resume_t resume
Function called when a request is resumed.
Definition interpret.h:130
void * unlang_interpret_stack_alloc(TALLOC_CTX *ctx)
Allocate a new unlang stack.
Definition interpret.c:1587
bool top_frame
Is this the top frame?
Definition interpret.h:151
bool(* unlang_request_scheduled_t)(request_t const *request, void *uctx)
Check whether a request is already scheduled to run.
Definition interpret.h:96
unlang_request_done_t done_external
Function called when a external request completes.
Definition interpret.h:124
unlang_t const * unlang_interpret_instruction(request_t *request)
Get the current instruction.
Definition interpret.c:326
void unlang_interpret_set_thread_default(unlang_interpret_t *intp)
Set the default interpreter for this thread.
Definition interpret.c:2435
unlang_request_init_t detach
Function called when a request is detached.
Definition interpret.h:128
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:1937
unlang_request_runnable_t mark_runnable
Function called when a request needs to be added back to the runnable queue.
Definition interpret.h:131
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
Definition interpret.h:140
bool unlang_request_is_cancelled(request_t const *request)
Return whether a request has been cancelled.
Definition interpret.c:1965
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:1559
unlang_request_yield_t yield
Function called when a request yields.
Definition interpret.h:129
void unlang_interpret_signal(request_t *request, fr_signal_t action)
Send a signal (usually stop) to a request.
Definition interpret.c:1783
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:102
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:1529
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:126
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:1984
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:133
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:1687
rlm_rcode_t unlang_interpret_rcode(request_t *request)
Get the last instruction result OR the last frame that was popped.
Definition interpret.c:1927
unlang_request_init_t init_internal
Function called to initialise an internal request.
Definition interpret.h:122
fr_event_list_t * unlang_interpret_event_list(request_t *request)
Get the event list for the current interpreter.
Definition interpret.c:2423
Configuration structure to make it easier to pass configuration options to initialise the frame with.
Definition interpret.h:150
External functions provided by the owner of the interpret.
Definition interpret.h:116
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))