The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_logtee.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: 6a7a18bbb4ad9080ca465d0e907822a65f16e79b $
19 * @file rlm_logtee.c
20 * @brief Add an additional log destination for any given request.
21 *
22 * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23 *
24 * @copyright 2017 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25 */
26RCSID("$Id: 6a7a18bbb4ad9080ca465d0e907822a65f16e79b $")
27
28#include <freeradius-devel/server/base.h>
29#include <freeradius-devel/server/module_rlm.h>
30#include <freeradius-devel/util/debug.h>
31
32#ifdef HAVE_FCNTL_H
33# include <fcntl.h>
34#endif
35
36#ifdef HAVE_UNISTD_H
37#endif
38
39#ifdef HAVE_GRP_H
40# include <grp.h>
41#endif
42
43#ifdef HAVE_SYSLOG_H
44# include <syslog.h>
45# ifndef LOG_INFO
46# define LOG_INFO (0)
47# endif
48#endif
49
50#include <sys/uio.h>
51
52typedef enum {
54 LOGTEE_DST_FILE, //!< Log to a file.
55 LOGTEE_DST_UNIX, //!< Log via Unix socket.
56 LOGTEE_DST_UDP, //!< Log via UDP.
57 LOGTEE_DST_TCP, //!< Log via TCP.
59
61 { L("file"), LOGTEE_DST_FILE },
62 { L("tcp"), LOGTEE_DST_TCP },
63 { L("udp"), LOGTEE_DST_UDP },
64 { L("unix"), LOGTEE_DST_UNIX }
65};
67
68typedef struct {
69 fr_ipaddr_t dst_ipaddr; //!< Network server.
70 fr_ipaddr_t src_ipaddr; //!< Send requests from a given src_ipaddr.
71 uint16_t port; //!< Network port.
73
74/** logtee module instance
75 */
76typedef struct {
77 char const *name; //!< Module instance name.
78
79 char const *delimiter; //!< Line termination string (usually \n).
80 size_t delimiter_len; //!< Length of line termination string.
81
82 tmpl_t *log_fmt; //!< Source of log messages.
83
84 logtee_dst_t log_dst; //!< Logging destination.
85 char const *log_dst_str; //!< Logging destination string.
86
87 size_t buffer_depth; //!< How big our circular buffer should be.
88
89 struct {
90 char const *name; //!< File to write to.
91 uint32_t permissions; //!< Permissions to use when creating new files.
92 char const *group_str; //!< Group to set on new files.
93 gid_t group; //!< Resolved gid.
95
96 struct {
97 char const *path; //!< Where the UNIX socket lives.
98 } unix_sock; // Lowercase unix is a macro on some systems?!
99
100 logtee_net_t tcp; //!< TCP server.
101 logtee_net_t udp; //!< UDP server.
102
103 fr_time_delta_t connection_timeout; //!< How long to wait to open a socket.
104 fr_time_delta_t reconnection_delay; //!< How long to wait to retry.
106
107/** Per-thread instance data
108 *
109 * Contains buffers and connection handles specific to the thread.
110 */
111typedef struct {
112 rlm_logtee_t const *inst; //!< Instance of logtee.
113 fr_event_list_t *el; //!< This thread's event list.
114 connection_t *conn; //!< Connection to our log destination.
115
116 fr_fring_t *fring; //!< Circular buffer used to batch up messages.
117
118 bool pending; //!< We have pending messages to write.
119
120 TALLOC_CTX *msg_pool; //!< A 1k talloc pool to hold the log message whilst
121 //!< it's being expanded.
122 fr_pair_t *msg; //!< Temporary value pair holding the message value.
123 fr_pair_t *type; //!< Temporary value pair holding the message type.
124 fr_pair_t *lvl; //!< Temporary value pair holding the log lvl.
126
127
128static const conf_parser_t file_config[] = {
130 { FR_CONF_OFFSET("permissions", rlm_logtee_t, file.permissions), .dflt = "0600" },
131 { FR_CONF_OFFSET("group", rlm_logtee_t, file.group_str) },
133};
134
135static const conf_parser_t unix_config[] = {
136 { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_FILE_READABLE, rlm_logtee_t, unix_sock.path) },
138};
139
140static const conf_parser_t udp_config[] = {
141 { FR_CONF_OFFSET_TYPE_FLAGS("server", FR_TYPE_COMBO_IP_ADDR, 0, logtee_net_t, dst_ipaddr) },
142 { FR_CONF_OFFSET("port", logtee_net_t, port) },
144};
145
146static const conf_parser_t tcp_config[] = {
147 { FR_CONF_OFFSET_TYPE_FLAGS("server", FR_TYPE_COMBO_IP_ADDR, 0, logtee_net_t, dst_ipaddr) },
148 { FR_CONF_OFFSET("port", logtee_net_t, port) },
149
151};
152
153static const conf_parser_t module_config[] = {
154 { FR_CONF_OFFSET_FLAGS("destination", CONF_FLAG_REQUIRED, rlm_logtee_t, log_dst_str) },
155 { FR_CONF_OFFSET_TYPE_FLAGS("buffer_depth", FR_TYPE_SIZE, 0, rlm_logtee_t, buffer_depth), .dflt = "10000" },
156
157 { FR_CONF_OFFSET("delimiter", rlm_logtee_t, delimiter), .dflt = "\n" },
158 { FR_CONF_OFFSET("format", rlm_logtee_t, log_fmt), .dflt = "%n - %s", .quote = T_DOUBLE_QUOTED_STRING },
159
160 /*
161 * Log destinations
162 */
163 { FR_CONF_POINTER("file", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) file_config },
164 { FR_CONF_POINTER("unix", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) unix_config },
167
168 { FR_CONF_OFFSET("connection_timeout", rlm_logtee_t, connection_timeout), .dflt = "1.0" },
169 { FR_CONF_OFFSET("reconnection_delay", rlm_logtee_t, reconnection_delay), .dflt = "1.0" },
170
172};
173
175
178 { .out = &dict_freeradius, .proto = "freeradius" },
180};
181
185
188 { .out = &attr_log_level, .name = "Log-Level", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
189 { .out = &attr_log_message, .name = "Log-Message", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
190 { .out = &attr_log_type, .name = "Log-Type", .type = FR_TYPE_UINT32, .dict = &dict_freeradius },
192};
193
194static void logtee_fd_idle(rlm_logtee_thread_t *t);
195
197
199 char const *file, int line,
200 char const *fmt, va_list ap, void *uctx)
201 CC_HINT(format (printf, 6, 0)) CC_HINT(nonnull (3, 6));
202
203static unlang_action_t mod_insert_logtee(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request) CC_HINT(nonnull);
204
205/** Connection errored
206 *
207 */
208static void _logtee_conn_error(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, int fd_errno, void *uctx)
209{
210 rlm_logtee_thread_t *t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
211
212 if (fd_errno) ERROR("Connection failed (%i): %s", sock, fr_syserror(fd_errno));
213
214 /*
215 * Something bad happened... Fix it...
216 */
218}
219
220/** Drain any data we received
221 *
222 * We don't care about this data, we just don't want the kernel to
223 * signal the other side that our read buffer's full.
224 */
225static void _logtee_conn_read(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, void *uctx)
226{
227 rlm_logtee_thread_t *t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
228 ssize_t slen;
229 uint8_t buffer[1024];
230
231 slen = read(sock, buffer, sizeof(buffer));
232 if (slen < 0) {
233 switch (errno) {
234 case EAGAIN: /* We drained all the data */
235 case EINTR:
236 return;
237
238 case ECONNRESET: /* Connection was reset */
239 case ETIMEDOUT:
240 case EIO:
241 case ENXIO:
243 return;
244
245 /*
246 * Shouldn't be any other errors
247 * If there are, investigate why we get them...
248 */
249 default:
250 fr_assert(0);
251 }
252 }
253}
254
255/** There's space available to write data, so do that...
256 *
257 */
258static void _logtee_conn_writable(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, void *uctx)
259{
260 rlm_logtee_thread_t *t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
261 char *msg;
262
263 /*
264 * Fixme in general...
265 */
266 while ((msg = fr_fring_next(t->fring))) {
267 ssize_t slen;
268
269 slen = write(sock, msg, talloc_strlen(msg)) ;
270 write_error:
271 if (slen < 0) {
272 switch (errno) {
273 case EAGAIN:
274#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
275 case EWOULDBLOCK:
276#endif
277 case EINTR:
278 case ENOBUFS:
279 return;
280
281 case ECONNRESET:
282 case EDESTADDRREQ:
283 case EIO:
284 case ENXIO:
285 case EPIPE:
286 case ENETDOWN:
288 return;
289
290 /*
291 * Shouldn't be any other errors
292 * If there are, investigate why we get them...
293 */
294 default:
295 fr_assert(0);
296 }
297 }
298
299 slen = write(sock, t->inst->delimiter, t->inst->delimiter_len);
300 if (slen < 0) goto write_error;
301 }
302
304}
305
306/** Set the socket to idle
307 *
308 * If the other side is sending back garbage, we want to drain it so our buffer doesn't fill up.
309 *
310 * @param[in] t Thread instance containing the connection.
311 */
313{
314 int fd = *((int *)t->conn->h);
315
316 DEBUG3("Marking socket (%i) as idle", fd);
317 if (fr_event_fd_insert(t->conn, NULL, t->el, fd,
319 NULL,
321 t) < 0) {
322 PERROR("Failed inserting FD event");
323 }
324}
325
326/** Set the socket to active
327 *
328 * We have messages we want to send, so need to know when the socket is writable.
329 *
330 * @param[in] t Thread instance containing the connection.
331 */
333{
334 int fd = *((int *)t->conn->h);
335
336 DEBUG3("Marking socket (%i) as active - Draining requests", fd);
337 if (fr_event_fd_insert(t->conn, NULL, t->el, fd,
341 t) < 0) {
342 PERROR("Failed inserting FD event");
343 }
344}
345
346/** Shutdown/close a file descriptor
347 *
348 */
349static void _logtee_conn_close(UNUSED fr_event_list_t *el, void *h, UNUSED void *uctx)
350{
351 int fd = *((int *)h);
352
353 DEBUG3("Closing socket (%i)", fd);
354 if (shutdown(fd, SHUT_RDWR) < 0) DEBUG3("Shutdown on socket (%i) failed: %s", fd, fr_syserror(errno));
355 if (close(fd) < 0) DEBUG3("Closing socket (%i) failed: %s", fd, fr_syserror(errno));
356}
357
358/** Process notification that fd is open
359 *
360 */
362{
363 rlm_logtee_thread_t *t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
364
365 DEBUG2("Socket connected");
366
367 /*
368 * If we have data pending, add the writable event immediately
369 */
370 if (t->pending) {
372 } else {
374 }
375
377}
378
379/** Initialise a new outbound connection
380 *
381 * @param[out] h_out Where to write the new file descriptor.
382 * @param[in] conn being initialised.
383 * @param[in] uctx A #rlm_logtee_thread_t.
384 */
385CC_NO_UBSAN(function) /* UBSAN: false positive - public vs private connection_t trips --fsanitize=function*/
386static connection_state_t _logtee_conn_init(void **h_out, connection_t *conn, void *uctx)
387{
388 rlm_logtee_thread_t *t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
389 rlm_logtee_t const *inst = t->inst;
390 int fd = -1;
391 int *fd_s;
392
393 switch (inst->log_dst) {
394 case LOGTEE_DST_UNIX:
395 DEBUG2("Opening UNIX socket at \"%s\"", inst->unix_sock.path);
396 fd = fr_socket_client_unix(inst->unix_sock.path, true);
397 if (fd < 0) return CONNECTION_STATE_FAILED;
398 break;
399
400 case LOGTEE_DST_TCP:
401 DEBUG2("Opening TCP connection to %pV:%u",
402 fr_box_ipaddr(inst->tcp.dst_ipaddr), inst->tcp.port);
403 fd = fr_socket_client_tcp(NULL, NULL, &inst->tcp.dst_ipaddr, inst->tcp.port, true);
404 if (fd < 0) return CONNECTION_STATE_FAILED;
405 break;
406
407 case LOGTEE_DST_UDP:
408 DEBUG2("Opening UDP connection to %pV:%u",
409 fr_box_ipaddr(inst->udp.dst_ipaddr), inst->udp.port);
410 fd = fr_socket_client_udp(NULL, NULL, NULL, &inst->udp.dst_ipaddr, inst->udp.port, true);
411 if (fd < 0) return CONNECTION_STATE_FAILED;
412 break;
413
414 /*
415 * Are not connection oriented destinations
416 */
418 case LOGTEE_DST_FILE:
419 fr_assert(0);
421 }
422
423 /*
424 * Avoid pointer/integer assignments
425 */
426 MEM(fd_s = talloc(conn, int));
427 *fd_s = fd;
428 *h_out = fd_s;
429
430 connection_signal_on_fd(conn, fd);
431
433}
434
435/** Logging callback to write log messages to a destination
436 *
437 * This allows the logging destination to be customised on a per request basis.
438 *
439 * @note Function does not write log output immediately
440 *
441 * @param[in] type What type of message this is (error, warn, info, debug).
442 * @param[in] lvl At what logging level this message should be output.
443 * @param[in] request The current request.
444 * @param[in] file src file the log message was generated in.
445 * @param[in] line number the log message was generated on.
446 * @param[in] fmt sprintf style fmt string.
447 * @param[in] ap Arguments for the fmt string.
448 * @param[in] uctx Context data for the log function.
449 */
451 UNUSED char const *file, UNUSED int line,
452 char const *fmt, va_list ap, void *uctx)
453{
454 rlm_logtee_thread_t *t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);
455 rlm_logtee_t const *inst = t->inst;
456 char *msg, *exp;
457 fr_dcursor_t cursor;
458 fr_pair_t *vp;
459 log_dst_t *dst;
460
461 fr_assert(t->msg->vp_length == 0); /* Should have been cleared before returning */
462
463 /*
464 * None of this should involve mallocs unless msg > 1k
465 */
468
469 t->type->vp_uint32 = (uint32_t) type;
470 t->lvl->vp_uint32 = (uint32_t) lvl;
471
472 fr_pair_dcursor_init(&cursor, &request->request_pairs);
473 fr_dcursor_prepend(&cursor, t->msg);
474 fr_dcursor_prepend(&cursor, t->type);
475 fr_dcursor_prepend(&cursor, t->lvl);
476 fr_dcursor_head(&cursor);
477
478 /*
479 * Now expand our fmt string to encapsulate the
480 * message and any metadata
481 *
482 * Fixme: Would be better to call tmpl_expand
483 * into a variable length ring buffer.
484 */
485 dst = request->log.dst;
486 request->log.dst = NULL;
487 if (tmpl_aexpand(t, &exp, request, inst->log_fmt, NULL, NULL) < 0) goto finish;
488 request->log.dst = dst;
489
490 fr_fring_overwrite(t->fring, exp); /* Insert it into the buffer */
491
492 if (!t->pending) {
493 t->pending = true;
494 logtee_fd_active(t); /* Listen for when the fd is writable */
495 }
496
497finish:
498 /*
499 * Don't free, we reuse the fr_pair_ts for the next message
500 */
501 vp = fr_dcursor_remove(&cursor);
502 if (!fr_cond_assert(vp == t->lvl)) fr_dcursor_append(&cursor, vp);
503
504 vp = fr_dcursor_remove(&cursor);
505 if (!fr_cond_assert(vp == t->type)) fr_dcursor_append(&cursor, vp);
506
507 vp = fr_dcursor_remove(&cursor);
508 if (!fr_cond_assert(vp == t->msg)) fr_dcursor_append(&cursor, vp);
509
510 fr_value_box_clear(&t->msg->data); /* Clear message data */
511}
512
513/** Add our logging destination to the linked list of logging destinations (if it doesn't already exist)
514 *
515 * @param[in] p_result the result of the module call:
516 * - #RLM_MODULE_NOOP if log destination already exists.
517 * - #RLM_MODULE_OK if we added a new destination.
518 * @param[in] mctx Module calling ctx.
519 * @param[in] request request to add our log destination to.
520 */
522{
523 log_dst_t *dst, **last = NULL;
524
525 for (dst = request->log.dst; dst; dst = dst->next) {
526 if (dst->uctx == mctx->thread) {
528 }
529
530 last = &(dst->next);
531 }
532
533 if (!last) RETURN_UNLANG_NOOP;
534
535 dst = talloc_zero(request, log_dst_t);
536 dst->func = logtee_it;
537 dst->uctx = mctx->thread;
538
539 *last = dst;
540
542}
543
544/** Create thread-specific connections and buffers
545 *
546 * @param[in] mctx specific data.
547 * @return
548 * - 0 on success.
549 * - -1 on failure.
550 */
552{
553 rlm_logtee_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_logtee_t);
554 rlm_logtee_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_logtee_thread_t);
555
556 MEM(t->fring = fr_fring_alloc(t, inst->buffer_depth, false));
557
558 t->inst = inst;
559 t->el = mctx->el;
560
561 /*
562 * Pre-allocate temporary attributes
563 */
564 MEM(t->msg_pool = talloc_pool(t, 1024));
568
569 /*
570 * This opens the outbound connection
571 */
572 t->conn = connection_alloc(t, t->el,
574 .init = _logtee_conn_init,
575 .open = _logtee_conn_open,
576 .close = _logtee_conn_close
577 },
579 .connection_timeout = inst->connection_timeout,
580 .reconnection_delay = inst->reconnection_delay
581 },
582 inst->name, t);
583 if (t->conn == NULL) return -1;
584
586
587 return 0;
588}
589
590/*
591 * Instantiate the module.
592 */
593static int mod_instantiate(module_inst_ctx_t const *mctx)
594{
595 rlm_logtee_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_logtee_t);
596 CONF_SECTION *conf = mctx->mi->conf;
597 char prefix[100];
598
600 if (inst->log_dst == LOGTEE_DST_INVALID) {
601 cf_log_err(conf, "Invalid log destination \"%s\"", inst->log_dst_str);
602 return -1;
603 }
604
605 snprintf(prefix, sizeof(prefix), "rlm_logtee (%s)", inst->name);
606
607 FR_SIZE_BOUND_CHECK("buffer_depth", inst->buffer_depth, >=, (size_t)1);
608 FR_SIZE_BOUND_CHECK("buffer_depth", inst->buffer_depth, <=, (size_t)1000000); /* 1 Million messages */
609
610 /*
611 * Setup the logging destination
612 */
613 switch (inst->log_dst) {
614 case LOGTEE_DST_FILE:
615 cf_log_err(conf, "Teeing to files NYI");
616 return -1;
617
618 case LOGTEE_DST_UNIX:
619#ifndef HAVE_SYS_UN_H
620 cf_log_err(conf, "Unix sockets are not supported on this system");
621 return -1;
622#endif
623
624 case LOGTEE_DST_UDP:
625 break;
626
627 case LOGTEE_DST_TCP:
628 break;
629
631 fr_assert(0);
632 break;
633 }
634
635 inst->delimiter_len = talloc_strlen(inst->delimiter);
636
637 return 0;
638}
639
640
641/*
642 * Externally visible module definition.
643 */
646 .common = {
647 .magic = MODULE_MAGIC_INIT,
648 .name = "logtee",
649 .inst_size = sizeof(rlm_logtee_t),
650 .thread_inst_size = sizeof(rlm_logtee_thread_t),
651 .config = module_config,
652 .instantiate = mod_instantiate,
653 .thread_instantiate = mod_thread_instantiate,
654 },
655 .method_group = {
656 .bindings = (module_method_binding_t[]){
657 { .section = SECTION_NAME(CF_IDENT_ANY, CF_IDENT_ANY), .method = mod_insert_logtee },
659 }
660 }
661};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
static int const char char buffer[256]
Definition acutest.h:576
int const char * file
Definition acutest.h:702
log_entry msg
Definition acutest.h:794
static int const char * fmt
Definition acutest.h:573
int const char int line
Definition acutest.h:702
#define RCSID(id)
Definition build.h:488
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:210
#define CC_NO_UBSAN(_sanitize)
Definition build.h:431
#define UNUSED
Definition build.h:318
#define NUM_ELEMENTS(_t)
Definition build.h:340
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
#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:280
#define FR_SIZE_BOUND_CHECK(_name, _var, _op, _bound)
Definition cf_parse.h:507
fr_token_t quote
Quoting around the default value. Only used for templates.
Definition cf_parse.h:649
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition cf_parse.h:334
#define FR_CONF_OFFSET_FLAGS(_name, _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:268
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition cf_parse.h:309
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition cf_parse.h:429
@ CONF_FLAG_XLAT
string will be dynamically expanded.
Definition cf_parse.h:443
@ CONF_FLAG_FILE_READABLE
File matching value must exist, and must be readable.
Definition cf_parse.h:435
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition cf_parse.h:423
@ CONF_FLAG_FILE_WRITABLE
File matching value must exist, and must be writable.
Definition cf_parse.h:437
#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:238
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define CF_IDENT_ANY
Definition cf_util.h:75
connection_state_t
Definition connection.h:47
@ CONNECTION_STATE_FAILED
Connection has failed.
Definition connection.h:56
@ CONNECTION_STATE_CONNECTED
File descriptor is open (ready for writing).
Definition connection.h:54
@ CONNECTION_STATE_CONNECTING
Waiting for connection to establish.
Definition connection.h:52
@ CONNECTION_FAILED
Connection is being reconnected because it failed.
Definition connection.h:85
Holds a complete set of functions for a connection.
Definition connection.h:195
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_remove(fr_dcursor_t *cursor)
Remove the current item.
Definition dcursor.h:480
static void * fr_dcursor_head(fr_dcursor_t *cursor)
Rewind cursor to the start of the list.
Definition dcursor.h:232
static int fr_dcursor_prepend(fr_dcursor_t *cursor, void *v)
Insert a single item at the start of the list.
Definition dcursor.h:376
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:141
#define MEM(x)
Definition debug.h:46
#define ERROR(fmt,...)
Definition dhcpclient.c:40
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:292
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:305
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
Specifies an attribute which must be present for the module to function.
Definition dict.h:291
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:304
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
#define fr_event_fd_insert(...)
Definition event.h:247
int fr_fring_overwrite(fr_fring_t *fring, void *in)
Insert a new item into the circular buffer, freeing the tail if we hit it.
Definition fring.c:120
void * fr_fring_next(fr_fring_t *fring)
Remove an item from the buffer.
Definition fring.c:177
fr_fring_t * fr_fring_alloc(TALLOC_CTX *ctx, uint32_t size, bool lock)
Initialise a ring buffer with fixed element size.
Definition fring.c:78
Standard thread safe circular buffer.
Definition fring.c:36
IPv4/6 prefix.
#define PERROR(_fmt,...)
Definition log.h:228
#define DEBUG3(_fmt,...)
Definition log.h:266
void * uctx
Context to pass to the logging function.
Definition log.h:72
log_dst_t * next
Next logging destination.
Definition log.h:74
log_func_t func
Function to call to log to this destination.
Definition log.h:71
Definition log.h:70
Stores all information relating to an event list.
Definition event.c:377
fr_log_lvl_t
Definition log.h:64
fr_log_type_t
Definition log.h:51
unsigned short uint16_t
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ 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.
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
void * thread
Thread specific instance data.
Definition module_ctx.h:43
fr_event_list_t * el
Event list to register any IO handlers and timers against.
Definition module_ctx.h:68
void * thread
Thread instance data.
Definition module_ctx.h:67
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:64
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
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:290
#define fr_assert(_expr)
Definition rad_assert.h:37
#define DEBUG2(fmt,...)
static rs_t * conf
Definition radsniff.c:52
#define RETURN_UNLANG_OK
Definition rcode.h:64
#define RETURN_UNLANG_NOOP
Definition rcode.h:69
static void logtee_it(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt, va_list ap, void *uctx))
static unlang_action_t mod_insert_logtee(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Add our logging destination to the linked list of logging destinations (if it doesn't already exist)
Definition rlm_logtee.c:521
static void logtee_fd_idle(rlm_logtee_thread_t *t)
Set the socket to idle.
Definition rlm_logtee.c:312
fr_ipaddr_t src_ipaddr
Send requests from a given src_ipaddr.
Definition rlm_logtee.c:70
static void _logtee_conn_error(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, int fd_errno, void *uctx)
Connection errored.
Definition rlm_logtee.c:208
logtee_dst_t log_dst
Logging destination.
Definition rlm_logtee.c:84
static void logtee_fd_active(rlm_logtee_thread_t *t)
Set the socket to active.
Definition rlm_logtee.c:332
static void _logtee_conn_close(UNUSED fr_event_list_t *el, void *h, UNUSED void *uctx)
Shutdown/close a file descriptor.
Definition rlm_logtee.c:349
static fr_dict_attr_t const * attr_log_type
Definition rlm_logtee.c:184
static const conf_parser_t file_config[]
Definition rlm_logtee.c:128
char const * name
Module instance name.
Definition rlm_logtee.c:77
char const * log_dst_str
Logging destination string.
Definition rlm_logtee.c:85
static fr_dict_attr_t const * attr_log_message
Definition rlm_logtee.c:183
static fr_dict_t const * dict_freeradius
Definition rlm_logtee.c:174
char const * delimiter
Line termination string (usually ).
Definition rlm_logtee.c:79
static fr_dict_attr_t const * attr_log_level
Definition rlm_logtee.c:182
size_t buffer_depth
How big our circular buffer should be.
Definition rlm_logtee.c:87
fr_pair_t * msg
Temporary value pair holding the message value.
Definition rlm_logtee.c:122
static connection_state_t _logtee_conn_init(void **h_out, connection_t *conn, void *uctx)
Initialise a new outbound connection.
Definition rlm_logtee.c:386
fr_dict_attr_autoload_t rlm_logtee_dict_attr[]
Definition rlm_logtee.c:187
static void _logtee_conn_writable(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, void *uctx)
There's space available to write data, so do that...
Definition rlm_logtee.c:258
static const conf_parser_t udp_config[]
Definition rlm_logtee.c:140
tmpl_t * log_fmt
Source of log messages.
Definition rlm_logtee.c:82
fr_fring_t * fring
Circular buffer used to batch up messages.
Definition rlm_logtee.c:116
fr_time_delta_t connection_timeout
How long to wait to open a socket.
Definition rlm_logtee.c:103
static fr_table_num_sorted_t const logtee_dst_table[]
Definition rlm_logtee.c:60
fr_dict_autoload_t rlm_logtee_dict[]
Definition rlm_logtee.c:177
fr_pair_t * type
Temporary value pair holding the message type.
Definition rlm_logtee.c:123
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Create thread-specific connections and buffers.
Definition rlm_logtee.c:551
bool pending
We have pending messages to write.
Definition rlm_logtee.c:118
static size_t logtee_dst_table_len
Definition rlm_logtee.c:66
fr_pair_t * lvl
Temporary value pair holding the log lvl.
Definition rlm_logtee.c:124
logtee_dst_t
Definition rlm_logtee.c:52
@ LOGTEE_DST_FILE
Log to a file.
Definition rlm_logtee.c:54
@ LOGTEE_DST_INVALID
Definition rlm_logtee.c:53
@ LOGTEE_DST_TCP
Log via TCP.
Definition rlm_logtee.c:57
@ LOGTEE_DST_UNIX
Log via Unix socket.
Definition rlm_logtee.c:55
@ LOGTEE_DST_UDP
Log via UDP.
Definition rlm_logtee.c:56
logtee_net_t tcp
TCP server.
Definition rlm_logtee.c:100
static connection_state_t _logtee_conn_open(UNUSED fr_event_list_t *el, UNUSED void *h, void *uctx)
Process notification that fd is open.
Definition rlm_logtee.c:361
fr_event_list_t * el
This thread's event list.
Definition rlm_logtee.c:113
fr_ipaddr_t dst_ipaddr
Network server.
Definition rlm_logtee.c:69
connection_t * conn
Connection to our log destination.
Definition rlm_logtee.c:114
static const conf_parser_t module_config[]
Definition rlm_logtee.c:153
module_rlm_t rlm_logtee
Definition rlm_logtee.c:645
static const conf_parser_t unix_config[]
Definition rlm_logtee.c:135
logtee_net_t udp
UDP server.
Definition rlm_logtee.c:101
size_t delimiter_len
Length of line termination string.
Definition rlm_logtee.c:80
static int mod_instantiate(module_inst_ctx_t const *mctx)
Definition rlm_logtee.c:593
fr_time_delta_t reconnection_delay
How long to wait to retry.
Definition rlm_logtee.c:104
uint16_t port
Network port.
Definition rlm_logtee.c:71
TALLOC_CTX * msg_pool
A 1k talloc pool to hold the log message whilst it's being expanded.
Definition rlm_logtee.c:120
rlm_logtee_t const * inst
Instance of logtee.
Definition rlm_logtee.c:112
static void _logtee_conn_read(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, void *uctx)
Drain any data we received.
Definition rlm_logtee.c:225
static const conf_parser_t tcp_config[]
Definition rlm_logtee.c:146
logtee module instance
Definition rlm_logtee.c:76
Per-thread instance data.
Definition rlm_logtee.c:111
static char const * name
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
Definition section.h:39
void connection_signal_reconnect(connection_t *conn, connection_reason_t reason)
Asynchronously signal the connection should be reconnected.
int connection_signal_on_fd(connection_t *conn, int fd)
Setup the connection to change states to connected or failed based on I/O events.
void connection_signal_init(connection_t *conn)
Asynchronously signal a halted connection to start.
connection_t * connection_alloc(TALLOC_CTX *ctx, fr_event_list_t *el, connection_funcs_t const *funcs, connection_conf_t const *conf, char const *log_prefix, void const *uctx)
Allocate a new connection.
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:293
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Definition module.h:152
Named methods exported by a module.
Definition module.h:174
#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
Definition tmpl.h:1064
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
int fr_socket_client_udp(char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected UDP socket.
Definition socket.c:613
int fr_socket_client_tcp(char const *ifname, fr_ipaddr_t *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
Definition socket.c:708
int fr_socket_client_unix(UNUSED char const *path, UNUSED bool async)
Definition socket.c:543
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
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
char * talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:572
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:136
A time delta, a difference in time measured in nanoseconds.
Definition time.h:80
@ T_DOUBLE_QUOTED_STRING
Definition token.h:119
static fr_event_list_t * el
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition pair.h:604
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
Definition value.c:4391
int fr_value_box_bstrdup_buffer_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Assign a talloced buffer containing a nul terminated string to a box, but don't copy it.
Definition value.c:4960
#define fr_box_ipaddr(_val)
Definition value.h:317
int nonnull(2, 5))