The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 96d9bb20303e73cb067d7cf525545f32f6b44183 $
19 *
20 * @file tls/log.c
21 * @brief Retrieve errors and log messages from OpenSSL's overly complex logging system.
22 *
23 * @copyright 2016,2021 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 * @copyright 2016 The FreeRADIUS server project
25 */
26RCSID("$Id: 96d9bb20303e73cb067d7cf525545f32f6b44183 $")
27USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
28
29#ifdef WITH_TLS
30#define LOG_PREFIX "tls"
31
32#include <freeradius-devel/util/debug.h>
33#include <freeradius-devel/util/atexit.h>
34#include <freeradius-devel/tls/strerror.h>
35#include <freeradius-devel/tls/utils.h>
36#include <stdatomic.h>
37
38#include "log.h"
39
40/** Holds the state of a log BIO
41 *
42 * Most of these fields are expected to change between uses of the BIO.
43 *
44 * BIOs do not have indexed extension structures like other structures in OpenSSL,
45 * so we're forced to place all information in a structure, and populate it just
46 * prior to a BIO being used.
47 *
48 * These BIOs are thread local to avoid conflicts or locking issues.
49 */
50typedef struct {
51 BIO *bio; //!< Logging bio to write to.
52 fr_sbuff_t sbuff; //!< Used to aggregate line data.
53 fr_sbuff_uctx_talloc_t tctx; //!< extra talloc information for the sbuff.
54 fr_sbuff_marker_t logged_m; //!< How much data has been written.
55
56 request_t *request; //!< the current request. Only used for the
57 ///< request log BIOs.
58 fr_log_type_t type; //!< The type of log messages the bio will produce.
59 fr_log_lvl_t lvl; //!< Level to log message at.
60 char const *file; //!< File this log bio was bound on.
61 int line; //!< Line this log bio was bound on.
62} fr_tls_log_bio_t;
63
64/** Template for the thread local request log BIOs
65 */
66static BIO_METHOD *tls_request_log_meth;
67
68/** Template for the global log BIOs
69 */
70static BIO_METHOD *tls_global_log_meth;
71
72/** Counter for users of the request log bio
73 *
74 */
75static _Atomic(uint32_t) tls_request_log_ref;
76
77/** Counter for users of the global log bio
78 *
79 */
80static _Atomic(uint32_t) tls_global_log_ref;
81
82/** Thread local request log BIO
83 */
84static _Thread_local fr_tls_log_bio_t *request_log_bio;
85
86/** Thread local global log BIO
87 */
88static _Thread_local fr_tls_log_bio_t *global_log_bio;
89
90/** Print out the current stack of certs
91 *
92 * @param[in] file File where this function is being called.
93 * @param[in] line Line where this function is being called.
94 * @param[in] request Current request, may be NULL.
95 * @param[in] log_type The type of log message to produce L_INFO, L_ERR, L_DBG etc...
96 * @param[in] chain The certificate chain.
97 * @param[in] cert The leaf certificate.
98 */
99void _fr_tls_chain_log(char const *file, int line,
100 request_t *request, fr_log_type_t log_type,
101 STACK_OF(X509) *chain, X509 *cert)
102{
103 /*
104 * Dump to the thread local buffer
105 */
107 _fr_tls_strerror_push_chain(file, line, chain, cert);
108 if (request) {
109 log_request_perror(log_type, L_DBG_LVL_OFF, request, file, line, NULL);
110 } else {
111 fr_perror(NULL);
112 }
113}
114
115/** Print out the current stack of certs
116 *
117 * @param[in] file File where this function is being called.
118 * @param[in] line Line where this function is being called.
119 * @param[in] request Current request, may be NULL.
120 * @param[in] log_type The type of log message to produce L_INFO, L_ERR, L_DBG etc...
121 * @param[in] chain The certificate chain.
122 * @param[in] cert The leaf certificate.
123 * @param[in] marker The certificate we want to mark.
124 */
125void _fr_tls_chain_marker_log(char const *file, int line,
126 request_t *request, fr_log_type_t log_type,
127 STACK_OF(X509) *chain, X509 *cert, X509 *marker)
128{
129 /*
130 * Dump to the thread local buffer
131 */
133 _fr_tls_strerror_push_chain_marker(file, line, chain, cert, marker);
134 if (request) {
135 log_request_perror(log_type, L_DBG_LVL_OFF, request, file, line, NULL);
136 } else {
137 fr_perror(NULL);
138 }
139}
140
141/** Print out the current stack of X509 objects (certificates only)
142 *
143 * @param[in] file File where this function is being called.
144 * @param[in] line Line where this function is being called.
145 * @param[in] request Current request, may be NULL.
146 * @param[in] log_type The type of log message to produce L_INFO, L_ERR, L_DBG etc...
147 * @param[in] objects A stack of X509 objects
148 */
149void _fr_tls_x509_objects_log(char const *file, int line,
150 request_t *request, fr_log_type_t log_type,
151 STACK_OF(X509_OBJECT) *objects)
152{
153
155 _fr_tls_strerror_push_x509_objects(file, line, objects);
156 if (request) {
157 log_request_perror(log_type, L_DBG_LVL_OFF, request, file, line, NULL);
158 } else {
159 fr_perror(NULL);
160 }
161}
162
163/** Print errors raised by OpenSSL I/O functions
164 *
165 * Drains the thread local OpenSSL error queue, and prints out errors
166 * based on the SSL handle and the return code of the I/O function.
167 *
168 * OpenSSL lists I/O functions to be:
169 * - SSL_connect
170 * - SSL_accept
171 * - SSL_do_handshake
172 * - SSL_read
173 * - SSL_peek
174 * - SSL_write
175 *
176 * @param request The current request (may be NULL).
177 * @param err returned from SSL_get_error().
178 * @param fmt Error message describing the operation being attempted.
179 * @param ... Arguments for msg.
180 * @return
181 * - 0 TLS session may still be viable.
182 * - -1 TLS session cannot continue.
183 */
184int fr_tls_log_io_error(request_t *request, int err, char const *fmt, ...)
185{
186 static fr_table_num_ordered_t const ssl_io_error_table[] = {
187 { L("SSL_ERROR_NONE"), SSL_ERROR_NONE },
188 { L("SSL_ERROR_ZERO_RETURN"), SSL_ERROR_ZERO_RETURN },
189 { L("SSL_ERROR_WANT_READ"), SSL_ERROR_WANT_READ },
190 { L("SSL_ERROR_WANT_WRITE"), SSL_ERROR_WANT_WRITE },
191 { L("SSL_ERROR_WANT_CONNECT"), SSL_ERROR_WANT_CONNECT },
192 { L("SSL_ERROR_WANT_ACCEPT"), SSL_ERROR_WANT_ACCEPT },
193 { L("SSL_ERROR_WANT_X509_LOOKUP"), SSL_ERROR_WANT_X509_LOOKUP },
194 { L("SSL_ERROR_WANT_ASYNC"), SSL_ERROR_WANT_ASYNC },
195 { L("SSL_ERROR_WANT_ASYNC_JOB"), SSL_ERROR_WANT_ASYNC_JOB },
196 { L("SSL_ERROR_WANT_CLIENT_HELLO_CB"), SSL_ERROR_WANT_CLIENT_HELLO_CB },
197 { L("SSL_ERROR_SYSCALL"), SSL_ERROR_SYSCALL },
198 { L("SSL_ERROR_SSL"), SSL_ERROR_SSL }
199 };
200 static size_t ssl_io_error_table_len = NUM_ELEMENTS(ssl_io_error_table);
201
202 va_list ap;
203 char *msg = NULL;
204
205 switch (err) {
206 /*
207 * These seem to be harmless and already "dealt
208 * with" by our non-blocking environment. NB:
209 * "ZERO_RETURN" is the clean "error"
210 * indicating a successfully closed SSL
211 * tunnel. We let this happen because our IO
212 * loop should not appear to have broken on
213 * this condition - and outside the IO loop, the
214 * "shutdown" state is checked.
215 *
216 * Don't print anything if we ignore the error.
217 */
218 case SSL_ERROR_NONE:
219 case SSL_ERROR_WANT_READ:
220 case SSL_ERROR_WANT_WRITE:
221 case SSL_ERROR_WANT_X509_LOOKUP:
222 case SSL_ERROR_ZERO_RETURN:
224 va_start(ap, fmt);
225 msg = fr_vasprintf(NULL, fmt, ap);
226 va_end(ap);
227
228 ROPTIONAL(RDEBUG2, DEBUG2, "%s - %s (%i)",
229 msg, fr_table_str_by_value(ssl_io_error_table, err, "<UNKNOWN>"), err);
231 }
232 break;
233
234 /*
235 * These seem to be indications of a genuine
236 * error that should result in the SSL tunnel
237 * being regarded as "dead".
238 */
239 case SSL_ERROR_SYSCALL:
240 va_start(ap, fmt);
241 msg = fr_vasprintf(NULL, fmt, ap);
242 va_end(ap);
243
244 ROPTIONAL(REDEBUG, ERROR, "%s - System call (I/O) error - %s (%i)",
245 msg, fr_table_str_by_value(ssl_io_error_table, err, "<UNKNOWN>"), err);
246
248 return -1;
249
250 /*
251 * Docs say a more verbose error is available
252 * in the normal error stack.
253 */
254 case SSL_ERROR_SSL:
255 va_start(ap, fmt);
256 (void)fr_tls_strerror_vprintf(fmt, ap);
257 va_end(ap);
258
260 return -1;
261
262 /*
263 * For any other errors that (a) exist, and (b)
264 * crop up - we need to interpret what to do with
265 * them - so "politely inform" the caller that
266 * the code needs updating here.
267 */
268 default:
269 va_start(ap, fmt);
270 msg = fr_vasprintf(NULL, fmt, ap);
271 va_end(ap);
272
273 ROPTIONAL(REDEBUG, ERROR, "%s - TLS session error - %s (%i)",
274 msg, fr_table_str_by_value(ssl_io_error_table, err, "<UNKNOWN>"), err);
275
277
278 return -1;
279 }
280
281 return 0;
282}
283
284
285/** Print errors in the TLS thread local error stack
286 *
287 * Drains the thread local OpenSSL error queue, and prints out errors.
288 *
289 * @param[in] request The current request (may be NULL).
290 * @param[in] msg Error message describing the operation being attempted.
291 * @param[in] ... Arguments for msg.
292 * @return the number of errors drained from the stack.
293 */
294int fr_tls_log(request_t *request, char const *msg, ...)
295{
296 va_list ap;
297 int ret;
298
299 va_start(ap, msg);
300 ret = fr_tls_strerror_vprintf(msg, ap);
301 va_end(ap);
302
304
305 return ret;
306}
307
308/** Clear errors in the TLS thread local error stack
309 *
310 */
311void fr_tls_log_clear(void)
312{
313 while (ERR_get_error() != 0);
314}
315
316/** Increment the bio meth reference counter
317 *
318 */
319static int tls_log_request_bio_create_cb(BIO *bio)
320{
321 atomic_fetch_add(&tls_request_log_ref, 1);
322 BIO_set_init(bio, 1);
323 return 1;
324}
325
326/** Converts BIO_write() calls to request log calls
327 *
328 * This callback is used to glue the output of OpenSSL functions into request log calls.
329 *
330 * @param[in] bio that was written to.
331 * @param[in] in data being written to BIO.
332 * @param[in] len Length of data being written.
333 */
334static int tls_log_request_bio_write_cb(BIO *bio, char const *in, int len)
335{
336 fr_tls_log_bio_t *lb = talloc_get_type_abort(BIO_get_data(bio), fr_tls_log_bio_t);
337 request_t *request = talloc_get_type_abort(lb->request, request_t);
339 char *le;
340
341 /*
342 * Pick the right logging function based on the type
343 */
344 if ((lb->type == L_ERR) || (lb->type == L_DBG_ERR) || (lb->type == L_DBG_ERR_REQ)) {
345 func = log_request_error;
346 } else {
347 func = log_request;
348 }
349
350 /*
351 * OpenSSL feeds us data in fragments so we need
352 * to aggregate it, then look for new line chars
353 * as an indication we need to print the line.
354 */
355 if (fr_sbuff_in_bstrncpy(&lb->sbuff, in, len) < 0) return 0;
356
357 /*
358 * Split incoming data on new lines
359 */
360 while (fr_sbuff_behind(&lb->logged_m)) {
361 le = memchr(fr_sbuff_current(&lb->logged_m), '\n',
362 fr_sbuff_current(&lb->sbuff) - fr_sbuff_current(&lb->logged_m));
363 /*
364 * Wait until we have a complete line
365 */
366 if (le == NULL) break;
367
368 /*
369 * Skip empty lines
370 */
371 if ((le - fr_sbuff_current(&lb->logged_m)) > 0) {
372 func(lb->type, lb->lvl, request, __FILE__, __LINE__, "%pV",
374 le - fr_sbuff_current(&lb->logged_m)));
375 }
376
377 fr_sbuff_set(&lb->logged_m, le + 1);
378 }
379
380 /*
381 * Clear out printed data
382 */
383 fr_sbuff_shift(&lb->sbuff, fr_sbuff_used(&lb->logged_m));
384
385 return len; /* Amount of data written */
386}
387
388/** Converts BIO_puts() calls to request log calls
389 *
390 * This callback is used to glue the output of OpenSSL functions into request log calls.
391 *
392 * @param[in] bio that was written to.
393 * @param[in] in data being written to BIO.
394 */
395static int tls_log_request_bio_puts_cb(BIO *bio, char const *in)
396{
397 return tls_log_request_bio_write_cb(bio, in, strlen(in));
398}
399
400/** Decrement the bio meth reference counter
401 *
402 */
403static int tls_log_request_bio_free_cb(BIO *bio)
404{
405 atomic_fetch_sub(&tls_request_log_ref, 1);
406 BIO_set_init(bio, 0);
407 return 1;
408}
409
410/** Increment the bio meth reference counter
411 *
412 */
413static int tls_log_global_bio_create_cb(BIO *bio)
414{
415 atomic_fetch_add(&tls_global_log_ref, 1);
416 BIO_set_init(bio, 1);
417 return 1;
418}
419
420/** Converts BIO_write() calls to global log calls
421 *
422 * This callback is used to glue the output of OpenSSL functions into global log calls.
423 *
424 * @param[in] bio that was written to.
425 * @param[in] in data being written to BIO.
426 * @param[in] len Length of data being written.
427 */
428static int tls_log_global_bio_write_cb(BIO *bio, char const *in, int len)
429{
430 fr_tls_log_bio_t *lb = talloc_get_type_abort(BIO_get_data(bio), fr_tls_log_bio_t);
431 char *le;
432
433 /*
434 * OpenSSL feeds us data in fragments so we need
435 * to aggregate it, then look for new line chars
436 * as an indication we need to print the line.
437 */
438 if (fr_sbuff_in_bstrncpy(&lb->sbuff, in, len) < 0) return 0;
439
440 /*
441 * Split incoming data on new lines
442 */
443 while (fr_sbuff_behind(&lb->logged_m)) {
444 le = memchr(fr_sbuff_current(&lb->logged_m), '\n',
445 fr_sbuff_current(&lb->sbuff) - fr_sbuff_current(&lb->logged_m));
446 /*
447 * Wait until we have a complete line
448 */
449 if (le == NULL) break;
450
451 /*
452 * Skip empty lines
453 */
454 if ((le - fr_sbuff_current(&lb->logged_m)) > 0) {
455 if (fr_debug_lvl >= lb->lvl) fr_log(&default_log, lb->type, __FILE__, __LINE__,
456 "%pV",
458 le - fr_sbuff_current(&lb->logged_m)));
459 }
460
461 fr_sbuff_set(&lb->logged_m, le + 1);
462 }
463
464 /*
465 * Clear out printed data
466 */
467 fr_sbuff_shift(&lb->sbuff, fr_sbuff_used(&lb->logged_m));
468
469 return len; /* Amount of data written */
470}
471
472/** Converts BIO_puts() calls to global log calls
473 *
474 * This callback is used to glue the output of OpenSSL functions into global log calls.
475 *
476 * @param[in] bio that was written to.
477 * @param[in] in data being written to BIO.
478 */
479static int tls_log_global_bio_puts_cb(BIO *bio, char const *in)
480{
481 return tls_log_global_bio_write_cb(bio, in, strlen(in));
482}
483
484/** Decrement the bio meth reference counter
485 *
486 */
487static int tls_log_global_bio_free_cb(BIO *bio)
488{
489 atomic_fetch_sub(&tls_global_log_ref, 1);
490 BIO_set_init(bio, 0);
491 return 1;
492}
493
494/** Frees a logging bio and its underlying OpenSSL BIO *
495 *
496 */
497static int _fr_tls_log_bio_free(void *log_bio)
498{
499 fr_tls_log_bio_t *our_log_bio = talloc_get_type_abort(log_bio, fr_tls_log_bio_t);
500
501 BIO_free(our_log_bio->bio);
502 our_log_bio->bio = NULL;
503 return talloc_free(our_log_bio);
504}
505
506/** Return a request log BIO to use with OpenSSL logging functions
507 *
508 * @note The contents of the BIO will only be written to the logging system on finding
509 * a new line. If data remains in the BIO when it is re-initialised (this function
510 * is called again), that data will be discarded.
511 *
512 * @note The returned BIO should be assumed to be invalid if the request yields.
513 *
514 * @param[in] file of caller.
515 * @param[in] line of caller.
516 * @param[in] request to temporarily associate with logging BIO.
517 * @param[in] type to temporarily assign to logging bio.
518 * @param[in] lvl to temporarily assign to logging bio.
519 * @return A thread local BIO to pass to OpenSSL logging functions.
520 */
521BIO *_fr_tls_request_log_bio(char const *file, int line, request_t *request, fr_log_type_t type, fr_log_lvl_t lvl)
522{
523 if (unlikely(!request_log_bio)) {
524 fr_tls_log_bio_t *lb;
525
526 MEM(lb = talloc(NULL, fr_tls_log_bio_t));
527 *lb = (fr_tls_log_bio_t) {
528 .bio = BIO_new(tls_request_log_meth),
529 .request = request,
530 .type = type,
531 .lvl = lvl,
532 .file = file,
533 .line = line
534 };
535 MEM(lb->bio);
536 BIO_set_data(lb->bio, lb); /* So we can retrieve the fr_tls_lb_t in the callbacks */
537 fr_sbuff_init_talloc(lb, &lb->sbuff, &lb->tctx, 1024, 10 * 1024); /* start 1k, max 10k */
538 fr_atexit_thread_local(request_log_bio, _fr_tls_log_bio_free, lb);
539 fr_sbuff_marker(&lb->logged_m, &lb->sbuff);
540 return lb->bio;
541 }
542 fr_sbuff_reset_talloc(&request_log_bio->sbuff); /* Reset to initial size */
543 fr_sbuff_marker(&request_log_bio->logged_m, &request_log_bio->sbuff);
544 request_log_bio->request = request;
545 request_log_bio->type = type;
546 request_log_bio->lvl = lvl;
547 request_log_bio->file = file;
548 request_log_bio->line = line;
549
550 return request_log_bio->bio;
551}
552
553/** Return a global log BIO to use with OpenSSL logging functions
554 *
555 * @note The contents of the BIO will only be written to the logging system on finding
556 * a new line. If data remains in the BIO when it is re-initialised (this function
557 * is called again), that data will be discarded.
558 *
559 * @note The returned BIO should be assumed to be invalid if the current request yields.
560 *
561 * @param[in] file of caller.
562 * @param[in] line of caller.
563 * @param[in] type to temporarily assign to logging bio.
564 * @param[in] lvl to temporarily assign to logging bio.
565 * @return A thread local BIO to pass to OpenSSL logging functions.
566 */
567BIO *_fr_tls_global_log_bio(char const *file, int line, fr_log_type_t type, fr_log_lvl_t lvl)
568{
569 if (unlikely(!global_log_bio)) {
570 fr_tls_log_bio_t *lb;
571
572 MEM(lb = talloc(NULL, fr_tls_log_bio_t));
573 *lb = (fr_tls_log_bio_t) {
574 .bio = BIO_new(tls_global_log_meth),
575 .type = type,
576 .lvl = lvl,
577 .file = file,
578 .line = line
579 };
580 MEM(lb->bio);
581 BIO_set_data(lb->bio, lb); /* So we can retrieve the fr_tls_lb_t in the callbacks */
582 fr_sbuff_init_talloc(lb, &lb->sbuff, &lb->tctx, 1024, 10 * 1024); /* start 1k, max 10k */
583 fr_atexit_thread_local(global_log_bio, _fr_tls_log_bio_free, lb);
584 fr_sbuff_marker(&lb->logged_m, &lb->sbuff);
585 return lb->bio;
586 }
587 fr_sbuff_reset_talloc(&request_log_bio->sbuff); /* Reset to initial size */
588 fr_sbuff_marker(&request_log_bio->logged_m, &request_log_bio->sbuff);
589 global_log_bio->type = type;
590 global_log_bio->lvl = lvl;
591 global_log_bio->file = file;
592 global_log_bio->line = line;
593
594 return global_log_bio->bio;
595}
596
597/** Initialise the BIO logging meths which are used to create thread local logging BIOs
598 *
599 */
600int fr_tls_log_init(void)
601{
602 /*
603 * As per the boringSSL documentation
604 *
605 * BIO_TYPE_START is the first user-allocated |BIO| type.
606 * No pre-defined type, flag bits aside, may exceed this
607 * value.
608 *
609 * The low byte here defines the BIO ID, and the high byte
610 * defines its capabilities.
611 */
612 tls_request_log_meth = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "fr_tls_request_log");
613 if (unlikely(!tls_request_log_meth)) return -1;
614
615 BIO_meth_set_create(tls_request_log_meth, tls_log_request_bio_create_cb);
616 BIO_meth_set_write(tls_request_log_meth, tls_log_request_bio_write_cb);
617 BIO_meth_set_puts(tls_request_log_meth, tls_log_request_bio_puts_cb);
618 BIO_meth_set_destroy(tls_request_log_meth, tls_log_request_bio_free_cb);
619
620 tls_global_log_meth = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "fr_tls_global_log");
621 if (unlikely(!tls_global_log_meth)) {
622 BIO_meth_free(tls_request_log_meth);
623 tls_request_log_meth = NULL;
624 return -1;
625 }
626
627 BIO_meth_set_create(tls_global_log_meth, tls_log_global_bio_create_cb);
628 BIO_meth_set_write(tls_global_log_meth, tls_log_global_bio_write_cb);
629 BIO_meth_set_puts(tls_global_log_meth, tls_log_global_bio_puts_cb);
630 BIO_meth_set_destroy(tls_global_log_meth, tls_log_global_bio_free_cb);
631
632 return 0;
633}
634
635/** Free the global log method templates
636 *
637 */
638void fr_tls_log_free(void)
639{
640 /*
641 * These must be freed first else
642 * we get crashes in the OpenSSL
643 * code when we try to free them.
644 */
645 fr_assert_msg(atomic_load(&tls_request_log_ref) == 0, "request log BIO refs remaining %u", atomic_load(&tls_request_log_ref));
646 fr_assert_msg(atomic_load(&tls_global_log_ref) == 0, "global log BIO refs remaining %u", atomic_load(&tls_global_log_ref));
647
648 if (tls_request_log_meth) {
649 BIO_meth_free(tls_request_log_meth);
650 tls_request_log_meth = NULL;
651 }
652
653 if (tls_global_log_meth) {
654 BIO_meth_free(tls_global_log_meth);
655 tls_global_log_meth = NULL;
656 }
657}
658#endif /* WITH_TLS */
int const char * file
Definition acutest.h:702
va_end(args)
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
va_start(args, fmt)
#define fr_atexit_thread_local(_name, _free, _uctx)
Definition atexit.h:221
#define USES_APPLE_DEPRECATED_API
Definition build.h:470
#define RCSID(id)
Definition build.h:483
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define unlikely(_x)
Definition build.h:381
#define NUM_ELEMENTS(_t)
Definition build.h:337
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
Definition debug.h:210
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
static fr_slen_t err
Definition dict.h:824
static fr_slen_t in
Definition dict.h:824
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:612
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:679
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:647
#define PERROR(_fmt,...)
Definition log.h:228
#define DEBUG_ENABLED2
True if global debug level 1-2 messages are enabled.
Definition log.h:258
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition log.h:528
void(* log_request_func_t)(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Function signature for log_request functions.
Definition log.h:93
#define RPERROR(fmt,...)
Definition log.h:302
talloc_free(reap)
int fr_debug_lvl
Definition log.c:43
fr_log_t default_log
Definition log.c:291
void fr_log(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.
Definition log.c:583
fr_log_lvl_t
Definition log.h:67
@ L_DBG_LVL_OFF
No debug messages.
Definition log.h:69
fr_log_type_t
Definition log.h:54
@ L_ERR
Error message.
Definition log.h:56
@ L_DBG_ERR
Error only displayed when debugging is enabled.
Definition log.h:62
@ L_DBG_ERR_REQ
Less severe error only displayed when debugging is enabled.
Definition log.h:64
unsigned int uint32_t
char * fr_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Definition print.c:851
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG_ENABLED2()
Definition radclient.h:50
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define DEBUG2(fmt,...)
Definition radclient.h:43
size_t fr_sbuff_shift(fr_sbuff_t *sbuff, size_t shift)
Shift the contents of the sbuff, returning the number of bytes we managed to shift.
Definition sbuff.c:195
int fr_sbuff_reset_talloc(fr_sbuff_t *sbuff)
Reset a talloced buffer to its initial length, clearing any data stored.
Definition sbuff.c:454
ssize_t fr_sbuff_in_bstrncpy(fr_sbuff_t *sbuff, char const *str, size_t len)
Copy bytes into the sbuff up to the first \0.
Definition sbuff.c:1480
#define fr_sbuff_set(_dst, _src)
#define fr_sbuff_current(_sbuff_or_marker)
#define fr_sbuff_used(_sbuff_or_marker)
#define fr_sbuff_behind(_sbuff_or_marker)
Talloc sbuff extension structure.
Definition sbuff.h:139
fr_aka_sim_id_type_t type
#define _Atomic(T)
Definition stdatomic.h:77
#define atomic_fetch_sub(object, operand)
Definition stdatomic.h:339
#define atomic_load(object)
Definition stdatomic.h:343
#define atomic_fetch_add(object, operand)
Definition stdatomic.h:333
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:772
An element in an arbitrarily ordered array of name to num mappings.
Definition table.h:57
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition strerror.c:733
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition strerror.c:577
#define fr_box_strvalue_len(_val, _len)
Definition value.h:286