/src/freeradius-server/src/freeradius-devel/server/request.h
Line | Count | Source |
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 of the License, or |
6 | | * (at your option) 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 |
15 | | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
16 | | */ |
17 | | |
18 | | /** |
19 | | * $Id: 80f25165b5f4db9a17ddf14344aa2716cd1bbb31 $ |
20 | | * |
21 | | * @file lib/server/request.h |
22 | | * @brief The main request structure, and allocation functions. |
23 | | * |
24 | | * @copyright 1999-2018 The FreeRADIUS server project |
25 | | */ |
26 | | RCSIDH(request_h, "$Id: 80f25165b5f4db9a17ddf14344aa2716cd1bbb31 $") |
27 | | |
28 | | /* |
29 | | * Forward declarations to avoid dependency loops |
30 | | */ |
31 | | #ifdef __cplusplus |
32 | | extern "C" { |
33 | | #endif |
34 | | |
35 | | typedef struct fr_async_s fr_async_t; |
36 | | typedef struct request_s request_t; |
37 | | |
38 | | typedef struct fr_client_s fr_client_t; |
39 | | |
40 | | #ifdef __cplusplus |
41 | | } |
42 | | #endif |
43 | | |
44 | | #include <freeradius-devel/server/log.h> |
45 | | #include <freeradius-devel/server/rcode.h> |
46 | | #include <freeradius-devel/server/signal.h> |
47 | | #include <freeradius-devel/util/event.h> |
48 | | #include <freeradius-devel/util/heap.h> |
49 | | #include <freeradius-devel/util/packet.h> |
50 | | #include <freeradius-devel/util/dlist.h> |
51 | | |
52 | | #ifdef __cplusplus |
53 | | extern "C" { |
54 | | #endif |
55 | | |
56 | | #ifndef NDEBUG |
57 | 0 | # define REQUEST_MAGIC (0xdeadbeef) |
58 | | #endif |
59 | | |
60 | | /* |
61 | | * Stack pool + |
62 | | * Stack Frames + |
63 | | * packets + |
64 | | * extra |
65 | | */ |
66 | 0 | #define REQUEST_POOL_HEADERS ( \ |
67 | 0 | 1 + \ |
68 | 0 | UNLANG_STACK_MAX + \ |
69 | 0 | 2 + \ |
70 | 0 | 10 \ |
71 | 0 | ) |
72 | | |
73 | | /* |
74 | | * Stack memory + |
75 | | * pair lists and root + |
76 | | * packets + |
77 | | * extra |
78 | | */ |
79 | 0 | #define REQUEST_POOL_SIZE ( \ |
80 | 0 | (UNLANG_FRAME_PRE_ALLOC * UNLANG_STACK_MAX) + \ |
81 | 0 | (sizeof(fr_pair_t) * 5) + \ |
82 | 0 | (sizeof(fr_packet_t) * 2) + \ |
83 | 0 | 128 \ |
84 | 0 | ) |
85 | | |
86 | | typedef enum { |
87 | | REQUEST_ACTIVE = 1, //!< Request is active (running or runnable) |
88 | | REQUEST_STOP_PROCESSING, //!< Request has been signalled to stop |
89 | | REQUEST_DONE, //!< Request has completed |
90 | | } request_master_state_t; |
91 | | #define REQUEST_MASTER_NUM_STATES (REQUEST_COUNTED + 1) |
92 | | |
93 | | typedef enum request_state_t { |
94 | | REQUEST_INIT = 0, |
95 | | REQUEST_RECV, |
96 | | REQUEST_PROCESS, |
97 | | REQUEST_SEND, |
98 | | REQUEST_OTHER_1, |
99 | | REQUEST_OTHER_2, |
100 | | REQUEST_OTHER_3, |
101 | | REQUEST_OTHER_4, |
102 | | } request_state_t; |
103 | | |
104 | | extern HIDDEN fr_dict_attr_t const *request_attr_root; |
105 | | extern fr_dict_attr_t const *request_attr_request; |
106 | | extern fr_dict_attr_t const *request_attr_reply; |
107 | | extern fr_dict_attr_t const *request_attr_control; |
108 | | extern fr_dict_attr_t const *request_attr_state; |
109 | | extern fr_dict_attr_t const *request_attr_local; |
110 | | |
111 | | /** Convenience macro for accessing the request list |
112 | | * |
113 | | * This should be used in the form `&request->request_pairs` |
114 | | * to get a pointer to the head of the request list. |
115 | | */ |
116 | 0 | #define request_pairs pair_list.request->children |
117 | | |
118 | | /** Talloc ctx for allocating request pairs under |
119 | | */ |
120 | 0 | #define request_ctx pair_list.request |
121 | | |
122 | | /** Convenience macro for accessing the reply list |
123 | | * |
124 | | * This should be used in the form `&request->reply_pairs` |
125 | | * to get a pointer to the head of the request list. |
126 | | */ |
127 | 0 | #define reply_pairs pair_list.reply->children |
128 | | |
129 | | /** Talloc ctx for allocating reply pairs under |
130 | | */ |
131 | 0 | #define reply_ctx pair_list.reply |
132 | | |
133 | | /** Convenience macro for accessing the control list |
134 | | * |
135 | | * This should be used in the form `&request->control_pairs` |
136 | | * to get a pointer to the head of the request list. |
137 | | */ |
138 | 0 | #define control_pairs pair_list.control->children |
139 | | |
140 | | /** Talloc ctx for allocating control pairs under |
141 | | */ |
142 | 0 | #define control_ctx pair_list.control |
143 | | |
144 | | /** Convenience macro for accessing the state list |
145 | | * |
146 | | * This should be used in the form `&request->session_state_pairs` |
147 | | * to get a pointer to the head of the request list. |
148 | | */ |
149 | 0 | #define session_state_pairs pair_list.state->children |
150 | | |
151 | | /** Talloc ctx for allocating reply pairs under |
152 | | */ |
153 | 0 | #define session_state_ctx pair_list.state |
154 | | |
155 | | /** Convenience macro for accessing the state list |
156 | | * |
157 | | * This should be used in the form `&request->local_pairs` |
158 | | * to get a pointer to the head of the local list. |
159 | | */ |
160 | 0 | #define local_pairs pair_list.local->children |
161 | | |
162 | | /** Talloc ctx for allocating local variables |
163 | | */ |
164 | 0 | #define local_ctx pair_list.local |
165 | | |
166 | | /** Pair lists accessible from the request |
167 | | * |
168 | | */ |
169 | | typedef struct { |
170 | | fr_pair_t *request; //!< Pair containing the request list. |
171 | | fr_pair_t *reply; //!< Pair containing the reply list. |
172 | | fr_pair_t *control; //!< Pair containing the control list. |
173 | | fr_pair_t *state; //!< Pair containing the state list. |
174 | | fr_pair_t *local; //!< Pair containing local variables |
175 | | } request_pair_lists_t; |
176 | | |
177 | | typedef enum { |
178 | | REQUEST_TYPE_EXTERNAL = 0, //!< A request received on the wire. |
179 | | REQUEST_TYPE_INTERNAL, //!< A request generated internally. |
180 | | REQUEST_TYPE_DETACHED //!< A request that was generated internally, but is now detached |
181 | | ///< (not associated with a parent request.) |
182 | | } request_type_t; |
183 | | |
184 | | #define request_is_external(_x) ((_x)->type == REQUEST_TYPE_EXTERNAL) |
185 | | #define request_is_internal(_x) ((_x)->type == REQUEST_TYPE_INTERNAL) |
186 | 0 | #define request_is_detached(_x) ((_x)->type == REQUEST_TYPE_DETACHED) |
187 | 0 | #define request_is_detachable(_x) ((_x)->flags.detachable) |
188 | | #define request_is_dynamic_client(_x) ((_x)->flags.dynamic_client) |
189 | | #define request_set_dynamic_client(_x) ((_x)->flags.dynamic_client = true) |
190 | | |
191 | | struct request_s { |
192 | | #ifndef NDEBUG |
193 | | uint32_t magic; //!< Magic number used to detect memory corruption, |
194 | | //!< or request structs that have not been properly initialised. |
195 | | |
196 | | uint64_t ins_count; //!< count of instructions we've ran |
197 | | uint64_t ins_max; //!< max instruction to bail out at |
198 | | |
199 | | #endif |
200 | | void *stack; //!< unlang interpreter stack. |
201 | | |
202 | | request_type_t type; //!< What type of request this is. |
203 | | |
204 | | request_t *parent; //!< Request that generated this request. |
205 | | |
206 | | uint64_t number; //!< Monotonically increasing request number. Reset on server restart. |
207 | | uint64_t child_number; //!< Monotonically increasing number for children of this request |
208 | | char const *name; //!< for debug printing, as (%d) is no longer sufficient |
209 | | |
210 | | uint64_t seq_start; //!< State sequence ID. Stable identifier for a sequence of requests |
211 | | //!< and responses. |
212 | | fr_dict_t const *proto_dict; //!< Dictionary of the protocol that this request belongs to. |
213 | | fr_dict_t const *local_dict; //!< dictionary for local variables |
214 | | |
215 | | fr_pair_t *pair_root; //!< Root attribute which contains the |
216 | | ///< other list attributes as children. |
217 | | |
218 | | /** Pair lists associated with the request |
219 | | * |
220 | | * @warning DO NOT allocate pairs directly beneath the root |
221 | | * or in the ctx of the request. |
222 | | * They MUST be allocated beneath their appropriate |
223 | | * list attribute. |
224 | | */ |
225 | | request_pair_lists_t pair_list; //!< Structure containing all pair lists. |
226 | | |
227 | | fr_dlist_head_t data; //!< Request data. |
228 | | |
229 | | /** Capabilities flags for this request |
230 | | * |
231 | | */ |
232 | | struct { |
233 | | unsigned int detachable : 1; //!< This request may be detached from its parent.. |
234 | | unsigned int dynamic_client : 1; //!< this is a dynamic client request |
235 | | } flags; |
236 | | |
237 | | /** Logging information |
238 | | * |
239 | | */ |
240 | | struct { |
241 | | log_dst_t *dst; //!< First in a list of log destinations. |
242 | | |
243 | | fr_log_lvl_t lvl; //!< Log messages with lvl >= to this should be logged. |
244 | | |
245 | | rindent_t indent; //!< Indentation for log messages. |
246 | | } log; |
247 | | |
248 | | char const *component; //!< Section the request is in. |
249 | | char const *module; //!< Module the request is currently being processed by. |
250 | | |
251 | | fr_packet_t *packet; //!< Incoming request. |
252 | | fr_packet_t *reply; //!< Outgoing response. |
253 | | |
254 | | fr_client_t *client; //!< The client that originally sent us the request. |
255 | | |
256 | | request_master_state_t master_state; //!< Set by the master thread to signal the child that's currently |
257 | | //!< working with the request, to do something. |
258 | | bool counted; //!< Set if the request has been counted in the stats. |
259 | | |
260 | | rlm_rcode_t rcode; //!< Last rcode returned by a module |
261 | | |
262 | | fr_rb_node_t dedup_node; //!< entry in the deduplication tree. |
263 | | |
264 | | fr_timer_t *timeout; //!< Timer event for this request. This tracks when we need to |
265 | | ///< forcefully terminate a request. |
266 | | |
267 | | uint32_t options; //!< mainly for proxying EAP-MSCHAPv2. |
268 | | |
269 | | fr_async_t *async; //!< for new async listeners |
270 | | |
271 | | char const *alloc_file; //!< File the request was allocated in. |
272 | | |
273 | | int alloc_line; //!< Line the request was allocated on. |
274 | | |
275 | | fr_dlist_t listen_entry; //!< request's entry in the list for this listener / socket |
276 | | |
277 | | uint32_t priority; //!< higher == higher priority |
278 | | uint32_t sequence; //!< higher == higher priority, too |
279 | | |
280 | | fr_heap_index_t runnable; //!< entry in the heap of runnable packets |
281 | | |
282 | | }; /* request_t typedef */ |
283 | | |
284 | | /** Optional arguments for initialising requests |
285 | | * |
286 | | */ |
287 | | typedef struct { |
288 | | fr_dict_t const *namespace; //!< The namespace this request implements. |
289 | | |
290 | | request_t *parent; //!< If set, the request is a child request used to run |
291 | | ///< policy sections and additional virtual servers. |
292 | | |
293 | | request_pair_lists_t pair_list; //!< Alternative pair list heads. |
294 | | ///< These allow a request to expose nested attributes as |
295 | | ///< request or reply lists from the parent. |
296 | | |
297 | | bool detachable; //!< Request should be detachable, i.e. able to run even |
298 | | ///< if its parent exits. |
299 | | } request_init_args_t; |
300 | | |
301 | | #ifdef WITH_VERIFY_PTR |
302 | 0 | # define REQUEST_VERIFY(_x) request_verify(__FILE__, __LINE__, _x) |
303 | | #else |
304 | | /* |
305 | | * Even if were building without WITH_VERIFY_PTR |
306 | | * the pointer must not be NULL when these various macros are used |
307 | | * so we can add some sneaky asserts. |
308 | | */ |
309 | | # define REQUEST_VERIFY(_x) fr_assert(_x) |
310 | | #endif |
311 | | |
312 | 0 | #define RAD_REQUEST_LVL_NONE (0) //!< No debug messages should be printed. |
313 | | #define RAD_REQUEST_LVL_DEBUG (1) |
314 | | #define RAD_REQUEST_LVL_DEBUG2 (2) |
315 | | #define RAD_REQUEST_LVL_DEBUG3 (3) |
316 | | #define RAD_REQUEST_LVL_DEBUG4 (4) |
317 | | |
318 | | #define RAD_REQUEST_OPTION_CTX (1 << 1) |
319 | | #define RAD_REQUEST_OPTION_DETAIL (1 << 2) |
320 | | |
321 | | #define request_init(_ctx, _type, _args) \ |
322 | | _request_init(__FILE__, __LINE__, _ctx, _type, _args) |
323 | | |
324 | | int _request_init(char const *file, int line, |
325 | | request_t *request, request_type_t type, |
326 | | request_init_args_t const *args); |
327 | | |
328 | | int request_slab_deinit(request_t *request); |
329 | | |
330 | | /** Allocate a new external request outside of the request pool |
331 | | * |
332 | | * @param[in] _ctx Talloc ctx to allocate the request in. |
333 | | * @param[in] _args Optional arguments that control how the request is initialised. |
334 | | */ |
335 | | #define request_local_alloc_external(_ctx, _args) \ |
336 | | _request_local_alloc(__FILE__, __LINE__, (_ctx), REQUEST_TYPE_EXTERNAL, (_args)) |
337 | | |
338 | | /** Allocate a new internal request outside of the request pool |
339 | | * |
340 | | * @param[in] _ctx Talloc ctx to allocate the request in. |
341 | | * @param[in] _args Optional arguments that control how the request is initialised. |
342 | | */ |
343 | | #define request_local_alloc_internal(_ctx, _args) \ |
344 | 0 | _request_local_alloc(__FILE__, __LINE__, (_ctx), REQUEST_TYPE_INTERNAL, (_args)) |
345 | | |
346 | | request_t *_request_local_alloc(char const *file, int line, TALLOC_CTX *ctx, |
347 | | request_type_t type, request_init_args_t const *args); |
348 | | |
349 | | fr_pair_t *request_state_replace(request_t *request, fr_pair_t *state) CC_HINT(nonnull(1)); |
350 | | |
351 | | int request_detach(request_t *child); |
352 | | |
353 | | int request_global_init(void); |
354 | | void request_global_free(void); |
355 | | |
356 | | void request_log_prepend(request_t *request, fr_log_t *log, fr_log_lvl_t lvl); |
357 | | |
358 | | #ifdef WITH_VERIFY_PTR |
359 | | void request_verify(char const *file, int line, request_t const *request); /* only for special debug builds */ |
360 | | #endif |
361 | | |
362 | | static inline bool request_attr_is_list(fr_dict_attr_t const *da) |
363 | 0 | { |
364 | 0 | return (da == request_attr_request) || |
365 | 0 | (da == request_attr_reply) || |
366 | 0 | (da == request_attr_control) || |
367 | 0 | (da == request_attr_state) || |
368 | 0 | (da == request_attr_local); |
369 | 0 | } Unexecuted instantiation: dl.c:request_attr_is_list Unexecuted instantiation: json.c:request_attr_is_list Unexecuted instantiation: jpath.c:request_attr_is_list Unexecuted instantiation: base.c:request_attr_is_list Unexecuted instantiation: cache.c:request_attr_is_list Unexecuted instantiation: cert.c:request_attr_is_list Unexecuted instantiation: conf.c:request_attr_is_list Unexecuted instantiation: ctx.c:request_attr_is_list Unexecuted instantiation: engine.c:request_attr_is_list Unexecuted instantiation: log.c:request_attr_is_list Unexecuted instantiation: pairs.c:request_attr_is_list Unexecuted instantiation: session.c:request_attr_is_list Unexecuted instantiation: strerror.c:request_attr_is_list Unexecuted instantiation: utils.c:request_attr_is_list Unexecuted instantiation: verify.c:request_attr_is_list Unexecuted instantiation: version.c:request_attr_is_list Unexecuted instantiation: virtual_server.c:request_attr_is_list Unexecuted instantiation: auth.c:request_attr_is_list Unexecuted instantiation: cf_file.c:request_attr_is_list Unexecuted instantiation: cf_parse.c:request_attr_is_list Unexecuted instantiation: cf_util.c:request_attr_is_list Unexecuted instantiation: client.c:request_attr_is_list Unexecuted instantiation: command.c:request_attr_is_list Unexecuted instantiation: connection.c:request_attr_is_list Unexecuted instantiation: dependency.c:request_attr_is_list Unexecuted instantiation: dl_module.c:request_attr_is_list Unexecuted instantiation: exec.c:request_attr_is_list Unexecuted instantiation: exec_legacy.c:request_attr_is_list Unexecuted instantiation: exfile.c:request_attr_is_list Unexecuted instantiation: global_lib.c:request_attr_is_list Unexecuted instantiation: main_config.c:request_attr_is_list Unexecuted instantiation: main_loop.c:request_attr_is_list Unexecuted instantiation: map.c:request_attr_is_list Unexecuted instantiation: map_proc.c:request_attr_is_list Unexecuted instantiation: module.c:request_attr_is_list Unexecuted instantiation: module_method.c:request_attr_is_list Unexecuted instantiation: module_rlm.c:request_attr_is_list Unexecuted instantiation: paircmp.c:request_attr_is_list Unexecuted instantiation: pairmove.c:request_attr_is_list Unexecuted instantiation: password.c:request_attr_is_list Unexecuted instantiation: pool.c:request_attr_is_list Unexecuted instantiation: regex.c:request_attr_is_list Unexecuted instantiation: request.c:request_attr_is_list Unexecuted instantiation: request_data.c:request_attr_is_list Unexecuted instantiation: snmp.c:request_attr_is_list Unexecuted instantiation: state.c:request_attr_is_list Unexecuted instantiation: stats.c:request_attr_is_list Unexecuted instantiation: tmpl_dcursor.c:request_attr_is_list Unexecuted instantiation: tmpl_eval.c:request_attr_is_list Unexecuted instantiation: tmpl_tokenize.c:request_attr_is_list Unexecuted instantiation: trigger.c:request_attr_is_list Unexecuted instantiation: trunk.c:request_attr_is_list Unexecuted instantiation: users_file.c:request_attr_is_list Unexecuted instantiation: util.c:request_attr_is_list Unexecuted instantiation: virtual_servers.c:request_attr_is_list Unexecuted instantiation: call.c:request_attr_is_list Unexecuted instantiation: call_env.c:request_attr_is_list Unexecuted instantiation: caller.c:request_attr_is_list Unexecuted instantiation: catch.c:request_attr_is_list Unexecuted instantiation: child_request.c:request_attr_is_list Unexecuted instantiation: compile.c:request_attr_is_list Unexecuted instantiation: condition.c:request_attr_is_list Unexecuted instantiation: detach.c:request_attr_is_list Unexecuted instantiation: edit.c:request_attr_is_list Unexecuted instantiation: finally.c:request_attr_is_list Unexecuted instantiation: foreach.c:request_attr_is_list Unexecuted instantiation: function.c:request_attr_is_list Unexecuted instantiation: group.c:request_attr_is_list Unexecuted instantiation: interpret.c:request_attr_is_list Unexecuted instantiation: interpret_synchronous.c:request_attr_is_list Unexecuted instantiation: io.c:request_attr_is_list Unexecuted instantiation: limit.c:request_attr_is_list Unexecuted instantiation: load_balance.c:request_attr_is_list Unexecuted instantiation: map_builtin.c:request_attr_is_list Unexecuted instantiation: parallel.c:request_attr_is_list Unexecuted instantiation: return.c:request_attr_is_list Unexecuted instantiation: subrequest.c:request_attr_is_list Unexecuted instantiation: switch.c:request_attr_is_list Unexecuted instantiation: timeout.c:request_attr_is_list Unexecuted instantiation: tmpl.c:request_attr_is_list Unexecuted instantiation: try.c:request_attr_is_list Unexecuted instantiation: transaction.c:request_attr_is_list Unexecuted instantiation: xlat.c:request_attr_is_list Unexecuted instantiation: xlat_alloc.c:request_attr_is_list Unexecuted instantiation: xlat_builtin.c:request_attr_is_list Unexecuted instantiation: xlat_eval.c:request_attr_is_list Unexecuted instantiation: xlat_expr.c:request_attr_is_list Unexecuted instantiation: xlat_func.c:request_attr_is_list Unexecuted instantiation: xlat_inst.c:request_attr_is_list Unexecuted instantiation: xlat_pair.c:request_attr_is_list Unexecuted instantiation: xlat_purify.c:request_attr_is_list Unexecuted instantiation: xlat_redundant.c:request_attr_is_list Unexecuted instantiation: xlat_tokenize.c:request_attr_is_list Unexecuted instantiation: app_io.c:request_attr_is_list Unexecuted instantiation: channel.c:request_attr_is_list Unexecuted instantiation: coord.c:request_attr_is_list Unexecuted instantiation: coord_pair.c:request_attr_is_list Unexecuted instantiation: master.c:request_attr_is_list Unexecuted instantiation: network.c:request_attr_is_list Unexecuted instantiation: schedule.c:request_attr_is_list Unexecuted instantiation: thread.c:request_attr_is_list Unexecuted instantiation: worker.c:request_attr_is_list |
370 | | |
371 | | #ifdef __cplusplus |
372 | | } |
373 | | #endif |