source: azure_iot_hub_f767zi/trunk/wolfssl-4.7.0/wolfcrypt/src/logging.c@ 464

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

WolfSSLとAzure IoT SDKを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 23.6 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 HAVE_WC_INTROSPECTION
115
116const char *wolfSSL_configure_args(void) {
117#ifdef LIBWOLFSSL_CONFIGURE_ARGS
118 /* the spaces on either side are to make matching simple and efficient. */
119 return " " LIBWOLFSSL_CONFIGURE_ARGS " ";
120#else
121 return NULL;
122#endif
123}
124
125const char *wolfSSL_global_cflags(void) {
126#ifdef LIBWOLFSSL_GLOBAL_CFLAGS
127 /* the spaces on either side are to make matching simple and efficient. */
128 return " " LIBWOLFSSL_GLOBAL_CFLAGS " ";
129#else
130 return NULL;
131#endif
132}
133
134#endif /* HAVE_WC_INTROSPECTION */
135
136#ifdef HAVE_STACK_SIZE_VERBOSE
137
138THREAD_LS_T unsigned char *StackSizeCheck_myStack = NULL;
139THREAD_LS_T size_t StackSizeCheck_stackSize = 0;
140THREAD_LS_T size_t StackSizeCheck_stackSizeHWM = 0;
141THREAD_LS_T size_t *StackSizeCheck_stackSizeHWM_ptr = 0;
142THREAD_LS_T void *StackSizeCheck_stackOffsetPointer = 0;
143
144#endif /* HAVE_STACK_SIZE_VERBOSE */
145
146#ifdef DEBUG_WOLFSSL
147
148/* Set these to default values initially. */
149static wolfSSL_Logging_cb log_function = NULL;
150static int loggingEnabled = 0;
151
152#if defined(WOLFSSL_APACHE_MYNEWT)
153#include "log/log.h"
154static struct log mynewt_log;
155#endif /* WOLFSSL_APACHE_MYNEWT */
156
157#endif /* DEBUG_WOLFSSL */
158
159
160/* allow this to be set to NULL, so logs can be redirected to default output */
161int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)
162{
163#ifdef DEBUG_WOLFSSL
164 log_function = f;
165 return 0;
166#else
167 (void)f;
168 return NOT_COMPILED_IN;
169#endif
170}
171
172/* allow this to be set to NULL, so logs can be redirected to default output */
173wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void)
174{
175#ifdef DEBUG_WOLFSSL
176 return log_function;
177#else
178 return NULL;
179#endif
180}
181
182
183int wolfSSL_Debugging_ON(void)
184{
185#ifdef DEBUG_WOLFSSL
186 loggingEnabled = 1;
187#if defined(WOLFSSL_APACHE_MYNEWT)
188 log_register("wolfcrypt", &mynewt_log, &log_console_handler, NULL, LOG_SYSLEVEL);
189#endif /* WOLFSSL_APACHE_MYNEWT */
190 return 0;
191#else
192 return NOT_COMPILED_IN;
193#endif
194}
195
196
197void wolfSSL_Debugging_OFF(void)
198{
199#ifdef DEBUG_WOLFSSL
200 loggingEnabled = 0;
201#endif
202}
203
204#ifdef WOLFSSL_FUNC_TIME
205/* WARNING: This code is only to be used for debugging performance.
206 * The code is not thread-safe.
207 * Do not use WOLFSSL_FUNC_TIME in production code.
208 */
209void WOLFSSL_START(int funcNum)
210{
211 double now = current_time(0) * 1000.0;
212#ifdef WOLFSSL_FUNC_TIME_LOG
213 fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]);
214#endif
215 wc_func_start[funcNum] = now;
216}
217
218void WOLFSSL_END(int funcNum)
219{
220 double now = current_time(0) * 1000.0;
221 wc_func_time[funcNum] += now - wc_func_start[funcNum];
222#ifdef WOLFSSL_FUNC_TIME_LOG
223 fprintf(stderr, "%17.3f: END - %s\n", now, wc_func_name[funcNum]);
224#endif
225}
226
227void WOLFSSL_TIME(int count)
228{
229 int i;
230 double avg, total = 0;
231
232 for (i = 0; i < WC_FUNC_COUNT; i++) {
233 if (wc_func_time[i] > 0) {
234 avg = wc_func_time[i] / count;
235 fprintf(stderr, "%8.3f ms: %s\n", avg, wc_func_name[i]);
236 total += avg;
237 }
238 }
239 fprintf(stderr, "%8.3f ms\n", total);
240}
241#endif
242
243#ifdef DEBUG_WOLFSSL
244
245#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
246 /* see wc_port.h for fio.h and nio.h includes */
247#elif defined(WOLFSSL_SGX)
248 /* Declare sprintf for ocall */
249 int sprintf(char* buf, const char *fmt, ...);
250#elif defined(WOLFSSL_DEOS)
251#elif defined(MICRIUM)
252 #if (BSP_SER_COMM_EN == DEF_ENABLED)
253 #include <bsp_ser.h>
254 #endif
255#elif defined(WOLFSSL_USER_LOG)
256 /* user includes their own headers */
257#elif defined(WOLFSSL_ESPIDF)
258 #include "esp_types.h"
259 #include "esp_log.h"
260#elif defined(WOLFSSL_TELIT_M2MB)
261 #include <stdio.h>
262 #include "m2m_log.h"
263#elif defined(WOLFSSL_ANDROID_DEBUG)
264 #include <android/log.h>
265#elif defined(WOLFSSL_XILINX)
266 #include "xil_printf.h"
267#elif defined(WOLFSSL_LINUXKM)
268 /* the requisite linux/kernel.h is included in wc_port.h, with incompatible warnings masked out. */
269#elif defined(FUSION_RTOS)
270 #include <fclstdio.h>
271 #include <wolfssl/wolfcrypt/wc_port.h>
272 #define fprintf FCL_FPRINTF
273#else
274 #include <stdio.h> /* for default printf stuff */
275#endif
276
277#if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
278 int dc_log_printf(char*, ...);
279#endif
280
281static void wolfssl_log(const int logLevel, const char *const logMessage)
282{
283 if (log_function)
284 log_function(logLevel, logMessage);
285 else {
286#if defined(WOLFSSL_USER_LOG)
287 WOLFSSL_USER_LOG(logMessage);
288#elif defined(WOLFSSL_LOG_PRINTF)
289 printf("%s\n", logMessage);
290
291#elif defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
292 dc_log_printf("%s\n", logMessage);
293#elif defined(WOLFSSL_DEOS)
294 printf("%s\r\n", logMessage);
295#elif defined(MICRIUM)
296 BSP_Ser_Printf("%s\r\n", logMessage);
297#elif defined(WOLFSSL_MDK_ARM)
298 fflush(stdout) ;
299 printf("%s\n", logMessage);
300 fflush(stdout) ;
301#elif defined(WOLFSSL_UTASKER)
302 fnDebugMsg((char*)logMessage);
303 fnDebugMsg("\r\n");
304#elif defined(MQX_USE_IO_OLD)
305 fprintf(_mqxio_stderr, "%s\n", logMessage);
306#elif defined(WOLFSSL_APACHE_MYNEWT)
307 LOG_DEBUG(&mynewt_log, LOG_MODULE_DEFAULT, "%s\n", logMessage);
308#elif defined(WOLFSSL_ESPIDF)
309 ESP_LOGI("wolfssl", "%s", logMessage);
310#elif defined(WOLFSSL_ZEPHYR)
311 printk("%s\n", logMessage);
312#elif defined(WOLFSSL_TELIT_M2MB)
313 M2M_LOG_INFO("%s\n", logMessage);
314#elif defined(WOLFSSL_ANDROID_DEBUG)
315 __android_log_print(ANDROID_LOG_VERBOSE, "[wolfSSL]", "%s", logMessage);
316#elif defined(WOLFSSL_XILINX)
317 xil_printf("%s\r\n", logMessage);
318#elif defined(WOLFSSL_LINUXKM)
319 printk("%s\n", logMessage);
320#else
321 fprintf(stderr, "%s\n", logMessage);
322#endif
323 }
324}
325
326#ifndef WOLFSSL_DEBUG_ERRORS_ONLY
327void WOLFSSL_MSG(const char* msg)
328{
329 if (loggingEnabled)
330 wolfssl_log(INFO_LOG , msg);
331}
332
333#ifndef LINE_LEN
334#define LINE_LEN 16
335#endif
336void WOLFSSL_BUFFER(const byte* buffer, word32 length)
337{
338 int i, buflen = (int)length, bufidx;
339 char line[(LINE_LEN * 4) + 3]; /* \t00..0F | chars...chars\0 */
340
341 if (!loggingEnabled) {
342 return;
343 }
344
345 if (!buffer) {
346 wolfssl_log(INFO_LOG, "\tNULL");
347 return;
348 }
349
350 while (buflen > 0) {
351 bufidx = 0;
352 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "\t");
353 bufidx++;
354
355 for (i = 0; i < LINE_LEN; i++) {
356 if (i < buflen) {
357 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "%02x ", buffer[i]);
358 }
359 else {
360 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, " ");
361 }
362 bufidx += 3;
363 }
364
365 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "| ");
366 bufidx++;
367
368 for (i = 0; i < LINE_LEN; i++) {
369 if (i < buflen) {
370 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx,
371 "%c", 31 < buffer[i] && buffer[i] < 127 ? buffer[i] : '.');
372 bufidx++;
373 }
374 }
375
376 wolfssl_log(INFO_LOG, line);
377 buffer += LINE_LEN;
378 buflen -= LINE_LEN;
379 }
380}
381
382
383void WOLFSSL_ENTER(const char* msg)
384{
385 if (loggingEnabled) {
386 char buffer[WOLFSSL_MAX_ERROR_SZ];
387 XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg);
388 wolfssl_log(ENTER_LOG , buffer);
389 }
390}
391
392
393void WOLFSSL_LEAVE(const char* msg, int ret)
394{
395 if (loggingEnabled) {
396 char buffer[WOLFSSL_MAX_ERROR_SZ];
397 XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
398 msg, ret);
399 wolfssl_log(LEAVE_LOG , buffer);
400 }
401}
402
403WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void)
404{
405 return loggingEnabled;
406}
407#endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */
408#endif /* DEBUG_WOLFSSL */
409
410/*
411 * When using OPENSSL_EXTRA or DEBUG_WOLFSSL_VERBOSE macro then WOLFSSL_ERROR is
412 * mapped to new function WOLFSSL_ERROR_LINE which gets the line # and function
413 * name where WOLFSSL_ERROR is called at.
414 */
415#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || \
416 defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
417 defined(OPENSSL_EXTRA)
418
419#if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(NO_ERROR_QUEUE)) \
420 || defined(DEBUG_WOLFSSL_VERBOSE)
421void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line,
422 const char* file, void* usrCtx)
423#else
424void WOLFSSL_ERROR(int error)
425#endif
426{
427#ifdef WOLFSSL_ASYNC_CRYPT
428 if (error != WC_PENDING_E)
429#endif
430 {
431 char buffer[WOLFSSL_MAX_ERROR_SZ];
432
433 #if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && \
434 !defined(NO_ERROR_QUEUE)) || defined(DEBUG_WOLFSSL_VERBOSE)
435 (void)usrCtx; /* a user ctx for future flexibility */
436 (void)func;
437
438 if (wc_LockMutex(&debug_mutex) != 0) {
439 WOLFSSL_MSG("Lock debug mutex failed");
440 XSNPRINTF(buffer, sizeof(buffer),
441 "wolfSSL error occurred, error = %d", error);
442 }
443 else {
444 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
445 /* If running in compatibility mode do not add want read and
446 want right to error queue */
447 if (error != WANT_READ && error != WANT_WRITE) {
448 #endif
449 if (error < 0)
450 error = error - (2 * error); /* get absolute value */
451 XSNPRINTF(buffer, sizeof(buffer),
452 "wolfSSL error occurred, error = %d line:%d file:%s",
453 error, line, file);
454 if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) {
455 WOLFSSL_MSG("Error creating logging node");
456 /* with void function there is no return here, continue on
457 * to unlock mutex and log what buffer was created. */
458 }
459 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
460 }
461 else {
462 XSNPRINTF(buffer, sizeof(buffer),
463 "wolfSSL error occurred, error = %d", error);
464
465 }
466 #endif
467
468 wc_UnLockMutex(&debug_mutex);
469 }
470 #else
471 XSNPRINTF(buffer, sizeof(buffer),
472 "wolfSSL error occurred, error = %d", error);
473 #endif
474
475 #ifdef DEBUG_WOLFSSL
476 if (loggingEnabled)
477 wolfssl_log(ERROR_LOG , buffer);
478 #endif
479 }
480}
481
482void WOLFSSL_ERROR_MSG(const char* msg)
483{
484#ifdef DEBUG_WOLFSSL
485 if (loggingEnabled)
486 wolfssl_log(ERROR_LOG , msg);
487#else
488 (void)msg;
489#endif
490}
491
492#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
493
494#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
495/* Internal function that is called by wolfCrypt_Init() */
496int wc_LoggingInit(void)
497{
498 if (wc_InitMutex(&debug_mutex) != 0) {
499 WOLFSSL_MSG("Bad Init Mutex");
500 return BAD_MUTEX_E;
501 }
502 wc_errors = NULL;
503 wc_current_node = NULL;
504 wc_last_node = NULL;
505
506 return 0;
507}
508
509
510/* internal function that is called by wolfCrypt_Cleanup */
511int wc_LoggingCleanup(void)
512{
513 /* clear logging entries */
514 wc_ClearErrorNodes();
515
516 /* free mutex */
517 if (wc_FreeMutex(&debug_mutex) != 0) {
518 WOLFSSL_MSG("Bad Mutex free");
519 return BAD_MUTEX_E;
520 }
521 return 0;
522}
523
524
525/* peek at an error node
526 *
527 * idx : if -1 then the most recent node is looked at, otherwise search
528 * through queue for node at the given index
529 * file : pointer to internal file string
530 * reason : pointer to internal error reason
531 * line : line number that error happened at
532 *
533 * Returns a negative value in error case, on success returns the nodes error
534 * value which is positive (absolute value)
535 */
536int wc_PeekErrorNode(int idx, const char **file, const char **reason,
537 int *line)
538{
539 struct wc_error_queue* err;
540
541 if (wc_LockMutex(&debug_mutex) != 0) {
542 WOLFSSL_MSG("Lock debug mutex failed");
543 return BAD_MUTEX_E;
544 }
545
546 if (idx < 0) {
547 err = wc_last_node;
548 }
549 else {
550 int i;
551
552 err = (struct wc_error_queue*)wc_errors;
553 for (i = 0; i < idx; i++) {
554 if (err == NULL) {
555 WOLFSSL_MSG("Error node not found. Bad index?");
556 wc_UnLockMutex(&debug_mutex);
557 return BAD_FUNC_ARG;
558 }
559 err = err->next;
560 }
561 }
562
563 if (err == NULL) {
564 WOLFSSL_MSG("No Errors in queue");
565 wc_UnLockMutex(&debug_mutex);
566 return BAD_STATE_E;
567 }
568
569 if (file != NULL) {
570 *file = err->file;
571 }
572
573 if (reason != NULL) {
574 *reason = err->error;
575 }
576
577 if (line != NULL) {
578 *line = err->line;
579 }
580
581 wc_UnLockMutex(&debug_mutex);
582
583 return err->value;
584}
585
586
587/* Pulls the current node from error queue and increments current state.
588 * Note: this does not delete nodes because input arguments are pointing to
589 * node buffers.
590 *
591 * file pointer to file that error was in. Can be NULL to return no file.
592 * reason error string giving reason for error. Can be NULL to return no reason.
593 * line return line number of where error happened.
594 *
595 * returns the error value on success and BAD_MUTEX_E or BAD_STATE_E on failure
596 */
597int wc_PullErrorNode(const char **file, const char **reason, int *line)
598{
599 struct wc_error_queue* err;
600 int value;
601
602 if (wc_LockMutex(&debug_mutex) != 0) {
603 WOLFSSL_MSG("Lock debug mutex failed");
604 return BAD_MUTEX_E;
605 }
606
607 err = wc_current_node;
608 if (err == NULL) {
609 WOLFSSL_MSG("No Errors in queue");
610 wc_UnLockMutex(&debug_mutex);
611 return BAD_STATE_E;
612 }
613
614 if (file != NULL) {
615 *file = err->file;
616 }
617
618 if (reason != NULL) {
619 *reason = err->error;
620 }
621
622 if (line != NULL) {
623 *line = err->line;
624 }
625
626 value = err->value;
627 wc_current_node = err->next;
628 wc_UnLockMutex(&debug_mutex);
629
630 return value;
631}
632
633
634/* create new error node and add it to the queue
635 * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal
636 * function. debug_mutex should be locked before a call to this function. */
637int wc_AddErrorNode(int error, int line, char* buf, char* file)
638{
639#if defined(NO_ERROR_QUEUE)
640 (void)error;
641 (void)line;
642 (void)buf;
643 (void)file;
644 WOLFSSL_MSG("Error queue turned off, can not add nodes");
645#else
646 struct wc_error_queue* err;
647 err = (struct wc_error_queue*)XMALLOC(
648 sizeof(struct wc_error_queue), wc_error_heap, DYNAMIC_TYPE_LOG);
649 if (err == NULL) {
650 WOLFSSL_MSG("Unable to create error node for log");
651 return MEMORY_E;
652 }
653 else {
654 int sz;
655
656 XMEMSET(err, 0, sizeof(struct wc_error_queue));
657 err->heap = wc_error_heap;
658 sz = (int)XSTRLEN(buf);
659 if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {
660 sz = WOLFSSL_MAX_ERROR_SZ - 1;
661 }
662 if (sz > 0) {
663 XMEMCPY(err->error, buf, sz);
664 }
665
666 sz = (int)XSTRLEN(file);
667 if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {
668 sz = WOLFSSL_MAX_ERROR_SZ - 1;
669 }
670 if (sz > 0) {
671 XMEMCPY(err->file, file, sz);
672 }
673
674 err->value = error;
675 err->line = line;
676
677 /* make sure is terminated */
678 err->error[WOLFSSL_MAX_ERROR_SZ - 1] = '\0';
679 err->file[WOLFSSL_MAX_ERROR_SZ - 1] = '\0';
680
681
682 /* since is queue place new node at last of the list */
683 if (wc_last_node == NULL) {
684 /* case of first node added to queue */
685 if (wc_errors != NULL) {
686 /* check for unexpected case before over writing wc_errors */
687 WOLFSSL_MSG("ERROR in adding new node to logging queue!!\n");
688 /* In the event both wc_last_node and wc_errors are NULL, err
689 * goes unassigned to external wc_errors, wc_last_node. Free
690 * err in this instance since wc_ClearErrorNodes will not
691 */
692 XFREE(err, wc_error_heap, DYNAMIC_TYPE_LOG);
693 }
694 else {
695 wc_errors = err;
696 wc_last_node = err;
697 wc_current_node = err;
698 }
699 }
700 else {
701 wc_last_node->next = err;
702 err->prev = wc_last_node;
703 wc_last_node = err;
704
705 /* check the case where have read to the end of the queue and the
706 * current node to read needs updated */
707 if (wc_current_node == NULL) {
708 wc_current_node = err;
709 }
710 }
711 }
712#endif
713 return 0;
714}
715
716/* Removes the error node at the specified index.
717 * idx : if -1 then the most recent node is looked at, otherwise search
718 * through queue for node at the given index
719 */
720void wc_RemoveErrorNode(int idx)
721{
722 struct wc_error_queue* current;
723
724 if (wc_LockMutex(&debug_mutex) != 0) {
725 WOLFSSL_MSG("Lock debug mutex failed");
726 return;
727 }
728
729 if (idx == -1)
730 current = wc_last_node;
731 else {
732 current = (struct wc_error_queue*)wc_errors;
733 for (; current != NULL && idx > 0; idx--)
734 current = current->next;
735 }
736 if (current != NULL) {
737 if (current->prev != NULL)
738 current->prev->next = current->next;
739 if (current->next != NULL)
740 current->next->prev = current->prev;
741 if (wc_last_node == current)
742 wc_last_node = current->prev;
743 if (wc_errors == current)
744 wc_errors = current->next;
745 if (wc_current_node == current)
746 wc_current_node = current->next;
747 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
748 }
749
750 wc_UnLockMutex(&debug_mutex);
751}
752
753
754/* Clears out the list of error nodes.
755 */
756void wc_ClearErrorNodes(void)
757{
758#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
759 defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
760
761 if (wc_LockMutex(&debug_mutex) != 0) {
762 WOLFSSL_MSG("Lock debug mutex failed");
763 return;
764 }
765
766 /* free all nodes from error queue */
767 {
768 struct wc_error_queue* current;
769 struct wc_error_queue* next;
770
771 current = (struct wc_error_queue*)wc_errors;
772 while (current != NULL) {
773 next = current->next;
774 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
775 current = next;
776 }
777 }
778
779 wc_errors = NULL;
780 wc_last_node = NULL;
781 wc_current_node = NULL;
782 wc_UnLockMutex(&debug_mutex);
783#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
784}
785
786int wc_SetLoggingHeap(void* h)
787{
788 if (wc_LockMutex(&debug_mutex) != 0) {
789 WOLFSSL_MSG("Lock debug mutex failed");
790 return BAD_MUTEX_E;
791 }
792 wc_error_heap = h;
793 wc_UnLockMutex(&debug_mutex);
794 return 0;
795}
796
797
798/* frees all nodes in the queue
799 *
800 * id this is the thread id
801 */
802int wc_ERR_remove_state(void)
803{
804 struct wc_error_queue* current;
805 struct wc_error_queue* next;
806
807 if (wc_LockMutex(&debug_mutex) != 0) {
808 WOLFSSL_MSG("Lock debug mutex failed");
809 return BAD_MUTEX_E;
810 }
811
812 /* free all nodes from error queue */
813 current = (struct wc_error_queue*)wc_errors;
814 while (current != NULL) {
815 next = current->next;
816 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
817 current = next;
818 }
819
820 wc_errors = NULL;
821 wc_last_node = NULL;
822
823 wc_UnLockMutex(&debug_mutex);
824
825 return 0;
826}
827
828#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
829/* empties out the error queue into the file */
830static int wc_ERR_dump_to_file (const char *str, size_t len, void *u)
831{
832 XFILE fp = (XFILE ) u;
833 fprintf(fp, "%-*.*s\n", (int)len, (int)len, str);
834 return 0;
835}
836
837/* This callback allows the application to provide a custom error printing
838 * function. */
839void wc_ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
840 void *u)
841{
842 WOLFSSL_ENTER("wc_ERR_print_errors_cb");
843
844 if (cb == NULL) {
845 /* Invalid param */
846 return;
847 }
848
849 if (wc_LockMutex(&debug_mutex) != 0)
850 {
851 WOLFSSL_MSG("Lock debug mutex failed");
852 }
853 else
854 {
855 /* free all nodes from error queue and print them to file */
856 struct wc_error_queue *current;
857 struct wc_error_queue *next;
858
859 current = (struct wc_error_queue *)wc_errors;
860 while (current != NULL)
861 {
862 next = current->next;
863 cb(current->error, XSTRLEN(current->error), u);
864 XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
865 current = next;
866 }
867
868 /* set global pointers to match having been freed */
869 wc_errors = NULL;
870 wc_last_node = NULL;
871
872 wc_UnLockMutex(&debug_mutex);
873 }
874}
875
876void wc_ERR_print_errors_fp(XFILE fp)
877{
878 WOLFSSL_ENTER("wc_ERR_print_errors_fp");
879
880 /* Send all errors to the wc_ERR_dump_to_file function */
881 wc_ERR_print_errors_cb(wc_ERR_dump_to_file, fp);
882}
883
884#endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */
885
886#endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */
Note: See TracBrowser for help on using the repository browser.