source: azure_iot_hub_f767zi/trunk/wolfssl-4.4.0/wolfcrypt/src/logging.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 22.3 KB
Line 
1/* logging.c
2 *
3 * Copyright (C) 2006-2020 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22
23#ifdef HAVE_CONFIG_H
24 #include <config.h>
25#endif
26
27#include <wolfssl/wolfcrypt/settings.h>
28
29#include <wolfssl/wolfcrypt/logging.h>
30#include <wolfssl/wolfcrypt/error-crypt.h>
31#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
32/* avoid adding WANT_READ and WANT_WRITE to error queue */
33#include <wolfssl/error-ssl.h>
34#endif
35
36#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
37static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */
38
39/* accessing any node from the queue should be wrapped in a lock of
40 * debug_mutex */
41static void* wc_error_heap;
42struct wc_error_queue {
43 void* heap; /* the heap hint used with nodes creation */
44 struct wc_error_queue* next;
45 struct wc_error_queue* prev;
46 char error[WOLFSSL_MAX_ERROR_SZ];
47 char file[WOLFSSL_MAX_ERROR_SZ];
48 int value;
49 int line;
50};
51volatile struct wc_error_queue* wc_errors;
52static struct wc_error_queue* wc_current_node;
53static struct wc_error_queue* wc_last_node;
54/* pointer to last node in queue to make insertion O(1) */
55#endif
56
57#ifdef WOLFSSL_FUNC_TIME
58/* WARNING: This code is only to be used for debugging performance.
59 * The code is not thread-safe.
60 * Do not use WOLFSSL_FUNC_TIME in production code.
61 */
62static double wc_func_start[WC_FUNC_COUNT];
63static double wc_func_time[WC_FUNC_COUNT] = { 0, };
64static const char* wc_func_name[WC_FUNC_COUNT] = {
65 "SendHelloRequest",
66 "DoHelloRequest",
67 "SendClientHello",
68 "DoClientHello",
69 "SendServerHello",
70 "DoServerHello",
71 "SendEncryptedExtensions",
72 "DoEncryptedExtensions",
73 "SendCertificateRequest",
74 "DoCertificateRequest",
75 "SendCertificate",
76 "DoCertificate",
77 "SendCertificateVerify",
78 "DoCertificateVerify",
79 "SendFinished",
80 "DoFinished",
81 "SendKeyUpdate",
82 "DoKeyUpdate",
83 "SendEarlyData",
84 "DoEarlyData",
85 "SendNewSessionTicket",
86 "DoNewSessionTicket",
87 "SendServerHelloDone",
88 "DoServerHelloDone",
89 "SendTicket",
90 "DoTicket",
91 "SendClientKeyExchange",
92 "DoClientKeyExchange",
93 "SendCertificateStatus",
94 "DoCertificateStatus",
95 "SendServerKeyExchange",
96 "DoServerKeyExchange",
97 "SendEarlyData",
98 "DoEarlyData",
99};
100
101#include <sys/time.h>
102
103/* WARNING: This function is not portable. */
104static WC_INLINE double current_time(int reset)
105{
106 struct timeval tv;
107 gettimeofday(&tv, 0);
108 (void)reset;
109
110 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
111}
112#endif /* WOLFSSL_FUNC_TIME */
113
114#ifdef DEBUG_WOLFSSL
115
116/* Set these to default values initially. */
117static wolfSSL_Logging_cb log_function = NULL;
118static int loggingEnabled = 0;
119
120#if defined(WOLFSSL_APACHE_MYNEWT)
121#include "log/log.h"
122static struct log mynewt_log;
123#endif /* WOLFSSL_APACHE_MYNEWT */
124
125#endif /* DEBUG_WOLFSSL */
126
127
128/* allow this to be set to NULL, so logs can be redirected to default output */
129int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)
130{
131#ifdef DEBUG_WOLFSSL
132 log_function = f;
133 return 0;
134#else
135 (void)f;
136 return NOT_COMPILED_IN;
137#endif
138}
139
140/* allow this to be set to NULL, so logs can be redirected to default output */
141wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void)
142{
143#ifdef DEBUG_WOLFSSL
144 return log_function;
145#else
146 return NULL;
147#endif
148}
149
150
151int wolfSSL_Debugging_ON(void)
152{
153#ifdef DEBUG_WOLFSSL
154 loggingEnabled = 1;
155#if defined(WOLFSSL_APACHE_MYNEWT)
156 log_register("wolfcrypt", &mynewt_log, &log_console_handler, NULL, LOG_SYSLEVEL);
157#endif /* WOLFSSL_APACHE_MYNEWT */
158 return 0;
159#else
160 return NOT_COMPILED_IN;
161#endif
162}
163
164
165void wolfSSL_Debugging_OFF(void)
166{
167#ifdef DEBUG_WOLFSSL
168 loggingEnabled = 0;
169#endif
170}
171
172#ifdef WOLFSSL_FUNC_TIME
173/* WARNING: This code is only to be used for debugging performance.
174 * The code is not thread-safe.
175 * Do not use WOLFSSL_FUNC_TIME in production code.
176 */
177void WOLFSSL_START(int funcNum)
178{
179 double now = current_time(0) * 1000.0;
180#ifdef WOLFSSL_FUNC_TIME_LOG
181 fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]);
182#endif
183 wc_func_start[funcNum] = now;
184}
185
186void WOLFSSL_END(int funcNum)
187{
188 double now = current_time(0) * 1000.0;
189 wc_func_time[funcNum] += now - wc_func_start[funcNum];
190#ifdef WOLFSSL_FUNC_TIME_LOG
191 fprintf(stderr, "%17.3f: END - %s\n", now, wc_func_name[funcNum]);
192#endif
193}
194
195void WOLFSSL_TIME(int count)
196{
197 int i;
198 double avg, total = 0;
199
200 for (i = 0; i < WC_FUNC_COUNT; i++) {
201 if (wc_func_time[i] > 0) {
202 avg = wc_func_time[i] / count;
203 fprintf(stderr, "%8.3f ms: %s\n", avg, wc_func_name[i]);
204 total += avg;
205 }
206 }
207 fprintf(stderr, "%8.3f ms\n", total);
208}
209#endif
210
211#ifdef DEBUG_WOLFSSL
212
213#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
214 /* see wc_port.h for fio.h and nio.h includes */
215#elif defined(WOLFSSL_SGX)
216 /* Declare sprintf for ocall */
217 int sprintf(char* buf, const char *fmt, ...);
218#elif defined(WOLFSSL_DEOS)
219#elif defined(MICRIUM)
220 #if (BSP_SER_COMM_EN == DEF_ENABLED)
221 #include <bsp_ser.h>
222 #endif
223#elif defined(WOLFSSL_USER_LOG)
224 /* user includes their own headers */
225#elif defined(WOLFSSL_ESPIDF)
226 #include "esp_types.h"
227 #include "esp_log.h"
228#elif defined(WOLFSSL_TELIT_M2MB)
229 #include <stdio.h>
230 #include "m2m_log.h"
231#elif defined(WOLFSSL_ANDROID_DEBUG)
232 #include <android/log.h>
233#else
234 #include <stdio.h> /* for default printf stuff */
235#endif
236
237#if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
238 int dc_log_printf(char*, ...);
239#endif
240
241static void wolfssl_log(const int logLevel, const char *const logMessage)
242{
243 if (log_function)
244 log_function(logLevel, logMessage);
245 else {
246#if defined(WOLFSSL_USER_LOG)
247 WOLFSSL_USER_LOG(logMessage);
248#elif defined(WOLFSSL_LOG_PRINTF)
249 printf("%s\n", logMessage);
250
251#elif defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
252 dc_log_printf("%s\n", logMessage);
253#elif defined(WOLFSSL_DEOS)
254 printf("%s\r\n", logMessage);
255#elif defined(MICRIUM)
256 BSP_Ser_Printf("%s\r\n", logMessage);
257#elif defined(WOLFSSL_MDK_ARM)
258 fflush(stdout) ;
259 printf("%s\n", logMessage);
260 fflush(stdout) ;
261#elif defined(WOLFSSL_UTASKER)
262 fnDebugMsg((char*)logMessage);
263 fnDebugMsg("\r\n");
264#elif defined(MQX_USE_IO_OLD)
265 fprintf(_mqxio_stderr, "%s\n", logMessage);
266
267#elif defined(WOLFSSL_APACHE_MYNEWT)
268 LOG_DEBUG(&mynewt_log, LOG_MODULE_DEFAULT, "%s\n", logMessage);
269#elif defined(WOLFSSL_ESPIDF)
270 ESP_LOGI("wolfssl", "%s", logMessage);
271#elif defined(WOLFSSL_ZEPHYR)
272 printk("%s\n", logMessage);
273#elif defined(WOLFSSL_TELIT_M2MB)
274 M2M_LOG_INFO("%s\n", logMessage);
275#elif defined(WOLFSSL_ANDROID_DEBUG)
276 __android_log_print(ANDROID_LOG_VERBOSE, "[wolfSSL]", "%s", logMessage);
277#else
278 fprintf(stderr, "%s\n", logMessage);
279#endif
280 }
281}
282
283#ifndef WOLFSSL_DEBUG_ERRORS_ONLY
284void WOLFSSL_MSG(const char* msg)
285{
286 if (loggingEnabled)
287 wolfssl_log(INFO_LOG , msg);
288}
289
290#ifndef LINE_LEN
291#define LINE_LEN 16
292#endif
293void WOLFSSL_BUFFER(const byte* buffer, word32 length)
294{
295 int i, buflen = (int)length, bufidx;
296 char line[(LINE_LEN * 4) + 3]; /* \t00..0F | chars...chars\0 */
297
298 if (!loggingEnabled) {
299 return;
300 }
301
302 if (!buffer) {
303 wolfssl_log(INFO_LOG, "\tNULL");
304 return;
305 }
306
307 while (buflen > 0) {
308 bufidx = 0;
309 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "\t");
310 bufidx++;
311
312 for (i = 0; i < LINE_LEN; i++) {
313 if (i < buflen) {
314 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "%02x ", buffer[i]);
315 }
316 else {
317 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, " ");
318 }
319 bufidx += 3;
320 }
321
322 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "| ");
323 bufidx++;
324
325 for (i = 0; i < LINE_LEN; i++) {
326 if (i < buflen) {
327 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx,
328 "%c", 31 < buffer[i] && buffer[i] < 127 ? buffer[i] : '.');
329 bufidx++;
330 }
331 }
332
333 wolfssl_log(INFO_LOG, line);
334 buffer += LINE_LEN;
335 buflen -= LINE_LEN;
336 }
337}
338
339
340void WOLFSSL_ENTER(const char* msg)
341{
342 if (loggingEnabled) {
343 char buffer[WOLFSSL_MAX_ERROR_SZ];
344 XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg);
345 wolfssl_log(ENTER_LOG , buffer);
346 }
347}
348
349
350void WOLFSSL_LEAVE(const char* msg, int ret)
351{
352 if (loggingEnabled) {
353 char buffer[WOLFSSL_MAX_ERROR_SZ];
354 XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
355 msg, ret);
356 wolfssl_log(LEAVE_LOG , buffer);
357 }
358}
359
360WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void)
361{
362 return loggingEnabled;
363}
364#endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */
365#endif /* DEBUG_WOLFSSL */
366
367/*
368 * When using OPENSSL_EXTRA or DEBUG_WOLFSSL_VERBOSE macro then WOLFSSL_ERROR is
369 * mapped to new function WOLFSSL_ERROR_LINE which gets the line # and function
370 * name where WOLFSSL_ERROR is called at.
371 */
372#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || \
373 defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
374 defined(OPENSSL_EXTRA)
375
376#if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(NO_ERROR_QUEUE)) \
377 || defined(DEBUG_WOLFSSL_VERBOSE)
378void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line,
379 const char* file, void* usrCtx)
380#else
381void WOLFSSL_ERROR(int error)
382#endif
383{
384#ifdef WOLFSSL_ASYNC_CRYPT
385 if (error != WC_PENDING_E)
386#endif
387 {
388 char buffer[WOLFSSL_MAX_ERROR_SZ];
389
390 #if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && \
391 !defined(NO_ERROR_QUEUE)) || defined(DEBUG_WOLFSSL_VERBOSE)
392 (void)usrCtx; /* a user ctx for future flexibility */
393 (void)func;
394
395 if (wc_LockMutex(&debug_mutex) != 0) {
396 WOLFSSL_MSG("Lock debug mutex failed");
397 XSNPRINTF(buffer, sizeof(buffer),
398 "wolfSSL error occurred, error = %d", error);
399 }
400 else {
401 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
402 /* If running in compatibility mode do not add want read and
403 want right to error queue */
404 if (error != WANT_READ && error != WANT_WRITE) {
405 #endif
406 if (error < 0)
407 error = error - (2 * error); /* get absolute value */
408 XSNPRINTF(buffer, sizeof(buffer),
409 "wolfSSL error occurred, error = %d line:%d file:%s",
410 error, line, file);
411 if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) {
412 WOLFSSL_MSG("Error creating logging node");
413 /* with void function there is no return here, continue on
414 * to unlock mutex and log what buffer was created. */
415 }
416 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
417 }
418 else {
419 XSNPRINTF(buffer, sizeof(buffer),
420 "wolfSSL error occurred, error = %d", error);
421
422 }
423 #endif
424
425 wc_UnLockMutex(&debug_mutex);
426 }
427 #else
428 XSNPRINTF(buffer, sizeof(buffer),
429 "wolfSSL error occurred, error = %d", error);
430 #endif
431
432 #ifdef DEBUG_WOLFSSL
433 if (loggingEnabled)
434 wolfssl_log(ERROR_LOG , buffer);
435 #endif
436 }
437}
438
439void WOLFSSL_ERROR_MSG(const char* msg)
440{
441#ifdef DEBUG_WOLFSSL
442 if (loggingEnabled)
443 wolfssl_log(ERROR_LOG , msg);
444#else
445 (void)msg;
446#endif
447}
448
449#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
450
451#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
452/* Internal function that is called by wolfCrypt_Init() */
453int wc_LoggingInit(void)
454{
455 if (wc_InitMutex(&debug_mutex) != 0) {
456 WOLFSSL_MSG("Bad Init Mutex");
457 return BAD_MUTEX_E;
458 }
459 wc_errors = NULL;
460 wc_current_node = NULL;
461 wc_last_node = NULL;
462
463 return 0;
464}
465
466
467/* internal function that is called by wolfCrypt_Cleanup */
468int wc_LoggingCleanup(void)
469{
470 /* clear logging entries */
471 wc_ClearErrorNodes();
472
473 /* free mutex */
474 if (wc_FreeMutex(&debug_mutex) != 0) {
475 WOLFSSL_MSG("Bad Mutex free");
476 return BAD_MUTEX_E;
477 }
478 return 0;
479}
480
481
482/* peek at an error node
483 *
484 * idx : if -1 then the most recent node is looked at, otherwise search
485 * through queue for node at the given index
486 * file : pointer to internal file string
487 * reason : pointer to internal error reason
488 * line : line number that error happened at
489 *
490 * Returns a negative value in error case, on success returns the nodes error
491 * value which is positive (absolute value)
492 */
493int wc_PeekErrorNode(int idx, const char **file, const char **reason,
494 int *line)
495{
496 struct wc_error_queue* err;
497
498 if (wc_LockMutex(&debug_mutex) != 0) {
499 WOLFSSL_MSG("Lock debug mutex failed");
500 return BAD_MUTEX_E;
501 }
502
503 if (idx < 0) {
504 err = wc_last_node;
505 }
506 else {
507 int i;
508
509 err = (struct wc_error_queue*)wc_errors;
510 for (i = 0; i < idx; i++) {
511 if (err == NULL) {
512 WOLFSSL_MSG("Error node not found. Bad index?");
513 wc_UnLockMutex(&debug_mutex);
514 return BAD_FUNC_ARG;
515 }
516 err = err->next;
517 }
518 }
519
520 if (err == NULL) {
521 WOLFSSL_MSG("No Errors in queue");
522 wc_UnLockMutex(&debug_mutex);
523 return BAD_STATE_E;
524 }
525
526 if (file != NULL) {
527 *file = err->file;
528 }
529
530 if (reason != NULL) {
531 *reason = err->error;
532 }
533
534 if (line != NULL) {
535 *line = err->line;
536 }
537
538 wc_UnLockMutex(&debug_mutex);
539
540 return err->value;
541}
542
543
544/* Pulls the current node from error queue and increments current state.
545 * Note: this does not delete nodes because input arguments are pointing to
546 * node buffers.
547 *
548 * file pointer to file that error was in. Can be NULL to return no file.
549 * reason error string giving reason for error. Can be NULL to return no reason.
550 * line return line number of where error happened.
551 *
552 * returns the error value on success and BAD_MUTEX_E or BAD_STATE_E on failure
553 */
554int wc_PullErrorNode(const char **file, const char **reason, int *line)
555{
556 struct wc_error_queue* err;
557 int value;
558
559 if (wc_LockMutex(&debug_mutex) != 0) {
560 WOLFSSL_MSG("Lock debug mutex failed");
561 return BAD_MUTEX_E;
562 }
563
564 err = wc_current_node;
565 if (err == NULL) {
566 WOLFSSL_MSG("No Errors in queue");
567 wc_UnLockMutex(&debug_mutex);
568 return BAD_STATE_E;
569 }
570
571 if (file != NULL) {
572 *file = err->file;
573 }
574
575 if (reason != NULL) {
576 *reason = err->error;
577 }
578
579 if (line != NULL) {
580 *line = err->line;
581 }
582
583 value = err->value;
584 wc_current_node = err->next;
585 wc_UnLockMutex(&debug_mutex);
586
587 return value;
588}
589
590
591/* create new error node and add it to the queue
592 * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal
593 * function. debug_mutex should be locked before a call to this function. */
594int wc_AddErrorNode(int error, int line, char* buf, char* file)
595{
596#if defined(NO_ERROR_QUEUE)
597 (void)error;
598 (void)line;
599 (void)buf;
600 (void)file;
601 WOLFSSL_MSG("Error queue turned off, can not add nodes");
602#else
603 struct wc_error_queue* err;
604 err = (struct wc_error_queue*)XMALLOC(
605 sizeof(struct wc_error_queue), wc_error_heap, DYNAMIC_TYPE_LOG);
606 if (err == NULL) {
607 WOLFSSL_MSG("Unable to create error node for log");
608 return MEMORY_E;
609 }
610 else {
611 int sz;
612
613 XMEMSET(err, 0, sizeof(struct wc_error_queue));
614 err->heap = wc_error_heap;
615 sz = (int)XSTRLEN(buf);
616 if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {
617 sz = WOLFSSL_MAX_ERROR_SZ - 1;
618 }
619 if (sz > 0) {
620 XMEMCPY(err->error, buf, sz);
621 }
622
623 sz = (int)XSTRLEN(file);
624 if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {
625 sz = WOLFSSL_MAX_ERROR_SZ - 1;
626 }
627 if (sz > 0) {
628 XMEMCPY(err->file, file, sz);
629 }
630
631 err->value = error;
632 err->line = line;
633
634 /* make sure is terminated */
635 err->error[WOLFSSL_MAX_ERROR_SZ - 1] = '\0';
636 err->file[WOLFSSL_MAX_ERROR_SZ - 1] = '\0';
637
638
639 /* since is queue place new node at last of the list */
640 if (wc_last_node == NULL) {
641 /* case of first node added to queue */
642 if (wc_errors != NULL) {
643 /* check for unexpected case before over writing wc_errors */
644 WOLFSSL_MSG("ERROR in adding new node to logging queue!!\n");
645 /* In the event both wc_last_node and wc_errors are NULL, err
646 * goes unassigned to external wc_errors, wc_last_node. Free
647 * err in this instance since wc_ClearErrorNodes will not
648 */
649 XFREE(err, wc_error_heap, DYNAMIC_TYPE_LOG);
650 }
651 else {
652 wc_errors = err;
653 wc_last_node = err;
654 wc_current_node = err;
655 }
656 }
657 else {
658 wc_last_node->next = err;
659 err->prev = wc_last_node;
660 wc_last_node = err;
661
662 /* check the case where have read to the end of the queue and the
663 * current node to read needs updated */
664 if (wc_current_node == NULL) {
665 wc_current_node = err;
666 }
667 }
668 }
669#endif
670 return 0;
671}
672
673/* Removes the error node at the specified index.
674 * idx : if -1 then the most recent node is looked at, otherwise search
675 * through queue for node at the given index
676 */
677void wc_RemoveErrorNode(int idx)
678{
679 struct wc_error_queue* current;
680
681 if (wc_LockMutex(&debug_mutex) != 0) {
682 WOLFSSL_MSG("Lock debug mutex failed");
683 return;
684 }
685
686 if (idx == -1)
687 current = wc_last_node;
688 else {
689 current = (struct wc_error_queue*)wc_errors;
690 for (; current != NULL && idx > 0; idx--)
691 current = current->next;
692 }
693 if (current != NULL) {
694 if (current->prev != NULL)
695 current->prev->next = current->next;
696 if (current->next != NULL)
697 current->next->prev = current->prev;
698 if (wc_last_node == current)
699 wc_last_node = current->prev;
700 if (wc_errors == current)
701 wc_errors = current->next;
702 if (wc_current_node == current)
703 wc_current_node = current->next;
704 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
705 }
706
707 wc_UnLockMutex(&debug_mutex);
708}
709
710
711/* Clears out the list of error nodes.
712 */
713void wc_ClearErrorNodes(void)
714{
715#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
716 defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
717
718 if (wc_LockMutex(&debug_mutex) != 0) {
719 WOLFSSL_MSG("Lock debug mutex failed");
720 return;
721 }
722
723 /* free all nodes from error queue */
724 {
725 struct wc_error_queue* current;
726 struct wc_error_queue* next;
727
728 current = (struct wc_error_queue*)wc_errors;
729 while (current != NULL) {
730 next = current->next;
731 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
732 current = next;
733 }
734 }
735
736 wc_errors = NULL;
737 wc_last_node = NULL;
738 wc_current_node = NULL;
739 wc_UnLockMutex(&debug_mutex);
740#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
741}
742
743int wc_SetLoggingHeap(void* h)
744{
745 if (wc_LockMutex(&debug_mutex) != 0) {
746 WOLFSSL_MSG("Lock debug mutex failed");
747 return BAD_MUTEX_E;
748 }
749 wc_error_heap = h;
750 wc_UnLockMutex(&debug_mutex);
751 return 0;
752}
753
754
755/* frees all nodes in the queue
756 *
757 * id this is the thread id
758 */
759int wc_ERR_remove_state(void)
760{
761 struct wc_error_queue* current;
762 struct wc_error_queue* next;
763
764 if (wc_LockMutex(&debug_mutex) != 0) {
765 WOLFSSL_MSG("Lock debug mutex failed");
766 return BAD_MUTEX_E;
767 }
768
769 /* free all nodes from error queue */
770 current = (struct wc_error_queue*)wc_errors;
771 while (current != NULL) {
772 next = current->next;
773 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
774 current = next;
775 }
776
777 wc_errors = NULL;
778 wc_last_node = NULL;
779
780 wc_UnLockMutex(&debug_mutex);
781
782 return 0;
783}
784
785#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
786/* empties out the error queue into the file */
787static int wc_ERR_dump_to_file (const char *str, size_t len, void *u)
788{
789 XFILE fp = (XFILE ) u;
790 fprintf(fp, "%-*.*s\n", (int)len, (int)len, str);
791 return 0;
792}
793
794/* This callback allows the application to provide a custom error printing
795 * function. */
796void wc_ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
797 void *u)
798{
799 WOLFSSL_ENTER("wc_ERR_print_errors_cb");
800
801 if (cb == NULL) {
802 /* Invalid param */
803 return;
804 }
805
806 if (wc_LockMutex(&debug_mutex) != 0)
807 {
808 WOLFSSL_MSG("Lock debug mutex failed");
809 }
810 else
811 {
812 /* free all nodes from error queue and print them to file */
813 struct wc_error_queue *current;
814 struct wc_error_queue *next;
815
816 current = (struct wc_error_queue *)wc_errors;
817 while (current != NULL)
818 {
819 next = current->next;
820 cb(current->error, strlen(current->error), u);
821 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
822 current = next;
823 }
824
825 /* set global pointers to match having been freed */
826 wc_errors = NULL;
827 wc_last_node = NULL;
828
829 wc_UnLockMutex(&debug_mutex);
830 }
831}
832
833void wc_ERR_print_errors_fp(XFILE fp)
834{
835 WOLFSSL_ENTER("wc_ERR_print_errors_fp");
836
837 /* Send all errors to the wc_ERR_dump_to_file function */
838 wc_ERR_print_errors_cb(wc_ERR_dump_to_file, fp);
839}
840
841#endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */
842
843#endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */
Note: See TracBrowser for help on using the repository browser.