The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
proto_detail.c
Go to the documentation of this file.
1 /*
2  * This program 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
5  * (at 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: 20e537c678922e935c0282347211e73d2b094d02 $
19  * @file proto_detail.c
20  * @brief Detail master protocol handler.
21  *
22  * @copyright 2017 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23  * @copyright 2016 Alan DeKok (aland@freeradius.org)
24  */
25 #include <freeradius-devel/io/application.h>
26 #include <freeradius-devel/io/listen.h>
27 #include <freeradius-devel/io/schedule.h>
28 #include <freeradius-devel/radius/radius.h>
29 #include <freeradius-devel/util/pair_legacy.h>
30 
31 #include <freeradius-devel/server/dl_module.h>
32 #include <freeradius-devel/server/module.h>
33 #include <freeradius-devel/server/module_rlm.h>
34 
35 #include "proto_detail.h"
36 
37 extern fr_app_t proto_detail;
38 
39 static int type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule);
40 static int transport_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule);
41 
42 #if 0
43 /*
44  * When we want detailed debugging here, without detailed server
45  * debugging.
46  */
47 #define MPRINT DEBUG
48 #else
49 #define MPRINT(x, ...)
50 #endif
51 
52 /** How to parse a Detail listen section
53  *
54  */
57  type), .func = type_parse },
58  { FR_CONF_OFFSET_TYPE_FLAGS("transport", FR_TYPE_VOID, 0, proto_detail_t, io_submodule),
59  .func = transport_parse, .dflt = "file" },
60 
61  /*
62  * Add this as a synonym so normal humans can understand it.
63  */
64  { FR_CONF_OFFSET("max_entry_size", proto_detail_t, max_packet_size) } ,
65 
66  /*
67  * For performance tweaking. NOT for normal humans.
68  */
69  { FR_CONF_OFFSET("max_packet_size", proto_detail_t, max_packet_size) } ,
70  { FR_CONF_OFFSET("num_messages", proto_detail_t, num_messages) } ,
71 
72  { FR_CONF_OFFSET("exit_when_done", proto_detail_t, exit_when_done) },
73 
74  { FR_CONF_OFFSET("priority", proto_detail_t, priority) },
75 
77 };
78 
79 static fr_dict_t const *dict_freeradius;
80 
83  { .out = &dict_freeradius, .proto = "freeradius" },
84 
85  { NULL }
86 };
87 
94 
97  { .out = &attr_packet_dst_ip_address, .name = "Net.Dst.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
98  { .out = &attr_packet_dst_port, .name = "Net.Dst.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
99  { .out = &attr_packet_original_timestamp, .name = "Packet-Original-Timestamp", .type = FR_TYPE_DATE, .dict = &dict_freeradius },
100  { .out = &attr_packet_src_ip_address, .name = "Net.Src.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
101  { .out = &attr_packet_src_port, .name = "Net.Src.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
102  { .out = &attr_protocol, .name = "Protocol", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
103 
104  { NULL }
105 };
106 
107 /** Translates the packet-type into a submodule name
108  *
109  * @param[in] ctx to allocate data in (instance of proto_detail).
110  * @param[out] out Where to write a module_instance_t containing the module handle and instance.
111  * @param[in] parent Base structure address.
112  * @param[in] ci #CONF_PAIR specifying the name of the type module.
113  * @param[in] rule unused.
114  * @return
115  * - 0 on success.
116  * - -1 on failure.
117  */
118 static int type_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
119 {
120  proto_detail_t *inst = talloc_get_type_abort(parent, proto_detail_t);
121  fr_dict_enum_value_t const *type_enum;
122  CONF_PAIR *cp = cf_item_to_pair(ci);
123  char const *value = cf_pair_value(cp);
124 
125  *((char const **) out) = value;
126 
128  if (!inst->dict) {
129  cf_log_err(ci, "Please define 'namespace' in this virtual server");
130  return -1;
131  }
132 
133  inst->attr_packet_type = fr_dict_attr_by_name(NULL, fr_dict_root(inst->dict), "Packet-Type");
134  if (!inst->attr_packet_type) {
135  cf_log_err(ci, "Failed to find 'Packet-Type' attribute");
136  return -1;
137  }
138 
139  if (!value) {
140  cf_log_err(ci, "No value given for 'type'");
141  return -1;
142  }
143 
144  type_enum = fr_dict_enum_by_name(inst->attr_packet_type, value, -1);
145  if (!type_enum) {
146  cf_log_err(ci, "Invalid type \"%s\"", value);
147  return -1;
148  }
149 
150  inst->code = type_enum->value->vb_uint32;
151  return 0;
152 }
153 
154 static int transport_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
155 {
156  proto_detail_t *inst = talloc_get_type_abort(parent, proto_detail_t);
157 
158  if (unlikely(virtual_server_listen_transport_parse(ctx, out, parent, ci, rule) < 0)) {
159  return -1;
160  }
161 
162  /*
163  * If we're not loading the work submodule directly, then try to load it here.
164  */
165  if (strcmp(inst->io_submodule->module->dl->name, "proto_detail_work") != 0) {
166  CONF_SECTION *transport_cs;
167  module_instance_t *mi;
168  char const *inst_name;
169 
170  inst->work_submodule = NULL;
171 
173  fr_assert(mi);
174 
175  transport_cs = cf_section_find(mi->conf, "work", NULL);
176  if (!transport_cs) {
177  transport_cs = cf_section_dup(mi->conf, mi->conf, inst->app_io_conf,
178  "work", NULL, false);
179  if (!transport_cs) {
180  cf_log_err(mi->conf, "Failed to create configuration for worker");
181  return -1;
182  }
183  }
184 
185  if (module_instance_name_from_conf(&inst_name, transport_cs) < 0) return -1;
186 
187  /*
188  * This *should* get bootstrapped at some point after this module
189  * as it's inserted into the three the caller is iterating over.
190  *
191  * We might want to revisit this, and use a linked list of modules
192  * to iterate over instead of a tree, so we can add this to the end
193  * of that list.
194  */
195  inst->work_submodule = module_instance_alloc(mi->ml, mi, DL_MODULE_TYPE_SUBMODULE,
196  "work", inst_name, 0);
197  if (inst->work_submodule == NULL) {
198  error:
199  cf_log_perr(mi->conf, "Failed to load proto_detail_work");
200  TALLOC_FREE(inst->work_submodule);
201  return -1;
202  }
203 
204  if (module_instance_conf_parse(inst->work_submodule, transport_cs) < 0) goto error;
205 
206  inst->work_io = (fr_app_io_t const *) inst->work_submodule->exported;
207  inst->work_io_instance = inst->work_submodule->data;
208  inst->work_io_conf = inst->work_submodule->conf;
209  }
210 
211  return 0;
212 }
213 
214 /** Decode the packet, and set the request->process function
215  *
216  */
217 static int mod_decode(void const *instance, request_t *request, uint8_t *const data, size_t data_len)
218 {
220  int num, lineno;
221  uint8_t const *p, *end;
222  fr_pair_t *vp;
223  fr_pair_list_t tmp_list;
224  fr_dcursor_t cursor;
225  time_t timestamp = 0;
226  fr_pair_parse_t root, relative;
227 
228  RHEXDUMP3(data, data_len, "proto_detail decode packet");
229 
230  request->dict = inst->dict;
231  request->packet->code = inst->code;
232 
233  /*
234  * Set default addresses
235  */
236  request->packet->socket.fd = -1;
237  request->packet->socket.inet.src_ipaddr.af = AF_INET;
238  request->packet->socket.inet.src_ipaddr.addr.v4.s_addr = htonl(INADDR_NONE);
239  request->packet->socket.inet.dst_ipaddr = request->packet->socket.inet.src_ipaddr;
240 
241  request->reply->socket.inet.src_ipaddr = request->packet->socket.inet.src_ipaddr;
242  request->reply->socket.inet.dst_ipaddr = request->packet->socket.inet.src_ipaddr;
243 
244  end = data + data_len;
245 
246  MPRINT("HEADER %s", data);
247 
248  if (sscanf((char const *) data, "%*s %*s %*d %*d:%*d:%*d %d", &num) != 1) {
249  REDEBUG("Malformed header '%s'", (char const *) data);
250  return -1;
251  }
252 
253  /*
254  * Skip the header
255  */
256  for (p = data; p < end; p++) {
257  if (!*p) break;
258  }
259 
260  lineno = 1;
261  fr_pair_dcursor_init(&cursor, &request->request_pairs);
262  fr_dcursor_tail(&cursor); /* Ensure we only free what we add on error */
263  fr_pair_list_init(&tmp_list);
264 
265  /*
266  * Parse each individual line.
267  */
268  while (p < end) {
269  /*
270  * Each record begins with a zero byte. If the
271  * next byte is also zero, that's the end of
272  * record indication.
273  */
274  if ((end - p) < 2) break;
275  if (!p[1]) break;
276 
277  /*
278  * Already checked in the "read" routine. But it
279  * doesn't hurt to re-check it here.
280  */
281  if ((*p != '\0') && (*p != '\t')) {
282  REDEBUG("Malformed line %d", lineno);
283  error:
284  fr_dcursor_free_list(&cursor);
285  return -1;
286  }
287 
288  p += 2;
289 
290  MPRINT("LINE :%s", p);
291 
292  /*
293  * Skip this for backwards compatibility.
294  */
295  if (strncasecmp((char const *) p, "Request-Authenticator", 21) == 0) goto next;
296 
297  /*
298  * The original time at which we received the
299  * packet. We need this to properly calculate
300  * Acct-Delay-Time.
301  */
302  if (strncasecmp((char const *) p, "Timestamp = ", 12) == 0) {
303  p += 12;
304 
305  timestamp = atoi((char const *) p);
306 
307  vp = fr_pair_afrom_da(request->request_ctx, attr_packet_original_timestamp);
308  if (vp) {
309  vp->vp_date = fr_unix_time_from_sec(timestamp);
310  fr_dcursor_append(&cursor, vp);
311  }
312  goto next;
313  }
314 
315  /*
316  * This should also have been caught.
317  */
318  if (strncasecmp((char const *) p, "Donestamp", 9) == 0) {
319  goto next;
320  }
321 
322  /*
323  * Ensure temporary list is empty before each use
324  */
325  fr_pair_list_free(&tmp_list);
326 
327  /*
328  * Reinitialize every time.
329  *
330  * @todo - maybe we want to keep "relative' around between lines?
331  * So that the detail file reader can read:
332  *
333  * foo = {}
334  * .bar = baz
335  *
336  * and get
337  *
338  * foo = { bar = baz }
339  *
340  * But doing that would require updating the
341  * detail file writer to track parent / child
342  * relationships, which we're not yet prepared to
343  * do.
344  *
345  * @todo - this also doesn't create nested attributes properly,
346  * as the write will write:
347  *
348  * foo.bar = baz
349  *
350  * and then the final pair "foo" is _appended_ to the input list, without paying
351  * any attention to what's going on!
352  *
353  * We likely just want to pass in request_pairs the parse function, AND also don't
354  * mash "relative" between calls.
355  */
356  root = (fr_pair_parse_t) {
357  .ctx = request->request_ctx,
358  .da = fr_dict_root(request->dict),
359  .list = &tmp_list,
360  };
361  relative = (fr_pair_parse_t) { };
362 
363  if ((fr_pair_list_afrom_substr(&root, &relative,
364  &FR_SBUFF_IN((char const *) p, (data + data_len) - p)) > 0) && !fr_pair_list_empty(&tmp_list)) {
365  vp = fr_pair_list_head(&tmp_list);
366  fr_pair_list_append(&request->request_pairs, &tmp_list);
367  } else {
368  vp = NULL;
369  RWDEBUG("Ignoring line %d - :%s", lineno, p);
370  }
371 
372  /*
373  * Set the original src/dst ip/port
374  */
375  if (vp) {
376  if (vp->da == attr_packet_src_ip_address) {
377  request->packet->socket.inet.src_ipaddr = vp->vp_ip;
378  } else if (vp->da == attr_packet_dst_ip_address) {
379  request->packet->socket.inet.dst_ipaddr = vp->vp_ip;
380  } else if (vp->da == attr_packet_src_port) {
381  request->packet->socket.inet.src_port = vp->vp_uint16;
382  } else if (vp->da == attr_packet_dst_port) {
383  request->packet->socket.inet.dst_port = vp->vp_uint16;
384  } else if (vp->da == attr_protocol) {
385  request->dict = fr_dict_by_protocol_num(vp->vp_uint32);
386  if (!request->dict) {
387  REDEBUG("Invalid protocol: %pP", vp);
388  goto error;
389  }
390  }
391  }
392 
393  next:
394  lineno++;
395  while ((p < end) && (*p)) p++;
396  }
397 
398  /*
399  * Let the app_io take care of populating additional fields in the request
400  */
401  return inst->app_io->decode(inst->app_io_instance, request, data, data_len);
402 }
403 
404 static ssize_t mod_encode(UNUSED void const *instance, request_t *request, uint8_t *buffer, size_t buffer_len)
405 {
406  if (buffer_len < 1) return -1;
407 
408  *buffer = request->reply->code;
409  return 1;
410 }
411 
412 static int mod_priority_set(void const *instance, UNUSED uint8_t const *buffer, UNUSED size_t buflen)
413 {
415 
416  /*
417  * Return the configured priority.
418  */
419  return inst->priority;
420 }
421 
422 
423 /** Open listen sockets/connect to external event source
424  *
425  * @param[in] instance Ctx data for this application.
426  * @param[in] sc to add our file descriptor to.
427  * @param[in] conf Listen section parsed to give us instance.
428  * @return
429  * - 0 on success.
430  * - -1 on failure.
431  */
432 static int mod_open(void *instance, fr_schedule_t *sc, CONF_SECTION *conf)
433 {
434  fr_listen_t *li;
435  proto_detail_t *inst = talloc_get_type_abort(instance, proto_detail_t);
436 
437  /*
438  * Build the #fr_listen_t. This describes the complete
439  * path, data takes from the socket to the decoder and
440  * back again.
441  */
442  MEM(li = talloc_zero(inst, fr_listen_t)); /* Assigned thread steals the memory */
443  talloc_set_destructor(li, fr_io_listen_free);
444 
445  li->app_io = inst->app_io;
446  li->thread_instance = talloc_zero_array(li, uint8_t, li->app_io->common.thread_inst_size);
447  talloc_set_name(li->thread_instance, "proto_%s_thread_t", inst->app_io->common.name);
448  li->app_io_instance = inst->app_io_instance;
449 
450  li->app = &proto_detail;
451  li->app_instance = instance;
452  li->server_cs = inst->server_cs;
453 
454  /*
455  * Set configurable parameters for message ring buffer.
456  */
457  li->default_message_size = inst->max_packet_size;
458  li->num_messages = inst->num_messages;
459 
460  /*
461  * Open the file.
462  */
463  if (inst->app_io->open(li) < 0) {
464  cf_log_err(conf, "Failed opening %s file", inst->app_io->common.name);
465  talloc_free(li);
466  return -1;
467  }
468 
469  fr_assert(li->app_io->get_name);
470  li->name = li->app_io->get_name(li);
471 
472  /*
473  * Testing: allow it to read a "detail.work" file
474  * directly.
475  */
476  if (strcmp(inst->io_submodule->module->dl->name, "proto_detail_work") == 0) {
477  if (!fr_schedule_listen_add(sc, li)) {
478  talloc_free(li);
479  return -1;
480  }
481 
482  inst->listen = li;
483  return 0;
484  }
485 
486  if (li->non_socket_listener) {
487  /*
488  * Add listener. Will insert polling timer.
489  */
490  if (!fr_schedule_listen_add(sc, li)) {
491  talloc_free(li);
492  return -1;
493  }
494  } else {
495  /*
496  * Watch the directory for changes.
497  */
498  if (!fr_schedule_directory_add(sc, li)) {
499  talloc_free(li);
500  return -1;
501  }
502  }
503 
504  DEBUG("Listening on %s bound to virtual server %s",
505  li->name, cf_section_name2(li->server_cs));
506 
507  inst->listen = li; /* Probably won't need it, but doesn't hurt */
508  inst->sc = sc;
509 
510  return 0;
511 }
512 
513 
514 /** Instantiate the application
515  *
516  * Instantiate I/O and type submodules.
517  *
518  * @return
519  * - 0 on success.
520  * - -1 on failure.
521  */
522 static int mod_instantiate(module_inst_ctx_t const *mctx)
523 {
524  proto_detail_t *inst = talloc_get_type_abort(mctx->mi->data, proto_detail_t);
525  CONF_SECTION *conf = mctx->mi->conf;
526 
527  /*
528  * The listener is inside of a virtual server.
529  */
530  inst->server_cs = cf_item_to_section(cf_parent(conf));
531  inst->self = &proto_detail;
532 
533  /*
534  * No IO module, it's an empty listener. That's not
535  * allowed for the detail file reader.
536  */
537  if (!inst->io_submodule) {
538  cf_log_err(conf, "Virtual server for detail files requires a 'transport' configuration");
539  return -1;
540  }
541 
542  /*
543  * Bootstrap the I/O module
544  */
545  inst->app_io = (fr_app_io_t const *) inst->io_submodule->exported;
546  inst->app_io_instance = inst->io_submodule->data;
547  inst->app_io_conf = inst->io_submodule->conf;
548 
549  /*
550  * These configuration items are not printed by default,
551  * because normal people shouldn't be touching them.
552  */
553  if (!inst->max_packet_size) inst->max_packet_size = inst->app_io->default_message_size;
554 
555  if (!inst->num_messages) inst->num_messages = 2;
556 
557  FR_INTEGER_BOUND_CHECK("num_messages", inst->num_messages, >=, 2);
558  FR_INTEGER_BOUND_CHECK("num_messages", inst->num_messages, <=, 65535);
559 
560  FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, >=, 1024);
561  FR_INTEGER_BOUND_CHECK("max_packet_size", inst->max_packet_size, <=, 65536);
562 
563  if (!inst->priority) inst->priority = PRIORITY_NORMAL;
564 
565  return 0;
566 }
567 
569  .common = {
570  .magic = MODULE_MAGIC_INIT,
571  .name = "detail",
572  .config = proto_detail_config,
573  .inst_size = sizeof(proto_detail_t),
574 
576  },
577  .open = mod_open,
578  .decode = mod_decode,
579  .encode = mod_encode,
580  .priority = mod_priority_set
581 };
static int const char char buffer[256]
Definition: acutest.h:574
module_t common
Common fields to all loadable modules.
Definition: app_io.h:34
fr_io_name_t get_name
get the socket name
Definition: app_io.h:70
Public structure describing an I/O path for a protocol.
Definition: app_io.h:33
module_t common
Common fields provided by all modules.
Definition: application.h:72
Describes a new application (protocol)
Definition: application.h:71
#define unlikely(_x)
Definition: build.h:379
#define UNUSED
Definition: build.h:313
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#define FR_INTEGER_BOUND_CHECK(_name, _var, _op, _bound)
Definition: cf_parse.h:487
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: cf_parse.h:405
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
Definition: cf_parse.h:420
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:241
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:564
Common header for all CONF_* types.
Definition: cf_priv.h:49
Configuration AVP similar to a fr_pair_t.
Definition: cf_priv.h:70
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:101
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition: cf_util.c:664
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition: cf_util.c:1028
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition: cf_util.c:1185
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition: cf_util.c:1594
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
Definition: cf_util.c:684
CONF_SECTION * cf_section_dup(TALLOC_CTX *ctx, CONF_SECTION *parent, CONF_SECTION const *cs, char const *name1, char const *name2, bool copy_meta)
Duplicate a configuration section.
Definition: cf_util.c:928
#define cf_log_err(_cf, _fmt,...)
Definition: cf_util.h:289
#define cf_parent(_cf)
Definition: cf_util.h:101
#define cf_log_perr(_cf, _fmt,...)
Definition: cf_util.h:296
#define PRIORITY_NORMAL
Definition: channel.h:151
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition: dcursor.h:406
static void * fr_dcursor_tail(fr_dcursor_t *cursor)
Wind cursor to the tail item in the list.
Definition: dcursor.h:259
next
Definition: dcursor.h:178
static void fr_dcursor_free_list(fr_dcursor_t *cursor)
Free the current item and all items after it.
Definition: dcursor.h:663
#define DEBUG(fmt,...)
Definition: dhcpclient.c:39
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:3263
fr_dict_t const * fr_dict_by_protocol_num(unsigned int num)
Lookup a protocol by its number.
Definition: dict_util.c:2590
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:267
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:280
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition: dict_util.c:2400
fr_value_box_t const * value
Enum value (what name maps to).
Definition: dict.h:230
fr_dict_enum_value_t * fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, ssize_t len)
Definition: dict_util.c:3395
Specifies an attribute which must be present for the module to function.
Definition: dict.h:266
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:279
Value of an enumerated attribute.
Definition: dict.h:226
Test enumeration values.
Definition: dict_test.h:92
@ DL_MODULE_TYPE_SUBMODULE
Driver (or method in the case of EAP)
Definition: dl_module.h:69
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:63
if(rcode > 0)
Definition: fd_read.h:9
size_t num_messages
for the message ring buffer
Definition: listen.h:52
bool non_socket_listener
special internal listener that does not use sockets.
Definition: listen.h:45
char const * name
printable name for this socket - set by open
Definition: listen.h:29
void const * app_instance
Definition: listen.h:38
size_t default_message_size
copied from app_io, but may be changed
Definition: listen.h:51
fr_app_t const * app
Definition: listen.h:37
void const * app_io_instance
I/O path configuration context.
Definition: listen.h:32
int fr_io_listen_free(fr_listen_t *li)
Definition: master.c:2923
CONF_SECTION * server_cs
CONF_SECTION of the server.
Definition: listen.h:40
void * thread_instance
thread / socket context
Definition: listen.h:33
fr_app_io_t const * app_io
I/O path functions.
Definition: listen.h:31
#define RWDEBUG(fmt,...)
Definition: log.h:361
#define RHEXDUMP3(_data, _len, _fmt,...)
Definition: log.h:705
talloc_free(reap)
@ FR_TYPE_UINT16
16 Bit unsigned integer.
Definition: merged_model.c:98
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
Definition: merged_model.c:111
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
Definition: merged_model.c:91
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
int strncasecmp(char *s1, char *s2, int n)
Definition: missing.c:36
module_instance_t * mi
Instance of the module being instantiated.
Definition: module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition: module_ctx.h:50
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition: pair.c:283
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition: pair.c:46
fr_slen_t fr_pair_list_afrom_substr(fr_pair_parse_t const *root, fr_pair_parse_t *relative, fr_sbuff_t *in)
Parse a fr_pair_list_t from a substring.
Definition: pair_legacy.c:150
struct fr_pair_parse_s fr_pair_parse_t
TALLOC_CTX * ctx
Definition: pair_legacy.h:43
static ssize_t mod_encode(UNUSED void const *instance, request_t *request, uint8_t *buffer, size_t buffer_len)
Definition: proto_detail.c:404
static fr_dict_attr_t const * attr_protocol
Definition: proto_detail.c:93
fr_app_t proto_detail
Definition: proto_detail.c:568
static int type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
static int mod_open(void *instance, fr_schedule_t *sc, CONF_SECTION *conf)
Open listen sockets/connect to external event source.
Definition: proto_detail.c:432
static fr_dict_attr_t const * attr_packet_src_port
Definition: proto_detail.c:92
static fr_dict_t const * dict_freeradius
Definition: proto_detail.c:79
#define MPRINT(x,...)
Definition: proto_detail.c:49
static int mod_decode(void const *instance, request_t *request, uint8_t *const data, size_t data_len)
Decode the packet, and set the request->process function.
Definition: proto_detail.c:217
static fr_dict_attr_t const * attr_packet_original_timestamp
Definition: proto_detail.c:90
static int mod_priority_set(void const *instance, UNUSED uint8_t const *buffer, UNUSED size_t buflen)
Definition: proto_detail.c:412
fr_dict_attr_autoload_t proto_detail_dict_attr[]
Definition: proto_detail.c:96
fr_dict_autoload_t proto_detail_dict[]
Definition: proto_detail.c:82
static int transport_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Definition: proto_detail.c:154
static fr_dict_attr_t const * attr_packet_dst_ip_address
Definition: proto_detail.c:88
static int mod_instantiate(module_inst_ctx_t const *mctx)
Instantiate the application.
Definition: proto_detail.c:522
static fr_dict_attr_t const * attr_packet_src_ip_address
Definition: proto_detail.c:91
static fr_dict_attr_t const * attr_packet_dst_port
Definition: proto_detail.c:89
static conf_parser_t const proto_detail_config[]
How to parse a Detail listen section.
Definition: proto_detail.c:55
Detail master protocol handler.
#define REDEBUG(fmt,...)
Definition: radclient.h:52
static rs_t * conf
Definition: radsniff.c:53
static int instantiate(module_inst_ctx_t const *mctx)
Definition: rlm_rest.c:1302
#define FR_SBUFF_IN(_start, _len_or_end)
fr_network_t * fr_schedule_directory_add(fr_schedule_t *sc, fr_listen_t *li)
Add a directory NOTE_EXTEND to a scheduler.
Definition: schedule.c:913
fr_network_t * fr_schedule_listen_add(fr_schedule_t *sc, fr_listen_t *li)
Add a fr_listen_t to a scheduler.
Definition: schedule.c:881
The scheduler.
Definition: schedule.c:125
CONF_SECTION * conf
Module's instance configuration.
Definition: module.h:329
void * data
Module's instance data.
Definition: module.h:271
module_list_t * ml
Module list this instance belongs to.
Definition: module.h:309
size_t thread_inst_size
Size of the module's thread-specific instance data.
Definition: module.h:235
Module instance data.
Definition: module.h:265
static const uchar sc[16]
Definition: smbdes.c:115
fr_slen_t module_instance_name_from_conf(char const **name, CONF_SECTION *conf)
Avoid boilerplate when setting the module instance name.
Definition: module.c:735
int module_instance_conf_parse(module_instance_t *mi, CONF_SECTION *conf)
Covert a CONF_SECTION into parsed module instance data.
Definition: module.c:764
module_instance_t * module_instance_alloc(module_list_t *ml, module_instance_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name, module_instance_state_t init_state)
Allocate a new module and add it to a module list for later bootstrap/instantiation.
Definition: module.c:1651
fr_assert(0)
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
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
#define talloc_get_type_abort_const
Definition: talloc.h:282
static fr_unix_time_t fr_unix_time_from_sec(int64_t sec)
Definition: time.h:449
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition: pair_inline.c:43
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
Definition: pair_inline.c:125
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
Definition: pair_inline.c:113
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
Definition: pair_inline.c:182
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition: pair.h:591
static fr_slen_t parent
Definition: pair.h:851
static fr_slen_t data
Definition: value.h:1265
static size_t char ** out
Definition: value.h:997
fr_dict_t const * virtual_server_dict_by_child_ci(CONF_ITEM const *ci)
Return the namespace for a given virtual server specified by a CONF_ITEM within the virtual server.
int virtual_server_listen_transport_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic conf_parser_t func for loading drivers.
module_instance_t * virtual_server_listener_by_data(void const *data)
Resolve proto data to a module instance.