The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
mruby.c
Go to the documentation of this file.
1/*
2 * This program is is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 9d25dd2b52b8d923a0acfac41c3347ad08b458e2 $
19 * @file rlm_mruby.c
20 * @brief Translates requests between the server an an mruby interpreter.
21 *
22 * @copyright 2016 Herwin Weststrate (freeradius@herwinw.nl)
23 * @copyright 2016 The FreeRADIUS server project
24 */
25
26#include "rlm_mruby.h"
27
30 rlm_mruby_t const *inst; //!< Module instance. Needed for access to classes
31 request_t *request; //!< Current request
32 fr_dict_attr_t const *da; //!< Dictionary attribute for this pair.
33 fr_pair_t *vp; //!< Real pair if it exists.
34 unsigned int idx; //!< Instance index.
35 mruby_pair_t *parent; //!< Parent pair.
36};
37
38static mrb_value mruby_request_frconfig(mrb_state *mrb, mrb_value self)
39{
40 return mrb_iv_get(mrb, self, mrb_intern_cstr(mrb, "@frconfig"));
41}
42
43static mrb_value mruby_request_request(mrb_state *mrb, mrb_value self)
44{
45 return mrb_iv_get(mrb, self, mrb_intern_cstr(mrb, "@request"));
46}
47
48static mrb_value mruby_request_reply(mrb_state *mrb, mrb_value self)
49{
50 return mrb_iv_get(mrb, self, mrb_intern_cstr(mrb, "@reply"));
51}
52
53static mrb_value mruby_request_control(mrb_state *mrb, mrb_value self)
54{
55 return mrb_iv_get(mrb, self, mrb_intern_cstr(mrb, "@control"));
56}
57
58static mrb_value mruby_request_session_state(mrb_state *mrb, mrb_value self)
59{
60 return mrb_iv_get(mrb, self, mrb_intern_cstr(mrb, "@session_state"));
61}
62
63struct RClass *mruby_request_class(mrb_state *mrb, struct RClass *parent)
64{
65 struct RClass *request;
66
67 request = mrb_define_class_under(mrb, parent, "Request", mrb->object_class);
68
69 mrb_define_method(mrb, request, "frconfig", mruby_request_frconfig, MRB_ARGS_NONE());
70 mrb_define_method(mrb, request, "request", mruby_request_request, MRB_ARGS_NONE());
71 mrb_define_method(mrb, request, "reply", mruby_request_reply, MRB_ARGS_NONE());
72 mrb_define_method(mrb, request, "control", mruby_request_control, MRB_ARGS_NONE());
73 mrb_define_method(mrb, request, "session_state", mruby_request_session_state, MRB_ARGS_NONE());
74
75 return request;
76}
77
78/*
79 * Structures used to identify C data types in mruby pointers
80 */
81static const struct mrb_data_type mruby_inst_type = {
82 .struct_name = "Inst",
83 .dfree = NULL
84};
85
86static const struct mrb_data_type mruby_request_type = {
87 .struct_name = "Request",
88 .dfree = NULL
89};
90
91static const struct mrb_data_type mruby_dict_attr_type = {
92 .struct_name = "DictAttr",
93 .dfree = NULL
94};
95
96static const struct mrb_data_type mruby_value_pair_type = {
97 .struct_name = "ValuePair",
98 .dfree = NULL
99};
100
101static const struct mrb_data_type mruby_ruby_pair_type = {
102 .struct_name = "RubyPair",
103 .dfree = NULL
104};
105
106/*
107 * Helper functions to return C data type pointers as mruby values
108 */
109mrb_value mruby_inst_object(mrb_state *mrb, struct RClass *klass, rlm_mruby_t const *inst)
110{
111 return mrb_obj_value(Data_Wrap_Struct(mrb, klass, &mruby_inst_type, UNCONST(void *, inst)));
112}
113
114mrb_value mruby_request_object(mrb_state *mrb, struct RClass *klass, request_t *request)
115{
116 return mrb_obj_value(Data_Wrap_Struct(mrb, klass, &mruby_request_type, (void *)request));
117}
118
119mrb_value mruby_dict_attr_object(mrb_state *mrb, struct RClass *klass, fr_dict_attr_t const *da)
120{
121 return mrb_obj_value(Data_Wrap_Struct(mrb, klass, &mruby_dict_attr_type, UNCONST(void *,da)));
122}
123
124mrb_value mruby_value_pair_object(mrb_state *mrb, struct RClass *klass, fr_pair_t *vp)
125{
126 return mrb_obj_value(Data_Wrap_Struct(mrb, klass, &mruby_value_pair_type, (void *)vp));
127}
128
129static mrb_value mruby_ruby_pair_object(mrb_state *mrb, struct RClass *klass, mruby_pair_t *pair)
130{
131 return mrb_obj_value(Data_Wrap_Struct(mrb, klass, &mruby_ruby_pair_type, (void *)pair));
132}
133
134/** Associate C structure with Ruby object representing a pair
135 *
136 * Will be called with 5 or 6 arguments
137 * - a pointer to the module instance
138 * - a pointer to the request
139 * - a pointer to the dictionary attribute for the pair
140 * - the instance number of the pair
141 * - a pointer to the real pair (if it exists)
142 * - (optional) the parent pair C structure
143 */
144static mrb_value mruby_pair_init(mrb_state *mrb, mrb_value self)
145{
146 mruby_pair_t *pair, *parent = NULL;
147 rlm_mruby_t const *inst;
148 request_t *request;
149 fr_dict_attr_t const *da;
150 mrb_int idx;
151 fr_pair_t *vp;
152
153 mrb_get_args(mrb, "dddid|d",
155 &request, &mruby_request_type,
157 &idx,
160
161 /*
162 * Apparently `initialize` can be called more than once in some
163 * scenarios, so it is best practice to clear up any old data first
164 */
165 pair = (mruby_pair_t *)DATA_PTR(self);
166 if (pair) talloc_free(pair);
167
168 /*
169 * The C data is talloced off frame ctx so we free correctly.
170 */
171 pair = talloc(unlang_interpret_frame_talloc_ctx(request), mruby_pair_t);
172 mrb_data_init(self, pair, &mruby_value_pair_type);
173
174 *pair = (mruby_pair_t) {
175 .inst = inst,
176 .request = request,
177 .da = da,
178 .idx = idx,
179 .vp = vp,
180 .parent = parent
181 };
182
183 return self;
184}
185
186/** Fetch the list of children of a list
187 *
188 */
189static mrb_value mruby_pair_list_keys(mrb_state *mrb, mrb_value self)
190{
191 mruby_pair_t *pair;
192 mrb_value keys, key;
193 fr_pair_t *vp = NULL;
194
195 pair = (mruby_pair_t *)DATA_PTR(self);
196 if (!pair) mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to retrieve C data");
197
198 keys = mrb_ary_new(mrb);
199 for (vp = fr_pair_list_head(&pair->vp->vp_group); vp; vp = fr_pair_list_next(&pair->vp->vp_group, vp)) {
200 key = mrb_str_new(mrb, vp->da->name, strlen(vp->da->name));
201 mrb_ary_push(mrb, keys, key);
202 }
203 return keys;
204}
205
206/** Convert a pair value to a suitable mruby value type
207 *
208 */
209static mrb_value mruby_pair_value_to_ruby(mrb_state *mrb, request_t *request, fr_pair_t *vp)
210{
211 switch(vp->vp_type){
212 case FR_TYPE_STRING:
213 case FR_TYPE_OCTETS:
214 return mrb_str_new(mrb, vp->vp_ptr, vp->vp_length);
215
216 case FR_TYPE_BOOL:
217 return vp->vp_bool ? mrb_obj_value(mrb->true_class) : mrb_obj_value(mrb->false_class);
218
219 case FR_TYPE_UINT8:
220 return mrb_int_value(mrb, vp->vp_uint8);
221 case FR_TYPE_UINT16:
222 return mrb_int_value(mrb, vp->vp_uint16);
223 case FR_TYPE_UINT32:
224 return mrb_int_value(mrb, vp->vp_uint32);
225 case FR_TYPE_UINT64:
226 return mrb_int_value(mrb, vp->vp_uint64);
227 case FR_TYPE_INT8:
228 return mrb_int_value(mrb, vp->vp_int8);
229 case FR_TYPE_INT16:
230 return mrb_int_value(mrb, vp->vp_int16);
231 case FR_TYPE_INT32:
232 return mrb_int_value(mrb, vp->vp_int32);
233 case FR_TYPE_INT64:
234 return mrb_int_value(mrb, vp->vp_int64);
235 case FR_TYPE_SIZE:
236 return mrb_int_value(mrb, vp->vp_size);
237
238 case FR_TYPE_FLOAT32:
239 return mrb_float_value(mrb, vp->vp_float32);
240 case FR_TYPE_FLOAT64:
241 return mrb_float_value(mrb, vp->vp_float64);
242
243 case FR_TYPE_ETHERNET:
250 case FR_TYPE_IFID:
252 case FR_TYPE_DATE:
253 case FR_TYPE_ATTR:
254 {
255 char *in;
256 size_t len;
257 mrb_value value;
258
259 len = fr_value_box_aprint(request, &in, &vp->data, NULL);
260 value = mrb_str_new(mrb, in, len);
262 return value;
263 }
264
265 case FR_TYPE_NON_LEAF:
266 REDEBUG("Cannot convert %s to ruby type", fr_type_to_str(vp->vp_type));
267 break;
268 }
269
270 return mrb_nil_value();
271}
272
273/** Get a pair value from mruby
274 *
275 * The mruby method can take an optional argument to specify the instance number
276 */
277static mrb_value mruby_value_pair_get(mrb_state *mrb, mrb_value self)
278{
279 mruby_pair_t *pair;
280 request_t *request;
281 mrb_int idx = 0;
282 fr_pair_t *vp = NULL;
283
284 pair = (mruby_pair_t *)DATA_PTR(self);
285 if (!pair) mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to retrieve C data");
286 request = pair->request;
287
288 if (mrb_get_argc(mrb) > 0) {
289 if (mrb_get_args(mrb, "|i", &idx) < 1) mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid argument");
290 }
291
292 if (idx == pair->idx) vp = pair->vp;
293 if (!vp && pair->parent && pair->parent->vp) vp = fr_pair_find_by_da_idx(&pair->parent->vp->vp_group, pair->da, idx);
294
295 if (!vp) return mrb_nil_value();
296
297 return mruby_pair_value_to_ruby(mrb, request, vp);
298}
299
300/** Build parent structural pairs needed when a leaf node is set
301 *
302 */
303static void mruby_pair_parent_build(mrb_state *mrb, mruby_pair_t *pair)
304{
305 mruby_pair_t *parent = pair->parent;
306 if (!parent->vp) mruby_pair_parent_build(mrb, parent);
307
308 if (pair->idx > 0) {
309 unsigned int count = fr_pair_count_by_da(&parent->vp->vp_group, pair->da);
310 if (count < pair->idx) mrb_raisef(mrb, E_ARGUMENT_ERROR,
311 "Attempt to set instance %d when only %d exist", pair->idx, count);
312 }
313
314 if (fr_pair_append_by_da(parent->vp, &pair->vp, &parent->vp->vp_group, pair->da) < 0) {
315 mrb_raisef(mrb, E_RUNTIME_ERROR, "Failed adding %s", pair->da->name);
316 }
317}
318
319/** Convert a ruby value to a fr_pair_t value
320 *
321 */
322static void mruby_ruby_to_pair_value(mrb_state *mrb, mrb_value *value, fr_pair_t *vp)
323{
325
326 /*
327 * Convert the type provided by mRuby to the largest containing FreeRADIUS type
328 */
329 switch (mrb_type(*value)) {
330 case MRB_TT_INTEGER:
331 fr_value_box_init(&vb, FR_TYPE_INT64, NULL, true);
332 vb.vb_int64 = mrb_integer(*value);
333 break;
334
335 case MRB_TT_FLOAT:
336 fr_value_box_init(&vb, FR_TYPE_FLOAT64, NULL, true);
337 vb.vb_float64 = mrb_float(*value);
338 break;
339
340 case MRB_TT_STRING:
341 fr_value_box_init(&vb, FR_TYPE_STRING, NULL, true);
342 fr_value_box_bstrndup_shallow(&vb, NULL, (char *)RSTRING_PTR(*value), (size_t)RSTRING_LEN(*value), true);
343 break;
344
345 case MRB_TT_TRUE:
346 fr_value_box_init(&vb, FR_TYPE_BOOL, NULL, true);
347 vb.vb_bool = true;
348 break;
349
350 case MRB_TT_FALSE:
351 fr_value_box_init(&vb, FR_TYPE_BOOL, NULL, true);
352 vb.vb_bool = false;
353 break;
354
355 default:
356 mrb_raise(mrb, E_ARGUMENT_ERROR, "Unsupported value type");
357 }
358
359 /*
360 * Cast the converted value to the required type for the pair
361 */
363 if (fr_value_box_cast(vp, &vp->data, vp->vp_type, vp->da, &vb) < 0) {
364 mrb_raisef(mrb, E_ARGUMENT_ERROR, "Failed casting ruby value to %s", fr_type_to_str(vp->vp_type));
365 }
366}
367
368/** Set a value pair from mruby
369 *
370 * The ruby method expects one or two arguments
371 * - the value to assign to the pair
372 * - (optional) instance number
373 */
374static mrb_value mruby_value_pair_set(mrb_state *mrb, mrb_value self)
375{
376 mruby_pair_t *pair;
377 mrb_value value;
378 mrb_int idx = 0;
379 fr_pair_t *vp = NULL;
380 request_t *request;
381
382 pair = (mruby_pair_t *)DATA_PTR(self);
383 if (!pair) mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to retrieve C data");
384
385 request = pair->request;
386 /*
387 * We use "o" (object) for the first argument type so we can
388 * accept strings and numbers, according to the pair type.
389 */
390 mrb_get_args(mrb, "o|i", &value, &idx);
391
392 if (!pair->parent->vp) mruby_pair_parent_build(mrb, pair->parent);
393
394 if (idx == pair->idx) vp = pair->vp;
395 if (!vp) vp = fr_pair_find_by_da_idx(&pair->parent->vp->vp_group, pair->da, idx);
396 if (!vp) {
397 if (idx > 0) {
398 unsigned int count = fr_pair_count_by_da(&pair->parent->vp->vp_group, pair->da);
399 if (count < idx) mrb_raisef(mrb, E_ARGUMENT_ERROR,
400 "Attempt to set instance %d when only %d exist", idx, count);
401 }
402
403 if (fr_pair_append_by_da(pair->parent->vp, &vp, &pair->parent->vp->vp_group, pair->da) < 0) {
404 mrb_raisef(mrb, E_RUNTIME_ERROR, "Failed adding %s", pair->da->name);
405 }
406 }
407
409
410 RDEBUG2("%pP", vp);
411 return mrb_nil_value();
412}
413
414/** Append an instance of a value pair from mruby
415 *
416 * The ruby method expects one argument - the value to assign to the pair
417 */
418static mrb_value mruby_value_pair_append(mrb_state *mrb, mrb_value self)
419{
420 mruby_pair_t *pair;
421 mrb_value value;
422 fr_pair_t *vp = NULL;
423 request_t *request;
424
425 pair = (mruby_pair_t *)DATA_PTR(self);
426 if (!pair) mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to retrieve C data");
427
428 request = pair->request;
429
430 mrb_get_args(mrb, "o", &value);
431
432 if (!pair->parent->vp) mruby_pair_parent_build(mrb, pair->parent);
433
434 if (fr_pair_append_by_da(pair->parent->vp, &vp, &pair->parent->vp->vp_group, pair->da) < 0) {
435 mrb_raisef(mrb, E_RUNTIME_ERROR, "Failed adding %s", pair->da->name);
436 }
437
439
440 RDEBUG2("%pP", vp);
441 return mrb_nil_value();
442}
443
444/** Delete a value pair from mruby
445 *
446 * The ruby method expects an optional argument - the instance number
447 */
448static mrb_value mruby_value_pair_del(mrb_state *mrb, mrb_value self)
449{
450 mruby_pair_t *pair;
451 mrb_int idx = 0;
452 fr_pair_t *vp = NULL;
453
454 pair = (mruby_pair_t *)DATA_PTR(self);
455 if (!pair) mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to retrieve C data");
456
457 mrb_get_args(mrb, "|i", &idx);
458
459 if (!pair->parent->vp) return mrb_nil_value();
460
461 if (idx == pair->idx) vp = pair->vp;
462 if (!vp) vp = fr_pair_find_by_da_idx(&pair->parent->vp->vp_group, pair->da, idx);
463 if (!vp) return mrb_nil_value();
464
465 fr_pair_delete(&pair->parent->vp->vp_group, vp);
466 if (idx == pair->idx) pair->vp = NULL;
467 return mrb_nil_value();
468}
469
470/** Implement mruby method_missing functionality to find child pairs
471 *
472 */
473static mrb_value mruby_pair_list_missing(mrb_state *mrb, mrb_value self)
474{
475 mruby_pair_t *pair;
476 request_t *request;
477 mrb_sym attr;
478 mrb_value *args = NULL, mruby_pair, pair_args[6], argv;
479 mrb_int argc = 0, len;
480 int i;
481 size_t idx = 0, child_idx = 0;
482 char *attr_name, *child_attr_name = NULL;
483 fr_dict_attr_t const *da, *child_da;
484 fr_pair_t *vp = NULL;
485
486 pair = (mruby_pair_t *)DATA_PTR(self);
487 if (!pair) mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to retrieve C data");
488 request = pair->request;
489
490 if (fr_type_is_leaf(pair->da->type)) mrb_raisef(mrb, E_RUNTIME_ERROR, "%s is a leaf attribute so has no children",
491 pair->da->name);
492 mrb_get_args(mrb, "n|*!", &attr, &args, &argc);
493
494 if (argc > 3) mrb_raise(mrb, E_ARGUMENT_ERROR, "Maximum three arguments allowed");
495
496 /*
497 * Parse any provided arguments. We allow
498 * * int - instance of attribute
499 * * str - child attribute name
500 * * int, str - instance of parent and child attribute name
501 * * str, int - child attribute and its instance
502 * * int, str, int - instance of parent, child attribute name and instance
503 *
504 * This is to allow for attribute names which begin with a number (e.g. 3GPP2 VSA) which is not
505 * allowed in mruby method names.
506 *
507 * p.request.vendor_specific("3gpp2") gets the pair request.Vendor-Specific.3GPP2
508 */
509 for (i = 0; i < argc; i++) {
510 argv = args[i];
511 switch (mrb_type(argv)) {
512 case MRB_TT_INTEGER:
513 if (i == 0) {
514 idx = mrb_integer(argv);
515 } else {
516 if (!child_attr_name) mrb_raise(mrb, E_ARGUMENT_ERROR, "Child attribute instance must follow attribute name");
517 child_idx = mrb_integer(argv);
518 }
519 break;
520
521 case MRB_TT_STRING:
522 if (child_attr_name) mrb_raise(mrb, E_ARGUMENT_ERROR, "Only one child attribute name allowed");
523 child_attr_name = mrb_str_to_cstr(mrb, argv);
524 break;
525
526 default:
527 mrb_raise(mrb, E_ARGUMENT_ERROR, "Arguments can only be integer (attribute instance), or string (attribute name)");
528 }
529 }
530
531 attr_name = talloc_strdup(request, mrb_sym_name_len(mrb, attr, &len));
532 for (i = 0; i < len; i++) {
533 if (attr_name[i] == '_') attr_name[i] = '-';
534 }
535
536 da = fr_dict_attr_by_name(NULL, pair->da, attr_name);
537
538 /*
539 * Allow fallback to internal attributes if the parent is a group or dictionary root.
540 */
541 if (!da && (fr_type_is_group(pair->da->type) || pair->da->flags.is_root)) {
542 da = fr_dict_attr_by_name(NULL, fr_dict_root(fr_dict_internal()), attr_name);
543 }
544
545 if (!da) mrb_raisef(mrb, E_ARGUMENT_ERROR, "Unknown or invalid attriubte name \"%s\"", attr_name);
546
547 if (pair->vp) vp = fr_pair_find_by_da_idx(&pair->vp->vp_group, da, idx);
548
549 pair_args[0] = mruby_inst_object(mrb, pair->inst->mruby_ptr, pair->inst);
550 pair_args[1] = mruby_request_object(mrb, pair->inst->mruby_ptr, request);
551 pair_args[2] = mruby_dict_attr_object(mrb, pair->inst->mruby_ptr, da);
552 pair_args[3] = mrb_int_value(mrb, idx);
553 pair_args[4] = mruby_value_pair_object(mrb, pair->inst->mruby_ptr, vp);
554 pair_args[5] = mruby_ruby_pair_object(mrb, pair->inst->mruby_ptr, pair);
555
556 mruby_pair = mrb_obj_new(mrb, fr_type_is_leaf(da->type) ? pair->inst->mruby_pair : pair->inst->mruby_pair_list,
557 6, pair_args);
558
559 /*
560 * No child attr name in the arguments, so return the pair
561 */
562 if (!child_attr_name) return mruby_pair;
563
564 for (i = 0; i < (int)strlen(child_attr_name); i++) {
565 if (child_attr_name[i] == '_') child_attr_name[i] = '-';
566 }
567
568 child_da = fr_dict_attr_by_name(NULL, da, child_attr_name);
569
570 if (!child_da && fr_type_is_group(da->type)) {
571 child_da = fr_dict_attr_by_name(NULL, fr_dict_root(fr_dict_internal()), attr_name);
572 }
573
574 if (!child_da) mrb_raisef(mrb, E_ARGUMENT_ERROR, "Unknown or invalid attriubte name \"%s\"", attr_name);
575
576 if (vp) vp = fr_pair_find_by_da_idx(&vp->vp_group, child_da, child_idx);
577
578 pair = (mruby_pair_t *)DATA_PTR(mruby_pair);
579 pair_args[2] = mruby_dict_attr_object(mrb, pair->inst->mruby_ptr, child_da);
580 pair_args[3] = mrb_boxing_int_value(mrb, child_idx);
581 pair_args[4] = mruby_value_pair_object(mrb, pair->inst->mruby_ptr, vp);
582 pair_args[5] = mruby_ruby_pair_object(mrb, pair->inst->mruby_ptr, pair);
583
584 mruby_pair = mrb_obj_new(mrb, fr_type_is_leaf(da->type) ? pair->inst->mruby_pair : pair->inst->mruby_pair_list, 6, pair_args);
585
586 return mruby_pair;
587}
588
589struct RClass *mruby_pair_list_class(mrb_state *mrb, struct RClass *parent)
590{
591 struct RClass *pair_list;
592
593 pair_list = mrb_define_class_under(mrb, parent, "PairList", mrb->object_class);
594 MRB_SET_INSTANCE_TT(pair_list, MRB_TT_DATA);
595
596 mrb_define_method(mrb, pair_list, "initialize", mruby_pair_init, MRB_ARGS_ARG(5,1));
597 mrb_define_method(mrb, pair_list, "keys", mruby_pair_list_keys, MRB_ARGS_REQ(0));
598 mrb_define_method(mrb, pair_list, "method_missing", mruby_pair_list_missing, MRB_ARGS_OPT(1));
599
600 return pair_list;
601}
602
603struct RClass *mruby_pair_class(mrb_state *mrb, struct RClass *parent)
604{
605 struct RClass *pair;
606
607 pair = mrb_define_class_under(mrb, parent, "Pair", mrb->object_class);
608 MRB_SET_INSTANCE_TT(pair, MRB_TT_DATA);
609
610 mrb_define_method(mrb, pair, "initialize", mruby_pair_init, MRB_ARGS_ARG(5,1));
611 mrb_define_method(mrb, pair, "get", mruby_value_pair_get, MRB_ARGS_OPT(1));
612 mrb_define_method(mrb, pair, "set", mruby_value_pair_set, MRB_ARGS_ARG(1,1));
613 mrb_define_method(mrb, pair, "del", mruby_value_pair_del, MRB_ARGS_OPT(1));
614 mrb_define_method(mrb, pair, "append", mruby_value_pair_append, MRB_ARGS_REQ(1));
615
616 return pair;
617}
va_list args
Definition acutest.h:770
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:167
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
Definition dict_util.c:3355
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2492
fr_dict_t const * fr_dict_internal(void)
Definition dict_util.c:4745
static fr_slen_t in
Definition dict.h:849
Test enumeration values.
Definition dict_test.h:92
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
Definition interpret.c:1665
talloc_free(reap)
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_FLOAT32
Single precision floating point.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_COMBO_IP_PREFIX
IPv4 or IPv6 address prefix depending on length.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_IFID
Interface ID.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_FLOAT64
Double precision floating point.
struct RClass * mruby_request_class(mrb_state *mrb, struct RClass *parent)
Definition mruby.c:63
static mrb_value mruby_value_pair_append(mrb_state *mrb, mrb_value self)
Append an instance of a value pair from mruby.
Definition mruby.c:418
mrb_value mruby_request_object(mrb_state *mrb, struct RClass *klass, request_t *request)
Definition mruby.c:114
static const struct mrb_data_type mruby_value_pair_type
Definition mruby.c:96
static mrb_value mruby_value_pair_del(mrb_state *mrb, mrb_value self)
Delete a value pair from mruby.
Definition mruby.c:448
mruby_pair_t * parent
Parent pair.
Definition mruby.c:35
static mrb_value mruby_pair_init(mrb_state *mrb, mrb_value self)
Associate C structure with Ruby object representing a pair.
Definition mruby.c:144
mrb_value mruby_value_pair_object(mrb_state *mrb, struct RClass *klass, fr_pair_t *vp)
Definition mruby.c:124
static const struct mrb_data_type mruby_ruby_pair_type
Definition mruby.c:101
static mrb_value mruby_request_reply(mrb_state *mrb, mrb_value self)
Definition mruby.c:48
rlm_mruby_t const * inst
Module instance. Needed for access to classes.
Definition mruby.c:30
static mrb_value mruby_value_pair_get(mrb_state *mrb, mrb_value self)
Get a pair value from mruby.
Definition mruby.c:277
unsigned int idx
Instance index.
Definition mruby.c:34
static mrb_value mruby_pair_list_keys(mrb_state *mrb, mrb_value self)
Fetch the list of children of a list.
Definition mruby.c:189
static const struct mrb_data_type mruby_dict_attr_type
Definition mruby.c:91
struct mruby_pair_s mruby_pair_t
Definition mruby.c:28
static const struct mrb_data_type mruby_inst_type
Definition mruby.c:81
static mrb_value mruby_pair_value_to_ruby(mrb_state *mrb, request_t *request, fr_pair_t *vp)
Convert a pair value to a suitable mruby value type.
Definition mruby.c:209
static void mruby_ruby_to_pair_value(mrb_state *mrb, mrb_value *value, fr_pair_t *vp)
Convert a ruby value to a fr_pair_t value.
Definition mruby.c:322
mrb_value mruby_dict_attr_object(mrb_state *mrb, struct RClass *klass, fr_dict_attr_t const *da)
Definition mruby.c:119
static mrb_value mruby_request_control(mrb_state *mrb, mrb_value self)
Definition mruby.c:53
struct RClass * mruby_pair_list_class(mrb_state *mrb, struct RClass *parent)
Definition mruby.c:589
request_t * request
Current request.
Definition mruby.c:31
static mrb_value mruby_value_pair_set(mrb_state *mrb, mrb_value self)
Set a value pair from mruby.
Definition mruby.c:374
static void mruby_pair_parent_build(mrb_state *mrb, mruby_pair_t *pair)
Build parent structural pairs needed when a leaf node is set.
Definition mruby.c:303
struct RClass * mruby_pair_class(mrb_state *mrb, struct RClass *parent)
Definition mruby.c:603
static mrb_value mruby_pair_list_missing(mrb_state *mrb, mrb_value self)
Implement mruby method_missing functionality to find child pairs.
Definition mruby.c:473
mrb_value mruby_inst_object(mrb_state *mrb, struct RClass *klass, rlm_mruby_t const *inst)
Definition mruby.c:109
static mrb_value mruby_request_session_state(mrb_state *mrb, mrb_value self)
Definition mruby.c:58
fr_pair_t * vp
Real pair if it exists.
Definition mruby.c:33
static const struct mrb_data_type mruby_request_type
Definition mruby.c:86
static mrb_value mruby_request_frconfig(mrb_state *mrb, mrb_value self)
Definition mruby.c:38
fr_dict_attr_t const * da
Dictionary attribute for this pair.
Definition mruby.c:32
static mrb_value mruby_request_request(mrb_state *mrb, mrb_value self)
Definition mruby.c:43
static mrb_value mruby_ruby_pair_object(mrb_state *mrb, struct RClass *klass, mruby_pair_t *pair)
Definition mruby.c:129
unsigned int fr_pair_count_by_da(fr_pair_list_t const *list, fr_dict_attr_t const *da)
Return the number of instances of a given da in the specified list.
Definition pair.c:675
int fr_pair_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t (and append)
Definition pair.c:1462
fr_pair_t * fr_pair_find_by_da_idx(fr_pair_list_t const *list, fr_dict_attr_t const *da, unsigned int idx)
Find a pair with a matching da at a given index.
Definition pair.c:746
void fr_pair_value_clear(fr_pair_t *vp)
Free/zero out value (or children) of a given VP.
Definition pair.c:2536
int fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
Definition pair.c:1822
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG2(fmt,...)
Definition radclient.h:54
Translates requests between the server an an mruby interpreter.
struct RClass * mruby_pair_list
Definition rlm_mruby.h:53
struct RClass * mruby_pair
Definition rlm_mruby.h:54
struct RClass * mruby_ptr
Definition rlm_mruby.h:52
return count
Definition module.c:155
eap_aka_sim_process_conf_t * inst
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
Definition pair_inline.c:69
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition pair_inline.c:42
static fr_slen_t parent
Definition pair.h:841
#define fr_type_is_group(_x)
Definition types.h:377
@ FR_TYPE_ATTR
A contains an attribute reference.
Definition types.h:84
#define FR_TYPE_NON_LEAF
Definition types.h:319
#define fr_type_is_leaf(_x)
Definition types.h:394
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition types.h:455
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
Definition value.c:3744
void fr_value_box_bstrndup_shallow(fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Assign a string to to a fr_value_box_t.
Definition value.c:4687
static fr_slen_t fr_value_box_aprint(TALLOC_CTX *ctx, char **out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules) 1(fr_value_box_print
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
Definition value.h:609