/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: 80ff812e65d815f20981b32466b172e2bda49a6f $ |
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: 80ff812e65d815f20981b32466b172e2bda49a6f $") |
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 + |
62 | | * 4 pair lists and root + |
63 | | * 2 packets + |
64 | | * some extra for VPs |
65 | | * |
66 | | * Stack frames are allocated within the stack pool. |
67 | | */ |
68 | 0 | #define REQUEST_POOL_NUM_OBJECTS ( \ |
69 | 0 | 1 + \ |
70 | 0 | 5 + \ |
71 | 0 | 2 + \ |
72 | 0 | 10 \ |
73 | 0 | ) |
74 | | |
75 | | /* |
76 | | * Stack memory + |
77 | | * 4 pair lists and root + |
78 | | * 2 packets + |
79 | | * some extra for VPs |
80 | | */ |
81 | 0 | #define REQUEST_POOL_SIZE ( \ |
82 | 0 | UNLANG_STACK_POOL_SIZE + \ |
83 | 0 | (sizeof(fr_pair_t) * 5) + \ |
84 | 0 | (sizeof(fr_packet_t) * 2) + \ |
85 | 0 | (sizeof(fr_pair_t) * 10) \ |
86 | 0 | ) |
87 | | |
88 | | typedef enum { |
89 | | REQUEST_ACTIVE = 1, //!< Request is active (running or runnable) |
90 | | REQUEST_STOP_PROCESSING, //!< Request has been signalled to stop |
91 | | REQUEST_DONE, //!< Request has completed |
92 | | } request_master_state_t; |
93 | | #define REQUEST_MASTER_NUM_STATES (REQUEST_COUNTED + 1) |
94 | | |
95 | | typedef enum request_state_t { |
96 | | REQUEST_INIT = 0, |
97 | | REQUEST_RECV, |
98 | | REQUEST_PROCESS, |
99 | | REQUEST_SEND, |
100 | | REQUEST_OTHER_1, |
101 | | REQUEST_OTHER_2, |
102 | | REQUEST_OTHER_3, |
103 | | REQUEST_OTHER_4, |
104 | | } request_state_t; |
105 | | |
106 | | extern HIDDEN fr_dict_attr_t const *request_attr_root; |
107 | | extern fr_dict_attr_t const *request_attr_request; |
108 | | extern fr_dict_attr_t const *request_attr_reply; |
109 | | extern fr_dict_attr_t const *request_attr_control; |
110 | | extern fr_dict_attr_t const *request_attr_state; |
111 | | extern fr_dict_attr_t const *request_attr_local; |
112 | | |
113 | | /** Convenience macro for accessing the request list |
114 | | * |
115 | | * This should be used in the form `&request->request_pairs` |
116 | | * to get a pointer to the head of the request list. |
117 | | */ |
118 | 0 | #define request_pairs pair_list.request->children |
119 | | |
120 | | /** Talloc ctx for allocating request pairs under |
121 | | */ |
122 | 0 | #define request_ctx pair_list.request |
123 | | |
124 | | /** Convenience macro for accessing the reply list |
125 | | * |
126 | | * This should be used in the form `&request->reply_pairs` |
127 | | * to get a pointer to the head of the request list. |
128 | | */ |
129 | 0 | #define reply_pairs pair_list.reply->children |
130 | | |
131 | | /** Talloc ctx for allocating reply pairs under |
132 | | */ |
133 | 0 | #define reply_ctx pair_list.reply |
134 | | |
135 | | /** Convenience macro for accessing the control list |
136 | | * |
137 | | * This should be used in the form `&request->control_pairs` |
138 | | * to get a pointer to the head of the request list. |
139 | | */ |
140 | 0 | #define control_pairs pair_list.control->children |
141 | | |
142 | | /** Talloc ctx for allocating control pairs under |
143 | | */ |
144 | 0 | #define control_ctx pair_list.control |
145 | | |
146 | | /** Convenience macro for accessing the state list |
147 | | * |
148 | | * This should be used in the form `&request->session_state_pairs` |
149 | | * to get a pointer to the head of the request list. |
150 | | */ |
151 | 0 | #define session_state_pairs pair_list.state->children |
152 | | |
153 | | /** Talloc ctx for allocating reply pairs under |
154 | | */ |
155 | 0 | #define session_state_ctx pair_list.state |
156 | | |
157 | | /** Convenience macro for accessing the state list |
158 | | * |
159 | | * This should be used in the form `&request->local_pairs` |
160 | | * to get a pointer to the head of the local list. |
161 | | */ |
162 | 0 | #define local_pairs pair_list.local->children |
163 | | |
164 | | /** Talloc ctx for allocating local variables |
165 | | */ |
166 | 0 | #define local_ctx pair_list.local |
167 | | |
168 | | /** Pair lists accessible from the request |
169 | | * |
170 | | */ |
171 | | typedef struct { |
172 | | fr_pair_t *request; //!< Pair containing the request list. |
173 | | fr_pair_t *reply; //!< Pair containing the reply list. |
174 | | fr_pair_t *control; //!< Pair containing the control list. |
175 | | fr_pair_t *state; //!< Pair containing the state list. |
176 | | fr_pair_t *local; //!< Pair containing local variables |
177 | | } request_pair_lists_t; |
178 | | |
179 | | typedef enum { |
180 | | REQUEST_TYPE_EXTERNAL = 0, //!< A request received on the wire. |
181 | | REQUEST_TYPE_INTERNAL, //!< A request generated internally. |
182 | | REQUEST_TYPE_DETACHED //!< A request that was generated internally, but is now detached |
183 | | ///< (not associated with a parent request.) |
184 | | } request_type_t; |
185 | | |
186 | | #define request_is_external(_x) ((_x)->type == REQUEST_TYPE_EXTERNAL) |
187 | | #define request_is_internal(_x) ((_x)->type == REQUEST_TYPE_INTERNAL) |
188 | 0 | #define request_is_detached(_x) ((_x)->type == REQUEST_TYPE_DETACHED) |
189 | 0 | #define request_is_detachable(_x) ((_x)->flags.detachable) |
190 | | #define request_is_dynamic_client(_x) ((_x)->flags.dynamic_client) |
191 | | #define request_set_dynamic_client(_x) ((_x)->flags.dynamic_client = true) |
192 | | |
193 | | struct request_s { |
194 | | #ifndef NDEBUG |
195 | | uint32_t magic; //!< Magic number used to detect memory corruption, |
196 | | //!< or request structs that have not been properly initialised. |
197 | | |
198 | | uint64_t ins_count; //!< count of instructions we've ran |
199 | | uint64_t ins_max; //!< max instruction to bail out at |
200 | | |
201 | | #endif |
202 | | void *stack; //!< unlang interpreter stack. |
203 | | |
204 | | request_type_t type; //!< What type of request this is. |
205 | | |
206 | | request_t *parent; //!< Request that generated this request. |
207 | | |
208 | | uint64_t number; //!< Monotonically increasing request number. Reset on server restart. |
209 | | uint64_t child_number; //!< Monotonically increasing number for children of this request |
210 | | char const *name; //!< for debug printing, as (%d) is no longer sufficient |
211 | | |
212 | | uint64_t seq_start; //!< State sequence ID. Stable identifier for a sequence of requests |
213 | | //!< and responses. |
214 | | fr_dict_t const *proto_dict; //!< Dictionary of the protocol that this request belongs to. |
215 | | fr_dict_t const *local_dict; //!< dictionary for local variables |
216 | | |
217 | | fr_pair_t *pair_root; //!< Root attribute which contains the |
218 | | ///< other list attributes as children. |
219 | | |
220 | | /** Pair lists associated with the request |
221 | | * |
222 | | * @warning DO NOT allocate pairs directly beneath the root |
223 | | * or in the ctx of the request. |
224 | | * They MUST be allocated beneath their appropriate |
225 | | * list attribute. |
226 | | */ |
227 | | request_pair_lists_t pair_list; //!< Structure containing all pair lists. |
228 | | |
229 | | fr_dlist_head_t data; //!< Request data. |
230 | | |
231 | | /** Capabilities flags for this request |
232 | | * |
233 | | */ |
234 | | struct { |
235 | | unsigned int detachable : 1; //!< This request may be detached from its parent.. |
236 | | unsigned int dynamic_client : 1; //!< this is a dynamic client request |
237 | | } flags; |
238 | | |
239 | | /** Logging information |
240 | | * |
241 | | */ |
242 | | struct { |
243 | | log_dst_t *dst; //!< First in a list of log destinations. |
244 | | |
245 | | fr_log_lvl_t lvl; //!< Log messages with lvl >= to this should be logged. |
246 | | |
247 | | rindent_t indent; //!< Indentation for log messages. |
248 | | } log; |
249 | | |
250 | | char const *component; //!< Section the request is in. |
251 | | char const *module; //!< Module the request is currently being processed by. |
252 | | |
253 | | fr_packet_t *packet; //!< Incoming request. |
254 | | fr_packet_t *reply; //!< Outgoing response. |
255 | | |
256 | | fr_client_t *client; //!< The client that originally sent us the request. |
257 | | |
258 | | request_master_state_t master_state; //!< Set by the master thread to signal the child that's currently |
259 | | //!< working with the request, to do something. |
260 | | bool counted; //!< Set if the request has been counted in the stats. |
261 | | |
262 | | rlm_rcode_t rcode; //!< Last rcode returned by a module |
263 | | |
264 | | fr_rb_node_t dedup_node; //!< entry in the deduplication tree. |
265 | | |
266 | | fr_timer_t *timeout; //!< Timer event for this request. This tracks when we need to |
267 | | ///< forcefully terminate a request. |
268 | | |
269 | | uint32_t options; //!< mainly for proxying EAP-MSCHAPv2. |
270 | | |
271 | | fr_async_t *async; //!< for new async listeners |
272 | | |
273 | | char const *alloc_file; //!< File the request was allocated in. |
274 | | |
275 | | int alloc_line; //!< Line the request was allocated on. |
276 | | |
277 | | fr_dlist_t listen_entry; //!< request's entry in the list for this listener / socket |
278 | | |
279 | | uint32_t priority; //!< higher == higher priority |
280 | | uint32_t sequence; //!< higher == higher priority, too |
281 | | |
282 | | fr_heap_index_t runnable; //!< entry in the heap of runnable packets |
283 | | |
284 | | }; /* request_t typedef */ |
285 | | |
286 | | /** Optional arguments for initialising requests |
287 | | * |
288 | | */ |
289 | | typedef struct { |
290 | | fr_dict_t const *namespace; //!< The namespace this request implements. |
291 | | |
292 | | request_t *parent; //!< If set, the request is a child request used to run |
293 | | ///< policy sections and additional virtual servers. |
294 | | |
295 | | request_pair_lists_t pair_list; //!< Alternative pair list heads. |
296 | | ///< These allow a request to expose nested attributes as |
297 | | ///< request or reply lists from the parent. |
298 | | |
299 | | bool detachable; //!< Request should be detachable, i.e. able to run even |
300 | | ///< if its parent exits. |
301 | | } request_init_args_t; |
302 | | |
303 | | #ifdef WITH_VERIFY_PTR |
304 | 0 | # define REQUEST_VERIFY(_x) request_verify(__FILE__, __LINE__, _x) |
305 | | #else |
306 | | /* |
307 | | * Even if were building without WITH_VERIFY_PTR |
308 | | * the pointer must not be NULL when these various macros are used |
309 | | * so we can add some sneaky asserts. |
310 | | */ |
311 | | # define REQUEST_VERIFY(_x) fr_assert(_x) |
312 | | #endif |
313 | | |
314 | 0 | #define RAD_REQUEST_LVL_NONE (0) //!< No debug messages should be printed. |
315 | | #define RAD_REQUEST_LVL_DEBUG (1) |
316 | | #define RAD_REQUEST_LVL_DEBUG2 (2) |
317 | | #define RAD_REQUEST_LVL_DEBUG3 (3) |
318 | | #define RAD_REQUEST_LVL_DEBUG4 (4) |
319 | | |
320 | | #define RAD_REQUEST_OPTION_CTX (1 << 1) |
321 | | #define RAD_REQUEST_OPTION_DETAIL (1 << 2) |
322 | | |
323 | | #define request_init(_ctx, _type, _args) \ |
324 | | _request_init(__FILE__, __LINE__, _ctx, _type, _args) |
325 | | |
326 | | int _request_init(char const *file, int line, |
327 | | request_t *request, request_type_t type, |
328 | | request_init_args_t const *args); |
329 | | |
330 | | int request_slab_deinit(request_t *request); |
331 | | |
332 | | /** Allocate a new external request outside of the request pool |
333 | | * |
334 | | * @param[in] _ctx Talloc ctx to allocate the request in. |
335 | | * @param[in] _args Optional arguments that control how the request is initialised. |
336 | | */ |
337 | | #define request_local_alloc_external(_ctx, _args) \ |
338 | | _request_local_alloc(__FILE__, __LINE__, (_ctx), REQUEST_TYPE_EXTERNAL, (_args)) |
339 | | |
340 | | /** Allocate a new internal request outside of the request pool |
341 | | * |
342 | | * @param[in] _ctx Talloc ctx to allocate the request in. |
343 | | * @param[in] _args Optional arguments that control how the request is initialised. |
344 | | */ |
345 | | #define request_local_alloc_internal(_ctx, _args) \ |
346 | 0 | _request_local_alloc(__FILE__, __LINE__, (_ctx), REQUEST_TYPE_INTERNAL, (_args)) |
347 | | |
348 | | request_t *_request_local_alloc(char const *file, int line, TALLOC_CTX *ctx, |
349 | | request_type_t type, request_init_args_t const *args); |
350 | | |
351 | | fr_pair_t *request_state_replace(request_t *request, fr_pair_t *state) CC_HINT(nonnull(1)); |
352 | | |
353 | | int request_detach(request_t *child); |
354 | | |
355 | | int request_global_init(void); |
356 | | void request_global_free(void); |
357 | | |
358 | | void request_log_prepend(request_t *request, fr_log_t *log, fr_log_lvl_t lvl); |
359 | | |
360 | | #ifdef WITH_VERIFY_PTR |
361 | | void request_verify(char const *file, int line, request_t const *request); /* only for special debug builds */ |
362 | | #endif |
363 | | |
364 | | static inline bool request_attr_is_list(fr_dict_attr_t const *da) |
365 | 3.81k | { |
366 | 3.81k | return (da == request_attr_request) || |
367 | 3.18k | (da == request_attr_reply) || |
368 | 3.18k | (da == request_attr_control) || |
369 | 3.18k | (da == request_attr_state) || |
370 | 3.18k | (da == request_attr_local); |
371 | 3.81k | } Unexecuted instantiation: fuzzer_cf.c:request_attr_is_list Unexecuted instantiation: fuzzer_xlat.c:request_attr_is_list Unexecuted instantiation: fuzzer_tmpl.c:request_attr_is_list Unexecuted instantiation: dl.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 tmpl_tokenize.c:request_attr_is_list Line | Count | Source | 365 | 3.81k | { | 366 | 3.81k | return (da == request_attr_request) || | 367 | 3.18k | (da == request_attr_reply) || | 368 | 3.18k | (da == request_attr_control) || | 369 | 3.18k | (da == request_attr_state) || | 370 | 3.18k | (da == request_attr_local); | 371 | 3.81k | } |
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: json.c:request_attr_is_list Unexecuted instantiation: jpath.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 |
372 | | |
373 | | #ifdef __cplusplus |
374 | | } |
375 | | #endif |