The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
log.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: 193999b34fafd0a717af039a59f289d0ace3f02c $
19 *
20 * @brief Logging functions used by the server core.
21 * @file src/lib/server/log.c
22 *
23 * @copyright 2000,2006 The FreeRADIUS server project
24 * @copyright 2000 Miquel van Smoorenburg (miquels@cistron.nl)
25 * @copyright 2000 Alan DeKok (aland@freeradius.org)
26 * @copyright 2001 Chad Miller (cmiller@surfsouth.com)
27 */
28RCSID("$Id: 193999b34fafd0a717af039a59f289d0ace3f02c $")
29
30#include <freeradius-devel/util/debug.h>
31#include <freeradius-devel/util/dict.h>
32#include <freeradius-devel/util/log.h>
33#include <freeradius-devel/util/syserror.h>
34#include <freeradius-devel/util/file.h>
35
36#include <freeradius-devel/server/log.h>
37#include <freeradius-devel/server/pair.h>
38#include <freeradius-devel/server/util.h>
39
40#include <freeradius-devel/unlang/xlat.h>
41
42#ifdef HAVE_SYS_STAT_H
43# include <sys/stat.h>
44#endif
45
46#include <fcntl.h>
47
48#ifdef HAVE_SYSLOG_H
49# include <syslog.h>
50#endif
51
52#include <sys/file.h>
53#include <pthread.h>
54
57
58/** Syslog facility table
59 *
60 * Maps syslog facility keywords, to the syslog facility macros defined
61 * in the system's syslog.h.
62 *
63 * @note Not all facilities are supported by every operating system.
64 * If a facility is unavailable it will not appear in the table.
65 */
67#ifdef LOG_AUTH
68 { L("auth"), LOG_AUTH },
69#endif
70
71#ifdef LOG_AUTHPRIV
72 { L("authpriv"), LOG_AUTHPRIV },
73#endif
74
75#ifdef LOG_CRON
76 { L("cron"), LOG_CRON },
77#endif
78
79#ifdef LOG_DAEMON
80 { L("daemon"), LOG_DAEMON },
81#endif
82
83#ifdef LOG_FTP
84 { L("ftp"), LOG_FTP },
85#endif
86
87#ifdef LOG_KERN
88 { L("kern"), LOG_KERN },
89#endif
90
91#ifdef LOG_LOCAL0
92 { L("local0"), LOG_LOCAL0 },
93#endif
94
95#ifdef LOG_LOCAL1
96 { L("local1"), LOG_LOCAL1 },
97#endif
98
99#ifdef LOG_LOCAL2
100 { L("local2"), LOG_LOCAL2 },
101#endif
102
103#ifdef LOG_LOCAL3
104 { L("local3"), LOG_LOCAL3 },
105#endif
106
107#ifdef LOG_LOCAL4
108 { L("local4"), LOG_LOCAL4 },
109#endif
110
111#ifdef LOG_LOCAL5
112 { L("local5"), LOG_LOCAL5 },
113#endif
114
115#ifdef LOG_LOCAL6
116 { L("local6"), LOG_LOCAL6 },
117#endif
118
119#ifdef LOG_LOCAL7
120 { L("local7"), LOG_LOCAL7 },
121#endif
122
123#ifdef LOG_LPR
124 { L("lpr"), LOG_LPR },
125#endif
126
127#ifdef LOG_MAIL
128 { L("mail"), LOG_MAIL },
129#endif
130
131#ifdef LOG_NEWS
132 { L("news"), LOG_NEWS },
133#endif
134
135#ifdef LOG_USER
136 { L("user"), LOG_USER },
137#endif
138
139#ifdef LOG_UUCP
140 { L("uucp"), LOG_UUCP }
141#endif
142};
144
145/** Syslog severity table
146 *
147 * Maps syslog severity keywords, to the syslog severity macros defined
148 * in the system's syslog.h file.
149 *
150 */
152#ifdef LOG_ALERT
153 { L("alert"), LOG_ALERT },
154#endif
155
156#ifdef LOG_CRIT
157 { L("critical"), LOG_CRIT },
158#endif
159
160#ifdef LOG_DEBUG
161 { L("debug"), LOG_DEBUG },
162#endif
163
164#ifdef LOG_EMERG
165 { L("emergency"), LOG_EMERG },
166#endif
167
168#ifdef LOG_ERR
169 { L("error"), LOG_ERR },
170#endif
171
172#ifdef LOG_INFO
173 { L("info"), LOG_INFO },
174#endif
175
176#ifdef LOG_NOTICE
177 { L("notice"), LOG_NOTICE },
178#endif
179
180#ifdef LOG_WARNING
181 { L("warning"), LOG_WARNING },
182#endif
183};
185
187 { L("file"), L_DST_FILES },
188 { L("files"), L_DST_FILES },
189 { L("null"), L_DST_NULL },
190 { L("stderr"), L_DST_STDERR },
191 { L("stdout"), L_DST_STDOUT },
192 { L("syslog"), L_DST_SYSLOG },
193};
195
196static char const spaces[] = " ";
197
199
202 { .out = &dict_freeradius, .proto = "freeradius" },
204};
205
207
210 { .out = &attr_module_failure_message, .name = "Module-Failure-Message", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
212};
213
214typedef struct {
215 char const *name; //!< name of this logging destination
216 fr_log_t *log; //!< pointer to the log structure
217 CONF_SECTION *cs; //!< where this log configuration came from
218
219 fr_rb_node_t name_node; //!< tree by name
220 fr_rb_node_t filename_node; //!< tree by name
222
223typedef struct {
224 char const *name; //!< name of this logging source
225 uint32_t id; //!< LOG_ID of this source
226 fr_log_t *original; //!< the original fr_log_t
227 fr_log_t **log; //!< where the logs should go
228
229 fr_rb_node_t name_node; //!< tree by name only
230 fr_rb_node_t id_node; //!< tree by ID
232
233static fr_rb_tree_t *dst_tree = NULL;
235static fr_rb_tree_t *src_tree = NULL;
236
237/** Send a server log message to its destination without evaluating its debug level
238 *
239 * @param[in] log destination.
240 * @param[in] type of log message.
241 * @param[in] file src file the log message was generated in.
242 * @param[in] line number the log message was generated on.
243 * @param[in] fmt with printf style substitution tokens.
244 * @param[in] ... Substitution arguments.
245 */
246
247static CC_HINT(format (printf, 5, 6))
249 char const *file, int line,
250 char const *fmt, ...)
251{
252 va_list ap;
253
254 va_start(ap, fmt);
255 fr_vlog(log, type, file, line, fmt, ap);
256 va_end(ap);
257}
258
259/** Whether a request specific debug message should be logged
260 *
261 * @param lvl of debugging this message should be logged at.
262 * @param request The current request.
263 * @return
264 * - true if message should be logged.
265 * - false if message shouldn't be logged.
266 */
267inline bool log_rdebug_enabled(fr_log_lvl_t lvl, request_t const *request)
268{
269 if (!request->log.dst) return false;
270
271 return (request->log.lvl >= lvl);
272}
273
274/** Cleanup the memory pool used by vlog_request
275 *
276 */
277static int _fr_vlog_request_pool_free(void *arg)
278{
279 return talloc_free(arg);
280}
281
282/** Send a log message to its destination, possibly including fields from the request
283 *
284 * @param[in] type of log message, #L_ERR, #L_WARN, #L_INFO, #L_DBG.
285 * @param[in] lvl Minimum required server or request level to output this message.
286 * @param[in] request The current request.
287 * @param[in] file src file the log message was generated in.
288 * @param[in] line number the log message was generated on.
289 * @param[in] fmt with printf style substitution tokens.
290 * @param[in] ap Substitution arguments.
291 * @param[in] uctx The #fr_log_t specifying the destination for log messages.
292 */
294 char const *file, int line,
295 char const *fmt, va_list ap, void *uctx)
296{
297 char const *filename;
298 FILE *fp = NULL;
299
300 char *p;
301 char const *extra = "";
302 uint8_t unlang_indent;
303 va_list aq;
304
305 char const *fmt_location = "";
306 char const *fmt_prefix = "";
307 char const *fmt_module = "";
308 char const *fmt_exp;
309
310 fr_log_t *log_dst = uctx;
311 TALLOC_CTX *pool;
312
313 /*
314 * No output means no output.
315 */
316 if (!log_dst) return;
317 if (!log_rdebug_enabled(lvl, request)) return;
318
319 /*
320 * Allocate a thread local, 4k pool so we don't
321 * need to keep allocating memory on the heap.
322 */
324 if (!pool) {
325 pool = talloc_pool(NULL, 4096);
326 if (!pool) {
327 fr_perror("Failed allocating memory for vlog_request_pool");
328 return;
329 }
331 }
332
333 filename = log_dst->file;
334
335 /*
336 * Debug messages get treated specially.
337 */
338 if ((type & L_DBG) != 0) {
339 /*
340 * If we're debugging to a file, then use that.
341 *
342 * @todo: have fr_vlog() take a fr_log_t*, so
343 * that we can cache the opened descriptor, and
344 * we don't need to re-open it on every log
345 * message.
346 */
347 switch (log_dst->dst) {
348 case L_DST_FILES:
349 fp = fopen(log_dst->file, "a");
350 if (!fp) goto finish;
351 break;
352
353#if defined(HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN)
354 case L_DST_FUNC:
355 {
356# ifdef HAVE_FOPENCOOKIE
358
359 /*
360 * These must be set separately as they have different prototypes.
361 */
362 io.read = NULL;
363 io.seek = NULL;
364 io.close = NULL;
365 io.write = log_dst->cookie_write;
366
367 fp = fopencookie(log_dst->cookie, "w", io);
368# else
369 fp = funopen(log_dst->cookie, NULL, log_dst->cookie_write, NULL, NULL);
370
371# endif
372 if (!fp) goto finish;
373 }
374 break;
375#endif
376 default:
377 break;
378 }
379 goto print_fmt;
380 }
381
382 if (filename) {
383 char *exp;
384 log_dst_t *dst;
385
386 dst = request->log.dst;
387
388 /*
389 * Prevent infinitely recursive calls if
390 * xlat_aeval attempts to write to the request log.
391 */
392 request->log.dst = NULL;
393
394 /*
395 * This is SLOW! Doing it for every log message
396 * in every request is NOT recommended!
397 */
398 if (xlat_aeval(request, &exp, request, filename, rad_filename_escape, NULL) < 0) return;
399
400 /*
401 * Restore the original logging function
402 */
403 request->log.dst = dst;
404
405 /*
406 * Ensure the directory structure exists, for
407 * where we're going to write the log file.
408 */
409 p = strrchr(exp, FR_DIR_SEP);
410 if (p) {
411 *p = '\0';
412 if (fr_mkdir(NULL, exp, -1, S_IRWXU, NULL, NULL) < 0) {
413 ERROR("Failed creating %s: %s", exp, fr_syserror(errno));
414 talloc_free(exp);
415 return;
416 }
417 *p = FR_DIR_SEP;
418 }
419
420 fp = fopen(exp, "a");
421 talloc_free(exp);
422 }
423
424print_fmt:
425 /*
426 * Request prefix i.e.
427 *
428 * (0) <fmt>
429 */
430 if (request->name) {
431 if ((request->seq_start == 0) || (request->number == request->seq_start)) {
432 fmt_prefix = talloc_typed_asprintf(pool, "(%s) ", request->name);
433 } else {
434 fmt_prefix = talloc_typed_asprintf(pool, "(%s,%" PRIu64 ") ",
435 request->name, request->seq_start);
436 }
437 }
438
439 /*
440 * Make sure the indent isn't set to something crazy
441 */
442 unlang_indent = request->log.indent.unlang > sizeof(spaces) - 1 ?
443 sizeof(spaces) - 1 :
444 request->log.indent.unlang;
445
446 /*
447 * Module name and indentation i.e.
448 *
449 * test - <fmt>
450 */
451 if (request->module) {
452 uint8_t module_indent = request->log.indent.module > sizeof(spaces) - 1 ?
453 sizeof(spaces) - 1 :
454 request->log.indent.module;
455 fmt_module = talloc_typed_asprintf(pool, "%s - %.*s", request->module, module_indent, spaces);
456 }
457
458 /*
459 * If we don't copy the original ap we get a segfault from vasprintf. This is apparently
460 * due to ap sometimes being implemented with a stack offset which is invalidated if
461 * ap is passed into another function. See here:
462 * http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
463 *
464 * I don't buy that explanation, but doing a va_copy here does prevent SEGVs seen when
465 * running unit tests which generate errors under CI.
466 */
467 va_copy(aq, ap);
468 if (!log_dst->suppress_secrets) {
469 fmt_exp = fr_vasprintf(pool, fmt, aq);
470 } else {
471 fmt_exp = fr_vasprintf_secure(pool, fmt, aq);
472 }
473 va_end(aq);
474
475 /*
476 * Logging to a file descriptor
477 */
478 if (fp) {
479 char time_buff[64]; /* The current timestamp */
480
481 time_t timeval;
482 timeval = time(NULL);
483
484#if 0
485 fmt_location = talloc_typed_asprintf(pool, "%s[%i]: ", file, line);
486#endif
487
488#ifdef HAVE_GMTIME_R
489 if (log_dates_utc) {
490 struct tm utc;
491 gmtime_r(&timeval, &utc);
492 ASCTIME_R(&utc, time_buff, sizeof(time_buff));
493 } else
494#endif
495 {
496 CTIME_R(&timeval, time_buff, sizeof(time_buff));
497 }
498
499 /*
500 * Strip trailing new lines
501 */
502 p = strrchr(time_buff, '\n');
503 if (p) p[0] = '\0';
504
505 fprintf(fp,
506 "%s" /* location */
507 "%s" /* prefix */
508 "%s : " /* time */
509 "%s" /* facility */
510 "%.*s" /* indent */
511 "%s" /* module */
512 "%s" /* message */
513 "\n",
514 fmt_location,
515 fmt_prefix,
516 time_buff,
518 unlang_indent, spaces,
519 fmt_module,
520 fmt_exp);
521 fclose(fp);
522 goto finish;
523 }
524
525 /*
526 * Logging everywhere else
527 */
528 if (!DEBUG_ENABLED3) switch (type) {
529 case L_DBG_WARN:
530 extra = "WARNING: ";
532 break;
533
534 case L_DBG_ERR:
535 extra = "ERROR: ";
537 break;
538 default:
539 break;
540 }
541
543 "%s" /* prefix */
544 "%.*s" /* indent */
545 "%s" /* module */
546 "%s" /* extra */
547 "%s", /* message */
548 fmt_prefix,
549 unlang_indent, spaces,
550 fmt_module,
551 extra,
552 fmt_exp);
553
554finish:
555 talloc_free_children(pool);
556}
557
558/** Add a module failure message fr_pair_t to the request
559 *
560 * @param[in] request The current request.
561 * @param[in] fmt with printf style substitution tokens.
562 * @param[in] ap Substitution arguments.
563 */
564static void vlog_module_failure_msg(request_t *request, char const *fmt, va_list ap)
565{
566 char *p;
567 fr_pair_t *vp;
568 va_list aq;
569
570 if (!fmt || !request || !request->packet) return;
571
573
575
576 /*
577 * If we don't copy the original ap we get a segfault from vasprintf. This is apparently
578 * due to ap sometimes being implemented with a stack offset which is invalidated if
579 * ap is passed into another function. See here:
580 * http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
581 *
582 * I don't buy that explanation, but doing a va_copy here does prevent SEGVs seen when
583 * running unit tests which generate errors under CI.
584 */
585 va_copy(aq, ap);
586 p = fr_vasprintf(vp, fmt, aq);
587 va_end(aq);
588
589 if (request->module && (request->module[0] != '\0')) {
590 fr_pair_value_aprintf(vp, "%s: %s", request->module, p);
591 talloc_free(p);
592 } else {
594 }
595}
596
597/** Marshal variadic log arguments into a va_list and pass to normal logging functions
598 *
599 * @see log_request_error for more details.
600 *
601 * @param[in] type the log category.
602 * @param[in] lvl of debugging this message should be logged at.
603 * @param[in] request The current request.
604 * @param[in] file src file the log message was generated in.
605 * @param[in] line number the log message was generated on.
606 * @param[in] fmt with printf style substitution tokens.
607 * @param[in] ... Substitution arguments.
608 */
610 char const *file, int line, char const *fmt, ...)
611{
612 va_list ap;
613
614 if (!request->log.dst) return;
615
616 va_start(ap, fmt);
617 log_dst_foreach(request->log.dst, dst) {
618 if ((lvl > request->log.lvl) && (lvl > dst->lvl)) continue;
619
620 dst->func(type, lvl, request, file, line, fmt, ap, dst->uctx);
621 }
622 va_end(ap);
623}
624
625/** Marshal variadic log arguments into a va_list and pass to error logging functions
626 *
627 * This could all be done in a macro, but it turns out some implementations of the
628 * variadic macros do not work at all well if the va_list being written to is further
629 * up the stack (which is required as you still need a function to convert the ellipsis
630 * into a va_list).
631 *
632 * So, we use this small wrapper function instead, which will hopefully guarantee
633 * consistent behaviour.
634 *
635 * @param[in] type the log category.
636 * @param[in] lvl of debugging this message should be logged at.
637 * @param[in] request The current request.
638 * @param[in] file src file the log message was generated in.
639 * @param[in] line number the log message was generated on.
640 * @param[in] fmt with printf style substitution tokens.
641 * @param[in] ... Substitution arguments.
642 */
644 char const *file, int line, char const *fmt, ...)
645{
646 va_list ap;
647
648 if (!request->log.dst) return;
649
650 va_start(ap, fmt);
651 log_dst_foreach(request->log.dst, dst) {
652 va_list copy;
653 va_copy(copy, ap);
654
655 dst->func(type, lvl, request, file, line, fmt, copy, dst->uctx);
656
657 va_end(copy);
658 }
659
660 if ((type == L_ERR) || (type == L_DBG_ERR) || (type == L_DBG_ERR_REQ)) {
661 vlog_module_failure_msg(request, fmt, ap);
662 }
663
664 va_end(ap);
665}
666
667/** Drain any outstanding messages from the fr_strerror buffers
668 *
669 * This function drains any messages from fr_strerror buffer adding a prefix (fmt)
670 * to the first message.
671 *
672 * @param[in] type the log category.
673 * @param[in] lvl of debugging this message should be logged at.
674 * @param[in] request The current request.
675 * @param[in] file src file the log message was generated in.
676 * @param[in] line number the log message was generated on.
677 * @param[in] fmt with printf style substitution tokens.
678 * @param[in] ... Substitution arguments.
679 */
681 char const *file, int line, char const *fmt, ...)
682{
683 char const *error;
684
685 if (!request->log.dst) return;
686
687 /*
688 * No strerror gets us identical behaviour to log_request_error
689 */
690 error = fr_strerror_pop();
691 if (!error) {
692 va_list ap;
693
694 if (!fmt) return; /* NOOP */
695
696 va_start(ap, fmt);
697 log_dst_foreach(request->log.dst, dst) {
698 va_list copy;
699 va_copy(copy, ap);
700
701 dst->func(type, lvl, request, file, line, fmt, copy, dst->uctx);
702
703 va_end(copy);
704 }
705 if ((type == L_ERR) || (type == L_DBG_ERR) || (type == L_DBG_ERR_REQ)) {
706 vlog_module_failure_msg(request, fmt, ap);
707 }
708 va_end(ap);
709
710 return; /* DONE */
711 }
712
713 /*
714 * Concatenate fmt with fr_strerror()
715 */
716 if (fmt) {
717 va_list ap;
718 char *tmp;
719
720 va_start(ap, fmt);
721 tmp = fr_vasprintf(request, fmt, ap);
722 va_end(ap);
723
724 if (!tmp) return;
725
726 log_request_error(type, lvl, request, file, line, "%s: %s", tmp, error);
727 talloc_free(tmp);
728 } else {
729 log_request_error(type, lvl, request, file, line, "%s", error);
730 }
731
732 /*
733 * Only the first message gets the prefix
734 */
735 while ((error = fr_strerror_pop())) log_request_error(type, lvl, request, file, line, "%s", error);
736}
737
738/** Cleanup the memory pool used by the OID sbuff
739 *
740 */
741static int _fr_log_request_oid_buff_free(void *arg)
742{
743 return talloc_free(arg);
744}
745
746/** Allocate an extensible sbuff for printing OID strings
747 *
748 */
749static inline CC_HINT(always_inline) fr_sbuff_t *log_request_oid_buff(void)
750{
751 fr_sbuff_t *sbuff;
753
755 if (unlikely(!sbuff)) {
756 sbuff = talloc(NULL, fr_sbuff_t);
757 if (!sbuff) {
758 fr_perror("Failed allocating memory for fr_log_request_oid_buff");
759 return NULL;
760 }
761 tctx = talloc(sbuff, fr_sbuff_uctx_talloc_t);
762 if (!tctx) {
763 fr_perror("Failed allocating memory for fr_sbuff_uctx_talloc_t");
764 talloc_free(sbuff);
765 return NULL;
766 }
767
768 fr_sbuff_init_talloc(sbuff, sbuff, tctx, 1024, (FR_DICT_ATTR_MAX_NAME_LEN + 1) * FR_DICT_MAX_TLV_STACK);
769
771 } else {
772 fr_sbuff_set(sbuff, fr_sbuff_start(sbuff)); /* Reset position */
773 }
774
775 return sbuff;
776}
777
778/** Print a #fr_pair_t.
779 *
780 * @param[in] lvl Debug lvl (1-4).
781 * @param[in] request to read logging params from.
782 * @param[in] parent of pair to print, may be NULL.
783 * @param[in] vp to print.
784 * @param[in] prefix (optional).
785 */
787 fr_pair_t const *parent, fr_pair_t const *vp, char const *prefix)
788{
789 fr_sbuff_t *oid_buff;
790
791 if (!request->log.dst) return;
792
793 if (!log_rdebug_enabled(lvl, request)) return;
794
796
797 oid_buff = log_request_oid_buff();
798
799 if (fr_pair_print_name(oid_buff, parent ? parent->da : NULL, &vp) <= 0) return;
800
801 /*
802 * Recursively print grouped attributes.
803 */
804 switch (vp->vp_type) {
806 RDEBUGX(lvl, "%s%s{", prefix ? prefix : "", fr_sbuff_start(oid_buff));
807 log_request_pair_list(lvl, request, vp, &vp->vp_group, NULL);
808 RDEBUGX(lvl, "}");
809 break;
810
811 default:
812 fr_assert(fr_type_is_leaf(vp->vp_type));
813
814 RDEBUGX(lvl, "%s%s%pV", prefix ? prefix : "", fr_sbuff_start(oid_buff), &vp->data);
815 break;
816 }
817}
818
819/** Print a #fr_pair_list_t
820 *
821 * @param[in] lvl Debug lvl (1-4).
822 * @param[in] request to read logging params from.
823 * @param[in] parent of vps to print, may be NULL.
824 * @param[in] vps to print.
825 * @param[in] prefix (optional).
826 */
828 fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
829{
830 if (fr_pair_list_empty(vps) || !request->log.dst) return;
831
832 if (!log_rdebug_enabled(lvl, request)) return;
833
834 RINDENT();
837
838 log_request_pair(lvl, request, parent, vp, prefix);
839 }
840 REXDENT();
841}
842
843/** Print a packet which we received or sent
844 *
845 * @param[in] request to read logging params from.
846 * @param[in] packet the packet in question
847 * @param[in] list to print.
848 * @param[in] type_da of Packet-Type
849 * @param[in] received is this packet being received or being sent
850 * @param[in] id do we log IDs, too
851 */
852void log_request_packet(request_t *request, fr_packet_t *packet, fr_pair_list_t *list, fr_dict_attr_t const *type_da, bool received, bool id)
853{
854 ssize_t slen;
855 fr_dict_enum_value_t const *enumv;
856 char const *name;
857 char name_buffer[32];
858 char id_buffer[32];
859 char buffer[256];
860
861 if (!RDEBUG_ENABLED) return;
862
863 slen = fr_socket_to_str(buffer, sizeof(buffer), &packet->socket, received);
864 if (slen <= 0) buffer[0] = '\0';
865
866 if (id) {
867 (void) snprintf(id_buffer, sizeof(id_buffer), " ID %u", packet->id);
868 } else {
869 id_buffer[0] = '\0';
870 }
871
872 enumv = fr_dict_enum_by_value(type_da, fr_box_uint32((uint32_t) packet->code));
873 if (enumv) {
874 name = enumv->name;
875 } else {
876 (void) snprintf(name_buffer, sizeof(name_buffer), "%u", packet->code);
877 name = name_buffer;
878 }
879
880 log_request(L_DBG, L_DBG_LVL_1, request, __FILE__, __LINE__, "%s %s%s %s",
881 received ? "Received" : "Sending",
882 name,
883 id_buffer,
884 buffer);
885
886 if (received || request->parent) {
887 log_request_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
888 } else {
889 log_request_proto_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
890 }
891}
892
893/** Print a list of protocol fr_pair_ts.
894 *
895 * @param[in] lvl Debug lvl (1-4).
896 * @param[in] request to read logging params from.
897 * @param[in] parent of vps to print, may be NULL.
898 * @param[in] vps to print.
899 * @param[in] prefix (optional).
900 */
902 fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
903{
904 if (fr_pair_list_empty(vps) || !request->log.dst) return;
905
906 if (!log_rdebug_enabled(lvl, request)) return;
907
908 RINDENT();
911
912 if (!fr_dict_attr_common_parent(fr_dict_root(request->proto_dict), vp->da, true)) continue;
913
914 log_request_pair(lvl, request, parent, vp, prefix);
915 }
916 REXDENT();
917}
918
919/** Write the string being parsed, and a marker showing where the parse error occurred
920 *
921 * @param[in] type the log category.
922 * @param[in] lvl of debugging this message should be logged at.
923 * @param[in] request The current request.
924 * @param[in] file src file the log message was generated in.
925 * @param[in] line number the log message was generated on.
926 * @param[in] str Subject string we're printing a marker for.
927 * @param[in] str_len Subject string length. Use SIZE_MAX for the
928 * length of the string.
929 * @param[in] marker_idx The position of the marker relative to the string.
930 * @param[in] marker_fmt What the parse error was.
931 * @param[in] ... Arguments for fmt string.
932 */
934 char const *file, int line,
935 char const *str, size_t str_len,
936 ssize_t marker_idx, char const *marker_fmt, ...)
937{
938 char const *ellipses = "";
939 rindent_t indent;
940 va_list ap;
941 char *error;
942 static char const marker_spaces[] = " "; /* 60 */
943
944 if (str_len == SIZE_MAX) str_len = strlen(str);
945
946 if (marker_idx < 0) marker_idx = (marker_idx == SSIZE_MIN) ? SSIZE_MAX : -marker_idx;
947
948 if ((size_t) marker_idx >= sizeof(marker_spaces)) {
949 size_t offset = (marker_idx - (sizeof(marker_spaces) - 1)) + (sizeof(marker_spaces) * 0.75);
950
951 marker_idx -= offset;
952
953 if (offset >= str_len) {
954 str += str_len;
955 str_len = 0;
956 } else {
957 str += offset;
958 str_len -= offset;
959 }
960
961 ellipses = "... ";
962 }
963
964 /*
965 * Don't want format markers being indented
966 */
967 indent = request->log.indent;
968 request->log.indent.module = 0;
969 request->log.indent.unlang = 0;
970
971 va_start(ap, marker_fmt);
972 error = fr_vasprintf(request, marker_fmt, ap);
973 va_end(ap);
974
975 log_request(type, lvl, request, file, line, "%s%.*s", ellipses, (int) str_len, str);
976 log_request(type, lvl, request, file, line, "%s%.*s^ %s", ellipses, (int) marker_idx, marker_spaces, error);
977 talloc_free(error);
978
979 request->log.indent = indent;
980}
981
983 char const *file, int line,
984 uint8_t const *data, size_t data_len)
985{
986 size_t i, j, len;
987 char buffer[(0x10 * 3) + 1];
988 char *p, *end = buffer + sizeof(buffer);
989
990 for (i = 0; i < data_len; i += 0x10) {
991 len = 0x10;
992 if ((i + len) > data_len) len = data_len - i;
993
994 for (p = buffer, j = 0; j < len; j++, p += 3) snprintf(p, end - p, "%02x ", data[i + j]);
995 log_request(type, lvl, request, file, line, "%04x: %s", (int)i, buffer);
996 }
997}
998
999/** Function to provide as the readable callback to the event loop
1000 *
1001 * Writes any data read from a file descriptor to the request log,
1002 * tries very hard not to chop lines in the middle, but will split
1003 * at 1024 byte boundaries if forced to.
1004 *
1005 * @param[in] el UNUSED
1006 * @param[in] fd UNUSED
1007 * @param[in] flags UNUSED
1008 * @param[in] uctx Pointer to a log_fd_event_ctx_t
1009 */
1010void log_request_fd_event(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
1011{
1012 char buffer[1024];
1013 log_fd_event_ctx_t *log_info = uctx;
1014 request_t *request = log_info->request;
1015 fr_sbuff_t sbuff;
1016 fr_sbuff_marker_t m_start, m_end;
1017
1018 fr_sbuff_term_t const line_endings = FR_SBUFF_TERMS(L("\n"), L("\r"));
1019
1020 if (!RDEBUG_ENABLEDX(log_info->lvl)) {
1021 while (read(fd, buffer, sizeof(buffer)) > 0); /* discard all input */
1022 return;
1023 }
1024
1025 fr_sbuff_init_out(&sbuff, buffer, sizeof(buffer));
1026 fr_sbuff_marker(&m_start, &sbuff);
1027 fr_sbuff_marker(&m_end, &sbuff);
1028
1029#ifndef NDEBUG
1030 memset(buffer, 0x42, sizeof(buffer));
1031#endif
1032
1033 for (;;) {
1034 ssize_t slen;
1035
1036 slen = read(fd, fr_sbuff_current(&m_end), fr_sbuff_remaining(&m_end));
1037 if (slen < 0) {
1038 if (errno == EINTR) continue;
1039
1040 /*
1041 * This can happen if the I/O handler is
1042 * manually called to clear out any pending
1043 * data, and we're using a nonblocking FD.
1044 *
1045 * This can happen with the exec code if
1046 * the EVFILT_PROC event gets passed before
1047 * the EVFILT_READ event.
1048 */
1049 if (errno == EWOULDBLOCK) slen = 0;
1050 }
1051 if ((slen < 0) && (errno == EINTR)) continue;
1052
1053 if (slen > 0) fr_sbuff_advance(&m_end, slen);
1054
1055 while (fr_sbuff_ahead(&m_end) > 0) {
1056 fr_sbuff_adv_until(&sbuff, fr_sbuff_ahead(&m_end), &line_endings, '\0');
1057
1058 /*
1059 * Incomplete line, try and read the rest.
1060 */
1061 if ((slen > 0) && (fr_sbuff_used(&m_start) > 0) &&
1062 !fr_sbuff_is_terminal(&sbuff, &line_endings)) {
1063 break;
1064 }
1065
1066 log_request(log_info->type, log_info->lvl, log_info->request,
1067 __FILE__, __LINE__,
1068 "%s%s%pV",
1069 log_info->prefix ? log_info->prefix : "",
1070 log_info->prefix ? " - " : "",
1072 fr_sbuff_behind(&m_start)));
1073
1074 fr_sbuff_advance(&sbuff, 1); /* Skip the whitespace */
1075 fr_sbuff_set(&m_start, &sbuff);
1076 }
1077
1078 /*
1079 * Error or done
1080 */
1081 if (slen <= 0) break;
1082
1083 /*
1084 * Clear out the existing data
1085 */
1086 fr_sbuff_shift(&sbuff, fr_sbuff_used(&m_start), false);
1087 }
1088}
1089
1090/** Log a fatal error, then exit
1091 *
1092 */
1093void log_fatal(fr_log_t const *log, char const *file, int line, char const *fmt, ...)
1094{
1095 va_list ap;
1096
1097 va_start(ap, fmt);
1098 fr_vlog(log, L_ERR, file, line, fmt, ap);
1099 va_end(ap);
1100
1101 fr_exit_now(EXIT_FAILURE);
1102}
1103
1104/** Register a logging destination.
1105 *
1106 */
1107static void log_register_dst(char const *name, fr_log_t *log, CONF_SECTION *cs)
1108{
1109 fr_log_track_t *dst;
1110
1111 MEM(dst = talloc_zero(dst_tree, fr_log_track_t));
1112 dst->name = name;
1113 dst->log = log;
1114 dst->cs = cs;
1115
1116 fr_rb_insert(dst_tree, dst);
1117
1118 if (log->dst != L_DST_FILES) return;
1119
1120 fr_assert(log->file != NULL);
1121
1123}
1124
1125/** Get a logging destination by name.
1126 *
1127 */
1129{
1130 fr_log_track_t find, *found;
1131
1132 memset(&find, 0, sizeof(find));
1133 find.name = name;
1134
1135 fr_rb_find((void **)&found, dst_tree, &find);
1136 return (found) ? found->log : NULL;
1137}
1138
1139static int _log_free(fr_log_t *log)
1140{
1141 fr_assert(log->dst == L_DST_FILES);
1142
1143 fclose(log->handle);
1144 return 0;
1145}
1146
1147static char const *log_destination = NULL;
1148static bool log_timestamp;
1150
1151/*
1152 * Parse an fr_log_t configuration.
1153 */
1154static const conf_parser_t log_config[] = {
1155 { FR_CONF_POINTER("destination", FR_TYPE_STRING, 0, &log_destination), .dflt = "file" },
1156#if 0
1157 /*
1158 * @todo - once we allow this, also check that there's only _one_ destination
1159 * which uses syslog_facility.
1160 */
1161 { FR_CONF_OFFSET("syslog_facility", main_config_t, syslog_facility), .dflt = "daemon",
1163 .uctx = &(cf_table_parse_ctx_t){
1164 .table = syslog_facility_table,
1166 }
1167 },
1168#endif
1169 { FR_CONF_POINTER_IS_SET("timestamp", FR_TYPE_BOOL, 0, &log_timestamp) },
1170 { FR_CONF_OFFSET("file", fr_log_t, file), },
1171 { FR_CONF_OFFSET("colourise", fr_log_t, colourise) },
1172 { FR_CONF_OFFSET("line_number", fr_log_t, line_number) },
1173 { FR_CONF_OFFSET("use_utc", fr_log_t, dates_utc) },
1174 { FR_CONF_OFFSET("print_level", fr_log_t, print_level) },
1175 { FR_CONF_OFFSET("suppress_secrets", fr_log_t, suppress_secrets) },
1177};
1178
1179/** Parse a named logging section.
1180 *
1181 * @todo - we should probably allow for TCP sockets, too. But then
1182 * those can block. So we then also need a way to buffer outbound
1183 * log messages, and discard log messages if the buffer is full.
1184 *
1185 * This should probably be done with a FILE*, and L_DST_FUNC.
1186 */
1188{
1189 fr_log_track_t *dst;
1190 fr_log_t *log;
1191 char const *name;
1192
1193 name = cf_section_name2(cs);
1194 if (!name) name = "DEFAULT";
1195
1196 fr_rb_find((void **)&dst, dst_tree, &(fr_log_track_t) {
1197 .name = name,
1198 });
1199 if (dst) {
1200 fr_strerror_printf("Cannot add duplicate log destination '%s'", name);
1201 return -1;
1202 }
1203
1204 MEM(log = talloc_zero(dst_tree, fr_log_t));
1205
1206 if (cf_section_rules_push(cs, log_config) < 0) {
1207 error:
1208 talloc_free(log);
1209 return -1;
1210 }
1211
1212 if (cf_section_parse(log, log, cs) < 0) goto error;
1213
1215 switch (log->dst) {
1216 case L_DST_NUM_DEST:
1217 fr_strerror_printf("Unknown log_destination '%s'", log_destination);
1219 log_destination = NULL;
1220 goto error;
1221
1222#ifdef HAVE_SYSLOG_H
1223 case L_DST_SYSLOG:
1225 log_destination = NULL;
1226
1227 if (fr_log_init_syslog(log) < 0) goto error;
1228 break;
1229#endif
1230
1231 case L_DST_STDOUT:
1233 log_destination = NULL;
1234
1235 if (fr_log_init_std(log, L_DST_STDOUT) < 0) goto error;
1236 break;
1237
1238 case L_DST_STDERR:
1240 log_destination = NULL;
1241
1242 if (fr_log_init_std(log, L_DST_STDERR) < 0) goto error;
1243 break;
1244
1245 case L_DST_FILES:
1247 log_destination = NULL;
1248
1249 if (!log->file) {
1250 fr_strerror_const("Specified \"files\" as a log destination, but no log filename was given!");
1251 goto error;
1252 }
1253
1254 fr_rb_find((void **)&dst, filename_tree, &(fr_log_track_t) {
1255 .log = log,
1256 });
1257 if (dst) {
1258 fr_strerror_printf("The log destination '%s' is already logging to file %s",
1259 dst->name, log->file);
1260 goto error;
1261 }
1262
1263 if (fr_log_init_file(log, log->file) < 0) goto error;
1264
1265 talloc_set_destructor(log, _log_free);
1266 break;
1267
1268 case L_DST_NULL:
1269 break;
1270
1271 default:
1273 log_destination = NULL;
1274
1275 fr_assert(0);
1276 break;
1277 }
1278
1281 } else {
1283 }
1284
1285 log_register_dst(name, log, cs);
1286
1287 return 0;
1288}
1289
1290static fr_cmp_ret_t _log_track_name_cmp(void const *two, void const *one)
1291{
1292 fr_log_track_t const *a = one;
1293 fr_log_track_t const *b = two;
1294
1295 return CMP(strcmp(a->name, b->name), 0);
1296}
1297
1298static fr_cmp_ret_t _log_track_filename_cmp(void const *two, void const *one)
1299{
1300 fr_log_track_t const *a = one;
1301 fr_log_track_t const *b = two;
1302
1303 fr_assert(a->log);
1304 fr_assert(a->log->dst == L_DST_FILES);
1305
1306 fr_assert(b->log);
1307 fr_assert(b->log->dst == L_DST_FILES);
1308
1309 return CMP(strcmp(a->log->file, b->log->file), 0);
1310}
1311
1312/** Initialises the server logging functionality, and the underlying libfreeradius log
1313 *
1314 * @note Call log free when the server is done to fix any spurious memory leaks.
1315 *
1316 * @param[in] log Logging parameters.
1317 * @param[in] daemonize Changes what we do with stdout/stderr.
1318 * @return
1319 * - 0 on success.
1320 * - -1 on failure.
1321 */
1322int log_global_init(fr_log_t *log, bool daemonize)
1323{
1324 int ret;
1325
1326 ret = fr_log_init_legacy(log, daemonize);
1327 if (ret < 0) return ret;
1328
1329 if (fr_dict_autoload(log_dict) < 0) {
1330 fr_perror("log_init");
1331 return -1;
1332 }
1333
1335 fr_perror("log_init");
1336 return -1;
1337 }
1338
1339 dst_tree = fr_rb_inline_alloc(NULL, fr_log_track_t, name_node,
1340 _log_track_name_cmp, NULL);
1341 if (!dst_tree) {
1342 fr_perror("log_init");
1343 return -1;
1344 }
1345
1346 filename_tree = fr_rb_inline_alloc(NULL, fr_log_track_t, filename_node,
1348 if (!filename_tree) {
1349 fr_perror("log_init");
1350 return -1;
1351 }
1352
1353 log_register_dst("default", log, NULL);
1354
1355 return ret;
1356}
1357
1359{
1361 TALLOC_FREE(src_tree);
1362 TALLOC_FREE(dst_tree);
1363 TALLOC_FREE(filename_tree);
1364}
static int const char char buffer[256]
Definition acutest.h:576
int const char * file
Definition acutest.h:702
va_end(args)
static int const char * fmt
Definition acutest.h:573
int const char int line
Definition acutest.h:702
va_start(args, fmt)
#define _Thread_local
Definition atexit.h:213
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition atexit.h:224
#define RCSID(id)
Definition build.h:560
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:228
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition build.h:113
#define unlikely(_x)
Definition build.h:455
#define UNUSED
Definition build.h:384
#define NUM_ELEMENTS(_t)
Definition build.h:406
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
Definition cf_parse.c:1288
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
Definition cf_parse.c:1723
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:673
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:627
#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_CONF_POINTER_IS_SET(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result, recording if a defaul...
Definition cf_parse.h:349
#define cf_section_rules_push(_cs, _rule)
Definition cf_parse.h:705
#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
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:610
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:106
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
Definition cf_util.c:1363
static fr_atomic_queue_t ** aq
#define MEM(x)
Definition debug.h:38
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition debug.h:272
#define ERROR(fmt,...)
Definition dhcpclient.c:40
#define fr_dict_autofree(_to_free)
Definition dict.h:937
fr_dict_attr_t const * fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor)
Find a common ancestor that two TLV type attributes share.
Definition dict_util.c:2368
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2720
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:316
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:329
fr_dict_enum_value_t const * fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the structure representing an enum value in a fr_dict_attr_t.
Definition dict_util.c:3732
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
Definition dict_util.c:4532
#define fr_dict_autoload(_to_load)
Definition dict.h:934
#define FR_DICT_MAX_TLV_STACK
Maximum TLV stack size.
Definition dict.h:541
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:335
char const * name
Enum name.
Definition dict.h:278
#define FR_DICT_ATTR_MAX_NAME_LEN
Maximum length of a attribute name.
Definition dict.h:525
Specifies an attribute which must be present for the module to function.
Definition dict.h:315
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:328
Value of an enumerated attribute.
Definition dict.h:277
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t io_funcs)
Definition fopencookie.c:99
cookie_close_function_t close
Definition fopencookie.h:55
cookie_seek_function_t seek
Definition fopencookie.h:54
cookie_read_function_t read
Definition fopencookie.h:52
cookie_write_function_t write
Definition fopencookie.h:53
talloc_free(hp)
static fr_rb_tree_t * filename_tree
Definition log.c:234
void log_request_hex(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, uint8_t const *data, size_t data_len)
Definition log.c:982
static const conf_parser_t log_config[]
Definition log.c:1154
static bool log_timestamp
Definition log.c:1148
fr_rb_node_t filename_node
tree by name
Definition log.c:220
static fr_sbuff_t * log_request_oid_buff(void)
Allocate an extensible sbuff for printing OID strings.
Definition log.c:749
static fr_dict_attr_t const * attr_module_failure_message
Definition log.c:206
void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a list of protocol fr_pair_ts.
Definition log.c:901
static char const * log_destination
Definition log.c:1147
void log_request_packet(request_t *request, fr_packet_t *packet, fr_pair_list_t *list, fr_dict_attr_t const *type_da, bool received, bool id)
Print a packet which we received or sent.
Definition log.c:852
fr_rb_node_t id_node
tree by ID
Definition log.c:230
fr_table_num_sorted_t const log_destination_table[]
Definition log.c:186
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
Definition log.c:609
int log_global_init(fr_log_t *log, bool daemonize)
Initialises the server logging functionality, and the underlying libfreeradius log.
Definition log.c:1322
static fr_rb_tree_t * dst_tree
Definition log.c:233
static _Thread_local fr_sbuff_t * fr_log_request_oid_buff
Definition log.c:56
fr_dict_autoload_t log_dict[]
Definition log.c:201
static fr_dict_t const * dict_freeradius
Definition log.c:198
static int _fr_log_request_oid_buff_free(void *arg)
Cleanup the memory pool used by the OID sbuff.
Definition log.c:741
void log_request_perror(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Drain any outstanding messages from the fr_strerror buffers.
Definition log.c:680
static int _log_free(fr_log_t *log)
Definition log.c:1139
size_t log_destination_table_len
Definition log.c:194
bool log_rdebug_enabled(fr_log_lvl_t lvl, request_t const *request)
Whether a request specific debug message should be logged.
Definition log.c:267
fr_rb_node_t name_node
tree by name only
Definition log.c:229
void log_request_marker(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *str, size_t str_len, ssize_t marker_idx, char const *marker_fmt,...)
Write the string being parsed, and a marker showing where the parse error occurred.
Definition log.c:933
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
Definition log.c:827
static fr_cmp_ret_t _log_track_name_cmp(void const *two, void const *one)
Definition log.c:1290
int log_parse_section(CONF_SECTION *cs)
Parse a named logging section.
Definition log.c:1187
fr_table_num_sorted_t const syslog_severity_table[]
Syslog severity table.
Definition log.c:151
fr_log_t * log_dst_by_name(char const *name)
Get a logging destination by name.
Definition log.c:1128
fr_dict_attr_autoload_t log_dict_attr[]
Definition log.c:209
fr_log_t ** log
where the logs should go
Definition log.c:227
static fr_rb_tree_t * src_tree
Definition log.c:235
fr_log_t * original
the original fr_log_t
Definition log.c:226
void log_fatal(fr_log_t const *log, char const *file, int line, char const *fmt,...)
Log a fatal error, then exit.
Definition log.c:1093
static void vlog_module_failure_msg(request_t *request, char const *fmt, va_list ap)
Add a module failure message fr_pair_t to the request.
Definition log.c:564
fr_log_t * log
pointer to the log structure
Definition log.c:216
void log_request_fd_event(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, void *uctx)
Function to provide as the readable callback to the event loop.
Definition log.c:1010
size_t syslog_facility_table_len
Definition log.c:143
static bool log_timestamp_is_set
Definition log.c:1149
static void log_always(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination without evaluating its debug level.
Definition log.c:248
CONF_SECTION * cs
where this log configuration came from
Definition log.c:217
size_t syslog_severity_table_len
Definition log.c:184
static char const spaces[]
Definition log.c:196
char const * name
name of this logging source
Definition log.c:224
void log_request_error(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to error logging functions.
Definition log.c:643
char const * name
name of this logging destination
Definition log.c:215
uint32_t id
LOG_ID of this source.
Definition log.c:225
static fr_cmp_ret_t _log_track_filename_cmp(void const *two, void const *one)
Definition log.c:1298
void vlog_request(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)
Send a log message to its destination, possibly including fields from the request.
Definition log.c:293
static void log_register_dst(char const *name, fr_log_t *log, CONF_SECTION *cs)
Register a logging destination.
Definition log.c:1107
void log_request_pair(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_t const *vp, char const *prefix)
Print a fr_pair_t.
Definition log.c:786
fr_rb_node_t name_node
tree by name
Definition log.c:219
static _Thread_local TALLOC_CTX * fr_vlog_request_pool
Definition log.c:55
fr_table_num_sorted_t const syslog_facility_table[]
Syslog facility table.
Definition log.c:66
void log_global_free(void)
Definition log.c:1358
static int _fr_vlog_request_pool_free(void *arg)
Cleanup the memory pool used by vlog_request.
Definition log.c:277
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition log.h:460
#define log_dst_foreach(_head, _iter)
Iterate over the contents of a log_dst_t.
Definition log.h:773
request_t * request
request to log messages in the context of.
Definition log.h:86
#define RDEBUG_ENABLEDX(_x)
True if specified lvl is enabled.
Definition log.h:355
#define RDEBUGX(_l, fmt,...)
Definition log.h:357
fr_log_lvl_t lvl
Priority of the message.
Definition log.h:85
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
Definition log.h:264
char const * prefix
To add to log messages.
Definition log.h:87
fr_log_type_t type
What type of log message it is.
Definition log.h:84
#define RINDENT()
Indent R* messages by one level.
Definition log.h:447
Definition log.h:70
Context structure for the log fd event function.
Definition log.h:83
ssize_t rad_filename_escape(UNUSED request_t *request, char *out, size_t outlen, char const *in, UNUSED void *arg)
Escapes the raw string such that it should be safe to use as part of a file path.
Definition util.c:178
Stores all information relating to an event list.
Definition event.c:377
ssize_t fr_mkdir(int *fd_out, char const *path, ssize_t len, mode_t mode, fr_mkdir_func_t func, void *uctx)
Create directories that are missing in the specified path.
Definition file.c:218
fr_table_num_ordered_t const fr_log_levels[]
Maps log categories to message prefixes.
Definition log.c:262
int fr_log_init_legacy(fr_log_t *log, bool daemonize)
Initialise file descriptors based on logging destination.
Definition log.c:993
int fr_log_init_syslog(fr_log_t *log)
Initialise a syslog logging destination.
Definition log.c:1221
int fr_log_init_std(fr_log_t *log, fr_log_dst_t dst_type)
Initialise log dst for stdout, stderr or /dev/null.
Definition log.c:1114
int fr_log_init_file(fr_log_t *log, char const *file)
Initialise a file logging destination.
Definition log.c:1169
bool log_dates_utc
Definition log.c:306
@ L_DST_NULL
Discard log messages.
Definition log.h:80
@ L_DST_STDERR
Log to stderr.
Definition log.h:78
@ L_DST_FILES
Log to a file on disk.
Definition log.h:76
@ L_DST_FUNC
Send log messages to a FILE*, via fopencookie()
Definition log.h:79
@ L_DST_NUM_DEST
Definition log.h:81
@ L_DST_STDOUT
Log to stdout.
Definition log.h:75
@ L_DST_SYSLOG
Log to syslog.
Definition log.h:77
@ L_TIMESTAMP_ON
Always log timestamps.
Definition log.h:87
@ L_TIMESTAMP_OFF
Never log timestamps.
Definition log.h:88
@ L_TIMESTAMP_AUTO
Timestamp logging preference not specified.
Definition log.h:85
fr_log_lvl_t
Definition log.h:64
@ L_DBG_LVL_1
Highest priority debug messages (-x).
Definition log.h:67
#define fr_vlog(_log, _lvl, _file, _line, _fmt, _ap)
Definition log.h:166
fr_log_type_t
Definition log.h:51
@ L_DBG_WARN_REQ
Less severe warning only displayed when debugging is enabled.
Definition log.h:60
@ L_ERR
Error message.
Definition log.h:53
@ L_DBG_ERR
Error only displayed when debugging is enabled.
Definition log.h:59
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
Definition log.h:61
@ L_DBG_WARN
Warning only displayed when debugging is enabled.
Definition log.h:58
@ L_DBG
Only displayed when debugging is enabled.
Definition log.h:56
Main server configuration.
Definition main_config.h:59
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_BOOL
A truth value.
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
fr_cmp_ret_t
Result of an ordering comparison.
Definition misc.h:50
struct tm * gmtime_r(time_t const *l_clock, struct tm *result)
Definition missing.c:205
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
Definition pair.c:2659
int fr_pair_value_strdup_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a vp, but don't copy it.
Definition pair.c:2619
char * fr_vasprintf_secure(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Definition print.c:865
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Definition print.c:860
#define fr_assert(_expr)
Definition rad_assert.h:37
#define RDEBUG_ENABLED()
int fr_rb_find(void **found, fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition rb.c:586
int fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition rb.c:637
#define fr_rb_inline_alloc(_ctx, _type, _field, _data_cmp, _data_free)
Allocs a red black tree.
Definition rb.h:269
The main red black tree structure.
Definition rb.h:71
static char const * name
size_t fr_sbuff_shift(fr_sbuff_t *sbuff, size_t shift, bool move_end)
Shift the contents of the sbuff, returning the number of bytes we managed to shift.
Definition sbuff.c:212
bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt)
Efficient terminal string search.
Definition sbuff.c:2311
size_t fr_sbuff_adv_until(fr_sbuff_t *sbuff, size_t len, fr_sbuff_term_t const *tt, char escape_chr)
Wind position until we hit a character in the terminal set.
Definition sbuff.c:2011
#define fr_sbuff_start(_sbuff_or_marker)
#define fr_sbuff_set(_dst, _src)
#define fr_sbuff_current(_sbuff_or_marker)
#define FR_SBUFF_TERMS(...)
Initialise a terminal structure with a list of sorted strings.
Definition sbuff.h:190
#define fr_sbuff_init_out(_out, _start, _len_or_end)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define fr_sbuff_remaining(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_behind(_sbuff_or_marker)
#define fr_sbuff_ahead(_sbuff_or_marker)
Set of terminal elements.
Talloc sbuff extension structure.
Definition sbuff.h:137
#define pair_prepend_request(_attr, _da)
Allocate and prepend a fr_pair_t to the request list.
Definition pair.h:77
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
ssize_t fr_socket_to_str(char *out, size_t outlen, fr_socket_t const *sock, bool received)
Print an fr_socket_t to a string.
Definition socket.c:1018
fr_aka_sim_id_type_t type
fr_pair_t * vp
Definition log.h:93
fr_log_dst_t dst
Log destination.
Definition log.h:94
fr_log_timestamp_t timestamp
Prefix log messages with timestamps.
Definition log.h:107
char const * file
Path to log file.
Definition log.h:110
FILE * handle
Path to log file.
Definition log.h:113
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
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:685
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:804
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:546
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition talloc.h:288
static fr_event_list_t * el
ssize_t xlat_aeval(TALLOC_CTX *ctx, char **out, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx))
Definition xlat_eval.c:1916
unsigned int code
Packet code (type).
Definition packet.h:61
fr_socket_t socket
This packet was received on.
Definition packet.h:57
int id
Packet ID (used to link requests/responses).
Definition packet.h:60
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
#define PAIR_VERIFY(_x)
Definition pair.h:205
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
Definition pair.h:281
static fr_slen_t quote ssize_t fr_pair_print_name(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const **vp_p)
Print an attribute name.
Definition pair_print.c:136
static fr_slen_t parent
Definition pair.h:860
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition strerror.c:737
char const * fr_strerror_pop(void)
Pop the last library error.
Definition strerror.c:685
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
#define fr_strerror_const(_msg)
Definition strerror.h:223
#define FR_TYPE_STRUCTURAL
Definition types.h:316
#define fr_type_is_leaf(_x)
Definition types.h:393
static fr_slen_t data
Definition value.h:1367
#define fr_box_strvalue_len(_val, _len)
Definition value.h:334
static fr_sbuff_err_t char size_t * len
Definition value.h:1062
#define fr_box_uint32(_val)
Definition value.h:360