The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
request.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 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: 1b2934f4a4f6cc23f49072ece970c597a3495827 $
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: 1b2934f4a4f6cc23f49072ece970c597a3495827 $")
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 # define REQUEST_MAGIC (0xdeadbeef)
58 #endif
59 
60 typedef enum {
61  REQUEST_ACTIVE = 1, //!< Request is active (running or runnable)
62  REQUEST_STOP_PROCESSING, //!< Request has been signalled to stop
63  REQUEST_DONE, //!< Request has completed
65 #define REQUEST_MASTER_NUM_STATES (REQUEST_COUNTED + 1)
66 
67 typedef enum request_state_t {
77 
84 
85 /** Convenience macro for accessing the request list
86  *
87  * This should be used in the form `&request->request_pairs`
88  * to get a pointer to the head of the request list.
89  */
90 #define request_pairs pair_list.request->children
91 
92 /** Talloc ctx for allocating request pairs under
93  */
94 #define request_ctx pair_list.request
95 
96 /** Convenience macro for accessing the reply list
97  *
98  * This should be used in the form `&request->reply_pairs`
99  * to get a pointer to the head of the request list.
100  */
101 #define reply_pairs pair_list.reply->children
102 
103 /** Talloc ctx for allocating reply pairs under
104  */
105 #define reply_ctx pair_list.reply
106 
107 /** Convenience macro for accessing the control list
108  *
109  * This should be used in the form `&request->control_pairs`
110  * to get a pointer to the head of the request list.
111  */
112 #define control_pairs pair_list.control->children
113 
114 /** Talloc ctx for allocating control pairs under
115  */
116 #define control_ctx pair_list.control
117 
118 /** Convenience macro for accessing the state list
119  *
120  * This should be used in the form `&request->session_state_pairs`
121  * to get a pointer to the head of the request list.
122  */
123 #define session_state_pairs pair_list.state->children
124 
125 /** Talloc ctx for allocating reply pairs under
126  */
127 #define session_state_ctx pair_list.state
128 
129 /** Convenience macro for accessing the state list
130  *
131  * This should be used in the form `&request->local_pairs`
132  * to get a pointer to the head of the local list.
133  */
134 #define local_pairs pair_list.local->children
135 
136 /** Talloc ctx for allocating local variagbles
137  */
138 #define local_ctx pair_list.local
139 
140 /** Pair lists accessible from the request
141  *
142  */
143 typedef struct {
144  fr_pair_t *request; //!< Pair containing the request list.
145  fr_pair_t *reply; //!< Pair containing the reply list.
146  fr_pair_t *control; //!< Pair containing the control list.
147  fr_pair_t *state; //!< Pair containing the state list.
148  fr_pair_t *local; //!< Pair containing local variables
150 
151 typedef enum {
152  REQUEST_TYPE_EXTERNAL = 0, //!< A request received on the wire.
153  REQUEST_TYPE_INTERNAL, //!< A request generated internally.
154  REQUEST_TYPE_DETACHED //!< A request that was generated internally, but is now detached
155  ///< (not associated with a parent request.)
157 
158 #define request_is_external(_x) ((_x)->type == REQUEST_TYPE_EXTERNAL)
159 #define request_is_internal(_x) ((_x)->type == REQUEST_TYPE_INTERNAL)
160 #define request_is_detached(_x) ((_x)->type == REQUEST_TYPE_DETACHED)
161 #define request_is_detachable(_x) ((_x)->flags.detachable)
162 #define request_is_dynamic_client(_x) ((_x)->flags.dynamic_client)
163 #define request_set_dynamic_client(_x) ((_x)->flags.dynamic_client = true)
164 
165 struct request_s {
166 #ifndef NDEBUG
167  uint32_t magic; //!< Magic number used to detect memory corruption,
168  //!< or request structs that have not been properly initialised.
169 
170  uint64_t ins_count; //!< count of instructions we've ran
171  uint64_t ins_max; //!< max instruction to bail out at
172 
173 #endif
174  void *stack; //!< unlang interpreter stack.
175 
176  request_type_t type; //!< What type of request this is.
177 
178  request_t *parent; //!< Request that generated this request.
179 
180  uint64_t number; //!< Monotonically increasing request number. Reset on server restart.
181  uint64_t child_number; //!< Monotonically increasing number for children of this request
182  char const *name; //!< for debug printing, as (%d) is no longer sufficient
183 
184  uint64_t seq_start; //!< State sequence ID. Stable identifier for a sequence of requests
185  //!< and responses.
186  fr_dict_t const *dict; //!< Dictionary of the protocol that this request belongs to.
187 
188  fr_pair_t *pair_root; //!< Root attribute which contains the
189  ///< other list attributes as children.
190 
191  /** Pair lists associated with the request
192  *
193  * @warning DO NOT allocate pairs directly beneath the root
194  * or in the ctx of the request.
195  * They MUST be allocated beneath their appropriate
196  * list attribute.
197  */
198  request_pair_lists_t pair_list; //!< Structure containing all pair lists.
199 
200  fr_dlist_head_t data; //!< Request data.
201 
202  /** Capabilities flags for this request
203  *
204  */
205  struct {
206  uint8_t detachable : 1; //!< This request may be detached from its parent..
207  uint8_t dynamic_client : 1; //!< this is a dynamic client request
208  } flags;
209 
210  /** Logging information
211  *
212  */
213  struct {
214  log_dst_t *dst; //!< First in a list of log destinations.
215 
216  fr_log_lvl_t lvl; //!< Log messages with lvl >= to this should be logged.
217 
218  rindent_t indent; //!< Indentation for log messages.
219  } log;
220 
221  char const *component; //!< Section the request is in.
222  char const *module; //!< Module the request is currently being processed by.
223 
224  fr_packet_t *packet; //!< Incoming request.
225  fr_packet_t *reply; //!< Outgoing response.
226 
227  fr_client_t *client; //!< The client that originally sent us the request.
228 
229  request_master_state_t master_state; //!< Set by the master thread to signal the child that's currently
230  //!< working with the request, to do something.
231  bool counted; //!< Set if the request has been counted in the stats.
232 
233  rlm_rcode_t rcode; //!< Last rcode returned by a module
234 
235  fr_rb_node_t dedup_node; //!< entry in the deduplication tree.
236  fr_heap_index_t runnable_id; //!< entry in the heap of runnable packets
237  fr_heap_index_t time_order_id; //!< entry in the heap of time ordered packets
238 
239  uint32_t options; //!< mainly for proxying EAP-MSCHAPv2.
240 
241  fr_async_t *async; //!< for new async listeners
242 
243  char const *alloc_file; //!< File the request was allocated in.
244 
245  int alloc_line; //!< Line the request was allocated on.
246 
247  fr_dlist_t listen_entry; //!< request's entry in the list for this listener / socket
248  fr_dlist_t free_entry; //!< Request's entry in the free list.
249 }; /* request_t typedef */
250 
251 /** Optional arguments for initialising requests
252  *
253  */
254 typedef struct {
255  fr_dict_t const *namespace; //!< The namespace this request implements.
256 
257  request_t *parent; //!< If set, the request is a child request used to run
258  ///< policy sections and additional virtual servers.
259 
260  request_pair_lists_t pair_list; //!< Alternative pair list heads.
261  ///< These allow a request to expose nested attributes as
262  ///< request or reply lists from the parent.
263 
264  bool detachable; //!< Request should be detachable, i.e. able to run even
265  ///< if its parent exits.
267 
268 #ifdef WITH_VERIFY_PTR
269 # define REQUEST_VERIFY(_x) request_verify(__FILE__, __LINE__, _x)
270 #else
271 /*
272  * Even if were building without WITH_VERIFY_PTR
273  * the pointer must not be NULL when these various macros are used
274  * so we can add some sneaky asserts.
275  */
276 # define REQUEST_VERIFY(_x) fr_assert(_x)
277 #endif
278 
279 #define RAD_REQUEST_LVL_NONE (0) //!< No debug messages should be printed.
280 #define RAD_REQUEST_LVL_DEBUG (1)
281 #define RAD_REQUEST_LVL_DEBUG2 (2)
282 #define RAD_REQUEST_LVL_DEBUG3 (3)
283 #define RAD_REQUEST_LVL_DEBUG4 (4)
284 
285 #define RAD_REQUEST_OPTION_CTX (1 << 1)
286 #define RAD_REQUEST_OPTION_DETAIL (1 << 2)
287 
288 /** Allocate a new external request
289  *
290  * Use for requests produced by listeners
291  *
292  * @param[in] _ctx Talloc ctx to bind the request to.
293  * @param[in] _args Optional arguments that control how the request is initialised.
294  */
295 #define request_alloc_external(_ctx, _args) \
296  _request_alloc( __FILE__, __LINE__, (_ctx), REQUEST_TYPE_EXTERNAL, (_args))
297 
298 /** Allocate a new internal request
299  *
300  * Use for requests produced by modules and unlang
301  *
302  * @param[in] _ctx Talloc ctx to bind the request to.
303  * @param[in] _args Optional arguments that control how the request is initialised.
304  */
305 #define request_alloc_internal(_ctx, _args) \
306  _request_alloc( __FILE__, __LINE__, (_ctx), REQUEST_TYPE_INTERNAL, (_args))
307 
308 request_t *_request_alloc(char const *file, int line, TALLOC_CTX *ctx,
310 
311 /** Allocate a new external request outside of the request pool
312  *
313  * @param[in] _ctx Talloc ctx to allocate the request in.
314  * @param[in] _args Optional arguments that control how the request is initialised.
315  */
316 #define request_local_alloc_external(_ctx, _args) \
317  _request_local_alloc(__FILE__, __LINE__, (_ctx), REQUEST_TYPE_EXTERNAL, (_args))
318 
319 /** Allocate a new internal request outside of the request pool
320  *
321  * @param[in] _ctx Talloc ctx to allocate the request in.
322  * @param[in] _args Optional arguments that control how the request is initialised.
323  */
324 #define request_local_alloc_internal(_ctx, _args) \
325  _request_local_alloc(__FILE__, __LINE__, (_ctx), REQUEST_TYPE_INTERNAL, (_args))
326 
327 request_t *_request_local_alloc(char const *file, int line, TALLOC_CTX *ctx,
329 
330 fr_pair_t *request_state_replace(request_t *request, fr_pair_t *state) CC_HINT(nonnull(1));
331 
332 int request_detach(request_t *child);
333 
334 int request_global_init(void);
336 
337 void request_log_prepend(request_t *request, fr_log_t *log, fr_log_lvl_t lvl);
338 
339 #ifdef WITH_VERIFY_PTR
340 void request_verify(char const *file, int line, request_t const *request); /* only for special debug builds */
341 #endif
342 
343 #ifdef __cplusplus
344 }
345 #endif
int const char * file
Definition: acutest.h:702
va_list args
Definition: acutest.h:770
int const char int line
Definition: acutest.h:702
void request_verify(UNUSED char const *file, UNUSED int line, UNUSED request_t *request)
#define RCSIDH(h, id)
Definition: build.h:482
#define HIDDEN
Definition: build.h:312
Head of a doubly linked list.
Definition: dlist.h:51
Entry in a doubly linked list.
Definition: dlist.h:41
unsigned int fr_heap_index_t
Definition: heap.h:80
Minimal data structure to use the new code.
Definition: listen.h:58
Describes a host allowed to send packets to the server.
Definition: client.h:80
Definition: log.h:70
Definition: log.h:40
fr_log_lvl_t
Definition: log.h:67
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char uint8_t
Definition: merged_model.c:30
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
request_type_t type
What type of request this is.
Definition: request.h:176
fr_dict_attr_t const * request_attr_request
Definition: request.c:45
bool counted
Set if the request has been counted in the stats.
Definition: request.h:231
fr_rb_node_t dedup_node
entry in the deduplication tree.
Definition: request.h:235
fr_packet_t * packet
Incoming request.
Definition: request.h:224
uint64_t child_number
Monotonically increasing number for children of this request.
Definition: request.h:181
fr_pair_t * local
Pair containing local variables.
Definition: request.h:148
bool detachable
Request should be detachable, i.e.
Definition: request.h:264
HIDDEN fr_dict_attr_t const * request_attr_root
Definition: request.c:44
fr_pair_t * pair_root
Root attribute which contains the other list attributes as children.
Definition: request.h:188
request_pair_lists_t pair_list
Alternative pair list heads.
Definition: request.h:260
fr_packet_t * reply
Outgoing response.
Definition: request.h:225
void request_log_prepend(request_t *request, fr_log_t *log, fr_log_lvl_t lvl)
Prepend another logging destination to the list.
Definition: request.c:100
uint64_t seq_start
State sequence ID.
Definition: request.h:184
fr_client_t * client
The client that originally sent us the request.
Definition: request.h:227
fr_dict_attr_t const * request_attr_control
Definition: request.c:47
int alloc_line
Line the request was allocated on.
Definition: request.h:245
char const * alloc_file
File the request was allocated in.
Definition: request.h:243
request_type_t
Definition: request.h:151
@ REQUEST_TYPE_EXTERNAL
A request received on the wire.
Definition: request.h:152
@ REQUEST_TYPE_INTERNAL
A request generated internally.
Definition: request.h:153
@ REQUEST_TYPE_DETACHED
A request that was generated internally, but is now detached (not associated with a parent request....
Definition: request.h:154
fr_dict_attr_t const * request_attr_local
Definition: request.c:49
fr_dict_attr_t const * request_attr_state
Definition: request.c:48
fr_dict_attr_t const * request_attr_reply
Definition: request.c:46
uint64_t ins_max
max instruction to bail out at
Definition: request.h:171
fr_dict_t const * dict
Dictionary of the protocol that this request belongs to.
Definition: request.h:186
uint32_t options
mainly for proxying EAP-MSCHAPv2.
Definition: request.h:239
void request_global_free(void)
fr_heap_index_t runnable_id
entry in the heap of runnable packets
Definition: request.h:236
int request_global_init(void)
Definition: request.c:722
request_t * _request_local_alloc(char const *file, int line, TALLOC_CTX *ctx, request_type_t type, request_init_args_t const *args)
Allocate a request that's not in the free list.
Definition: request.c:608
struct request_s::@66 flags
Capabilities flags for this request.
int request_detach(request_t *child)
Unlink a subrequest from its parent.
Definition: request.c:668
void * stack
unlang interpreter stack.
Definition: request.h:174
fr_pair_t * request
Pair containing the request list.
Definition: request.h:144
fr_dlist_t free_entry
Request's entry in the free list.
Definition: request.h:248
request_pair_lists_t pair_list
Pair lists associated with the request.
Definition: request.h:198
request_t * parent
Request that generated this request.
Definition: request.h:178
request_t * _request_alloc(char const *file, int line, TALLOC_CTX *ctx, request_type_t type, request_init_args_t const *args)
Create a new request_t data structure.
Definition: request.c:501
rlm_rcode_t rcode
Last rcode returned by a module.
Definition: request.h:233
fr_dlist_t listen_entry
request's entry in the list for this listener / socket
Definition: request.h:247
request_state_t
Definition: request.h:67
@ REQUEST_INIT
Definition: request.h:68
@ REQUEST_SEND
Definition: request.h:71
@ REQUEST_OTHER_1
Definition: request.h:72
@ REQUEST_RECV
Definition: request.h:69
@ REQUEST_OTHER_3
Definition: request.h:74
@ REQUEST_OTHER_4
Definition: request.h:75
@ REQUEST_OTHER_2
Definition: request.h:73
@ REQUEST_PROCESS
Definition: request.h:70
uint64_t number
Monotonically increasing request number. Reset on server restart.
Definition: request.h:180
request_t * parent
< The namespace this request implements.
Definition: request.h:255
request_master_state_t master_state
Set by the master thread to signal the child that's currently working with the request,...
Definition: request.h:229
uint64_t ins_count
count of instructions we've ran
Definition: request.h:170
char const * component
Section the request is in.
Definition: request.h:221
fr_heap_index_t time_order_id
entry in the heap of time ordered packets
Definition: request.h:237
fr_async_t * async
for new async listeners
Definition: request.h:241
fr_pair_t * reply
Pair containing the reply list.
Definition: request.h:145
char const * name
for debug printing, as (d) is no longer sufficient
Definition: request.h:182
fr_pair_t * state
Pair containing the state list.
Definition: request.h:147
fr_dlist_head_t data
Request data.
Definition: request.h:200
char const * module
Module the request is currently being processed by.
Definition: request.h:222
request_master_state_t
Definition: request.h:60
@ REQUEST_ACTIVE
Request is active (running or runnable)
Definition: request.h:61
@ REQUEST_DONE
Request has completed.
Definition: request.h:63
@ REQUEST_STOP_PROCESSING
Request has been signalled to stop.
Definition: request.h:62
struct request_s::@67 log
Logging information.
uint32_t magic
Magic number used to detect memory corruption, or request structs that have not been properly initial...
Definition: request.h:167
fr_pair_t * control
Pair containing the control list.
Definition: request.h:146
fr_pair_t * request_state_replace(request_t *request, fr_pair_t *state))
Replace the session_state_ctx with a new one.
Definition: request.c:637
Optional arguments for initialising requests.
Definition: request.h:254
Pair lists accessible from the request.
Definition: request.h:143
fr_aka_sim_id_type_t type
Definition: log.h:96
Stores an attribute, a value and various bits of other data.
Definition: pair.h:68
int nonnull(2, 5))