Skip to content

Commit 3f906d3

Browse files
committed
add and use request->local_dict
which is initialized to request->dict (the protocol dictionary) in request_init(). it is saved, updated, and restored every time the interpreter defines a local attribute update request_init() to set dict to internal if it isn't passed in. update nearly all references to run-time parsing from request->dict to request->local_dict. Only the protocol encoders are left unchanged. this means that maps, %debug() etc. can now reference local attributes, which they couldn't before. update %eval() to use the local dict, too. update fr_listen_t to have a dict, so the worker thread can use it. and don't set request->dict in the listen decode any more.
1 parent bbb1a7a commit 3f906d3

31 files changed

+73
-167
lines changed

src/bin/unit_test_module.c

+12-20
Original file line numberDiff line numberDiff line change
@@ -190,35 +190,28 @@ static request_t *request_from_file(TALLOC_CTX *ctx, FILE *fp, fr_client_t *clie
190190

191191
static int number = 0;
192192

193-
/*
194-
* Create and initialize the new request.
195-
*/
196-
request = request_local_alloc_external(ctx, NULL);
197-
198-
/*
199-
* FIXME - Should be less RADIUS centric, but everything
200-
* else assumes RADIUS at the moment so we can fix this later.
201-
*/
202-
request->dict = dict_protocol;
203-
if (!request->dict) {
193+
if (!dict_protocol) {
204194
fr_strerror_printf_push("%s dictionary failed to load", PROTOCOL_NAME);
205-
error:
206-
talloc_free(request);
207195
return NULL;
208196
}
209197

198+
/*
199+
* Create and initialize the new request.
200+
*/
201+
request = request_local_alloc_external(ctx, (&(request_init_args_t){ .namespace = dict_protocol }));
202+
210203
request->packet = fr_packet_alloc(request, false);
211204
if (!request->packet) {
205+
oom:
212206
fr_strerror_const("No memory");
213-
goto error;
207+
error:
208+
talloc_free(request);
209+
return NULL;
214210
}
215211
request->packet->timestamp = fr_time();
216212

217213
request->reply = fr_packet_alloc(request, false);
218-
if (!request->reply) {
219-
fr_strerror_const("No memory");
220-
goto error;
221-
}
214+
if (!request->reply) goto oom;
222215

223216
request->client = client;
224217
request->number = number++;
@@ -606,7 +599,7 @@ static request_t *request_clone(request_t *old, int number, CONF_SECTION *server
606599
{
607600
request_t *request;
608601

609-
request = request_alloc_internal(NULL, NULL);
602+
request = request_alloc_internal(NULL, (&(request_init_args_t){ .namespace = old->dict }));
610603
if (!request) return NULL;
611604

612605
if (!request->packet) request->packet = fr_packet_alloc(request, false);
@@ -621,7 +614,6 @@ static request_t *request_clone(request_t *old, int number, CONF_SECTION *server
621614
unlang_call_push(request, server_cs, UNLANG_TOP_FRAME);
622615

623616
request->master_state = REQUEST_ACTIVE;
624-
request->dict = old->dict;
625617

626618
return request;
627619
}

src/lib/io/listen.h

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct fr_listen {
2727

2828
int fd; //!< file descriptor for this socket - set by open
2929
char const *name; //!< printable name for this socket - set by open
30+
fr_dict_t const *dict; //!< dictionary for this listener
3031

3132
fr_app_io_t const *app_io; //!< I/O path functions.
3233
void const *app_io_instance; //!< I/O path configuration context.

src/lib/io/network.c

+4
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ int fr_network_listen_add(fr_network_t *nr, fr_listen_t *li)
237237
{
238238
fr_ring_buffer_t *rb;
239239

240+
fr_assert(li->server_cs != NULL);
241+
li->dict = virtual_server_dict_by_cs(li->server_cs);
242+
fr_assert(li->dict != NULL);
243+
240244
/*
241245
* Skip a bunch of work if we're already in the network thread.
242246
*/

src/lib/io/worker.c

+9-10
Original file line numberDiff line numberDiff line change
@@ -803,11 +803,17 @@ static void worker_request_bootstrap(fr_worker_t *worker, fr_channel_data_t *cd,
803803
int ret = -1;
804804
request_t *request;
805805
TALLOC_CTX *ctx;
806-
fr_listen_t const *listen;
806+
fr_listen_t *listen = cd->listen;
807807

808808
if (fr_minmax_heap_num_elements(worker->time_order) >= (uint32_t) worker->config.max_requests) goto nak;
809809

810-
ctx = request = request_alloc_external(NULL, NULL);
810+
/*
811+
* Receive a message to the worker queue, and decode it
812+
* to a request.
813+
*/
814+
fr_assert(listen != NULL);
815+
816+
ctx = request = request_alloc_external(NULL, (&(request_init_args_t){ .namespace = listen->dict }));
811817
if (!request) goto nak;
812818

813819
worker_request_init(worker, request, now);
@@ -820,23 +826,16 @@ static void worker_request_bootstrap(fr_worker_t *worker, fr_channel_data_t *cd,
820826

821827
request->packet->timestamp = cd->request.recv_time; /* Legacy - Remove once everything looks at request->async */
822828

823-
/*
824-
* Receive a message to the worker queue, and decode it
825-
* to a request.
826-
*/
827-
fr_assert(cd->listen != NULL);
828-
829829
/*
830830
* Update the transport-specific fields.
831831
*/
832832
request->async->channel = cd->channel.ch;
833833

834834
request->async->recv_time = cd->request.recv_time;
835835

836-
request->async->listen = cd->listen;
836+
request->async->listen = listen;
837837
request->async->packet_ctx = cd->packet_ctx;
838838
request->async->priority = cd->priority;
839-
listen = request->async->listen;
840839

841840
/*
842841
* Now that the "request" structure has been initialized, go decode the packet.

src/lib/server/map.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,7 @@ int map_to_request(request_t *request, map_t const *map, radius_map_getvalue_t f
19211921
slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &exp_lhs, attr_str,
19221922
&(tmpl_rules_t){
19231923
.attr = {
1924-
.dict_def = request->dict,
1924+
.dict_def = request->local_dict,
19251925
.list_def = request_attr_request,
19261926
}
19271927
});

src/lib/server/map_async.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out,
320320
slen = tmpl_afrom_attr_str(tmp_ctx, NULL, &map_tmp.lhs, lhs_result_head->vb_strvalue,
321321
&(tmpl_rules_t){
322322
.attr = {
323-
.dict_def = request->dict,
323+
.dict_def = request->local_dict,
324324
.list_def = request_attr_request,
325325
}
326326
});

src/lib/server/pair_server_tests.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static request_t *request_fake_alloc(void)
7979
/*
8080
* Create and initialize the new request.
8181
*/
82-
request = request_local_alloc_external(autofree, NULL);
82+
request = request_local_alloc_external(autofree, (&(request_init_args_t){ .namespace = test_dict }));
8383

8484
request->packet = fr_packet_alloc(request, false);
8585
TEST_CHECK(request->packet != NULL);

src/lib/server/request.c

+21-11
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ RCSID("$Id$")
3131
#include <freeradius-devel/util/debug.h>
3232
#include <freeradius-devel/util/atexit.h>
3333

34-
static request_init_args_t default_args;
35-
3634
static fr_dict_t const *dict_freeradius;
3735

3836
extern fr_dict_autoload_t request_dict[];
@@ -198,7 +196,7 @@ static inline CC_HINT(always_inline) int request_detachable_init(request_t *chil
198196
static inline CC_HINT(always_inline) int request_child_init(request_t *child, request_t *parent)
199197
{
200198
child->number = parent->child_number++;
201-
if (!child->dict) child->dict = parent->dict;
199+
if (!child->dict) child->local_dict = child->dict = parent->dict;
202200

203201
if ((parent->seq_start == 0) || (parent->number == parent->seq_start)) {
204202
child->name = talloc_typed_asprintf(child, "%s.%" PRIu64, parent->name, child->number);
@@ -243,16 +241,28 @@ static inline CC_HINT(always_inline) int request_init(char const *file, int line
243241
request_t *request, request_type_t type,
244242
request_init_args_t const *args)
245243
{
244+
fr_dict_t const *dict;
246245

247246
/*
248247
* Sanity checks for different requests types
249248
*/
250249
switch (type) {
251250
case REQUEST_TYPE_EXTERNAL:
251+
fr_assert(args);
252+
252253
if (!fr_cond_assert_msg(!args->parent, "External requests must NOT have a parent")) return -1;
254+
255+
fr_assert(args->namespace);
256+
257+
dict = args->namespace;
253258
break;
254259

255260
case REQUEST_TYPE_INTERNAL:
261+
if (!args || !args->namespace) {
262+
dict = fr_dict_internal();
263+
} else {
264+
dict = args->namespace;
265+
}
256266
break;
257267

258268
case REQUEST_TYPE_DETACHED:
@@ -267,10 +277,11 @@ static inline CC_HINT(always_inline) int request_init(char const *file, int line
267277
#endif
268278
.type = type,
269279
.master_state = REQUEST_ACTIVE,
270-
.dict = args->namespace,
280+
.dict = dict,
281+
.local_dict = dict,
271282
.component = "<pre-core>",
272283
.flags = {
273-
.detachable = args->detachable
284+
.detachable = args && args->detachable,
274285
},
275286
.alloc_file = file,
276287
.alloc_line = line
@@ -306,7 +317,7 @@ static inline CC_HINT(always_inline) int request_init(char const *file, int line
306317
* the any uninitialised lists and
307318
* create them locally.
308319
*/
309-
memcpy(&request->pair_list, &args->pair_list, sizeof(request->pair_list));
320+
if (args) memcpy(&request->pair_list, &args->pair_list, sizeof(request->pair_list));
310321

311322
#define list_init(_ctx, _list) \
312323
do { \
@@ -337,7 +348,7 @@ static inline CC_HINT(always_inline) int request_init(char const *file, int line
337348
* fields if this is going to be a
338349
* child request.
339350
*/
340-
if (args->parent) {
351+
if (args && args->parent) {
341352
if (request_child_init(request, args->parent) < 0) return -1;
342353

343354
if (args->detachable) {
@@ -504,8 +515,6 @@ request_t *_request_alloc(char const *file, int line, TALLOC_CTX *ctx,
504515
request_t *request;
505516
fr_dlist_head_t *free_list;
506517

507-
if (!args) args = &default_args;
508-
509518
/*
510519
* Setup the free list, or return the free
511520
* list for this thread.
@@ -610,8 +619,6 @@ request_t *_request_local_alloc(char const *file, int line, TALLOC_CTX *ctx,
610619
{
611620
request_t *request;
612621

613-
if (!args) args = &default_args;
614-
615622
request = request_alloc_pool(ctx);
616623
if (request_init(file, line, request, type, args) < 0) return NULL;
617624

@@ -814,6 +821,9 @@ void request_verify(char const *file, int line, request_t const *request)
814821
fr_pair_list_verify(file, line, request->session_state_ctx, &request->session_state_pairs);
815822
fr_pair_list_verify(file, line, request->local_ctx, &request->local_pairs);
816823

824+
fr_assert(request->dict != NULL);
825+
fr_assert(request->local_dict != NULL);
826+
817827
if (request->packet) {
818828
packet_verify(file, line, request, request->packet, &request->request_pairs, "request");
819829
}

src/lib/server/request.h

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ struct request_s {
184184
uint64_t seq_start; //!< State sequence ID. Stable identifier for a sequence of requests
185185
//!< and responses.
186186
fr_dict_t const *dict; //!< Dictionary of the protocol that this request belongs to.
187+
fr_dict_t const *local_dict; //!< dictionary for local variables
187188

188189
fr_pair_t *pair_root; //!< Root attribute which contains the
189190
///< other list attributes as children.

src/lib/server/tmpl_dcursor_tests.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static request_t *request_fake_alloc(void)
4141
/*
4242
* Create and initialize the new request.
4343
*/
44-
request = request_local_alloc_external(autofree, NULL);
44+
request = request_local_alloc_external(autofree, (&(request_init_args_t){ .namespace = test_dict }));
4545

4646
request->packet = fr_packet_alloc(request, false);
4747
TEST_CHECK(request->packet != NULL);

src/lib/server/trigger.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ xlat_action_t trigger_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out,
9292

9393
head = request_data_reference(request, &trigger_exec_main, REQUEST_INDEX_TRIGGER_ARGS);
9494

95-
da = fr_dict_attr_by_name(NULL, fr_dict_root(request->dict ? request->dict : fr_dict_internal()),
96-
in_head->vb_strvalue);
95+
da = fr_dict_attr_by_name(NULL, fr_dict_root(request->dict), in_head->vb_strvalue);
9796
if (!da) {
9897
ERROR("Unknown attribute \"%pV\"", in_head);
9998
return XLAT_ACTION_FAIL;
@@ -386,7 +385,7 @@ int trigger_exec(unlang_interpret_t *intp,
386385
&FR_SBUFF_IN(trigger->command, talloc_array_length(trigger->command) - 1),
387386
NULL, NULL, &(tmpl_rules_t) {
388387
.attr = {
389-
.dict_def = request->dict,
388+
.dict_def = request->local_dict,
390389
.list_def = request_attr_request,
391390
.allow_unresolved = false,
392391
},

src/lib/unlang/edit.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static int tmpl_attr_from_result(TALLOC_CTX *ctx, map_t const *map, edit_result_
129129
slen = tmpl_afrom_attr_str(ctx, NULL, &out->to_free, box->vb_strvalue,
130130
&(tmpl_rules_t){
131131
.attr = {
132-
.dict_def = request->dict,
132+
.dict_def = request->local_dict,
133133
.list_def = request_attr_request,
134134
}
135135
});

src/lib/unlang/interpret.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ int unlang_interpret_push(request_t *request, unlang_t const *instruction,
213213
}
214214

215215
typedef struct {
216-
fr_dict_t const *dict;
217-
request_t *request;
216+
fr_dict_t const *old_dict; //!< the previous dictionary for the request
217+
request_t *request; //!< the request
218218
} unlang_variable_ref_t;
219219

220220
static int _local_variables_free(unlang_variable_ref_t *ref)
@@ -228,14 +228,16 @@ static int _local_variables_free(unlang_variable_ref_t *ref)
228228
vp = fr_pair_list_tail(&ref->request->local_pairs);
229229
while (vp) {
230230
prev = fr_pair_list_prev(&ref->request->local_pairs, vp);
231-
if (vp->da->dict != ref->dict) {
231+
if (vp->da->dict != ref->request->local_dict) {
232232
break;
233233
}
234234

235235
(void) fr_pair_delete(&ref->request->local_pairs, vp);
236236
vp = prev;
237237
}
238238

239+
ref->request->local_dict = ref->old_dict;
240+
239241
return 0;
240242
}
241243

@@ -295,8 +297,9 @@ unlang_action_t unlang_interpret_push_children(rlm_rcode_t *p_result, request_t
295297
/*
296298
* Set the destructor to clean up local variables.
297299
*/
298-
ref->dict = g->variables->dict;
299300
ref->request = request;
301+
ref->old_dict = request->local_dict;
302+
request->local_dict = g->variables->dict;
300303
talloc_set_destructor(ref, _local_variables_free);
301304

302305
return UNLANG_ACTION_PUSHED_CHILD;

0 commit comments

Comments
 (0)