wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
logging.c
00001 /* logging.c 00002 * 00003 * Copyright (C) 2006-2020 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 #include <wolfssl/wolfcrypt/logging.h > 00030 #include <wolfssl/wolfcrypt/error-crypt.h > 00031 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) 00032 /* avoid adding WANT_READ and WANT_WRITE to error queue */ 00033 #include <wolfssl/error-ssl.h> 00034 #endif 00035 00036 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) 00037 static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */ 00038 00039 /* accessing any node from the queue should be wrapped in a lock of 00040 * debug_mutex */ 00041 static void* wc_error_heap; 00042 struct wc_error_queue { 00043 void* heap; /* the heap hint used with nodes creation */ 00044 struct wc_error_queue* next; 00045 struct wc_error_queue* prev; 00046 char error[WOLFSSL_MAX_ERROR_SZ]; 00047 char file[WOLFSSL_MAX_ERROR_SZ]; 00048 int value; 00049 int line; 00050 }; 00051 volatile struct wc_error_queue* wc_errors; 00052 static struct wc_error_queue* wc_current_node; 00053 static struct wc_error_queue* wc_last_node; 00054 /* pointer to last node in queue to make insertion O(1) */ 00055 #endif 00056 00057 #ifdef WOLFSSL_FUNC_TIME 00058 /* WARNING: This code is only to be used for debugging performance. 00059 * The code is not thread-safe. 00060 * Do not use WOLFSSL_FUNC_TIME in production code. 00061 */ 00062 static double wc_func_start[WC_FUNC_COUNT]; 00063 static double wc_func_time[WC_FUNC_COUNT] = { 0, }; 00064 static const char* wc_func_name[WC_FUNC_COUNT] = { 00065 "SendHelloRequest", 00066 "DoHelloRequest", 00067 "SendClientHello", 00068 "DoClientHello", 00069 "SendServerHello", 00070 "DoServerHello", 00071 "SendEncryptedExtensions", 00072 "DoEncryptedExtensions", 00073 "SendCertificateRequest", 00074 "DoCertificateRequest", 00075 "SendCertificate", 00076 "DoCertificate", 00077 "SendCertificateVerify", 00078 "DoCertificateVerify", 00079 "SendFinished", 00080 "DoFinished", 00081 "SendKeyUpdate", 00082 "DoKeyUpdate", 00083 "SendEarlyData", 00084 "DoEarlyData", 00085 "SendNewSessionTicket", 00086 "DoNewSessionTicket", 00087 "SendServerHelloDone", 00088 "DoServerHelloDone", 00089 "SendTicket", 00090 "DoTicket", 00091 "SendClientKeyExchange", 00092 "DoClientKeyExchange", 00093 "SendCertificateStatus", 00094 "DoCertificateStatus", 00095 "SendServerKeyExchange", 00096 "DoServerKeyExchange", 00097 "SendEarlyData", 00098 "DoEarlyData", 00099 }; 00100 00101 #include <sys/time.h> 00102 00103 /* WARNING: This function is not portable. */ 00104 static WC_INLINE double current_time(int reset) 00105 { 00106 struct timeval tv; 00107 gettimeofday(&tv, 0); 00108 (void)reset; 00109 00110 return (double)tv.tv_sec + (double)tv.tv_usec / 1000000; 00111 } 00112 #endif /* WOLFSSL_FUNC_TIME */ 00113 00114 #ifdef DEBUG_WOLFSSL 00115 00116 /* Set these to default values initially. */ 00117 static wolfSSL_Logging_cb log_function = NULL; 00118 static int loggingEnabled = 0; 00119 00120 #if defined(WOLFSSL_APACHE_MYNEWT) 00121 #include "log/log.h" 00122 static struct log mynewt_log; 00123 #endif /* WOLFSSL_APACHE_MYNEWT */ 00124 00125 #endif /* DEBUG_WOLFSSL */ 00126 00127 00128 /* allow this to be set to NULL, so logs can be redirected to default output */ 00129 int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f) 00130 { 00131 #ifdef DEBUG_WOLFSSL 00132 log_function = f; 00133 return 0; 00134 #else 00135 (void)f; 00136 return NOT_COMPILED_IN; 00137 #endif 00138 } 00139 00140 /* allow this to be set to NULL, so logs can be redirected to default output */ 00141 wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void) 00142 { 00143 #ifdef DEBUG_WOLFSSL 00144 return log_function; 00145 #else 00146 return NULL; 00147 #endif 00148 } 00149 00150 00151 int wolfSSL_Debugging_ON(void) 00152 { 00153 #ifdef DEBUG_WOLFSSL 00154 loggingEnabled = 1; 00155 #if defined(WOLFSSL_APACHE_MYNEWT) 00156 log_register("wolfcrypt", &mynewt_log, &log_console_handler, NULL, LOG_SYSLEVEL); 00157 #endif /* WOLFSSL_APACHE_MYNEWT */ 00158 return 0; 00159 #else 00160 return NOT_COMPILED_IN; 00161 #endif 00162 } 00163 00164 00165 void wolfSSL_Debugging_OFF(void) 00166 { 00167 #ifdef DEBUG_WOLFSSL 00168 loggingEnabled = 0; 00169 #endif 00170 } 00171 00172 #ifdef WOLFSSL_FUNC_TIME 00173 /* WARNING: This code is only to be used for debugging performance. 00174 * The code is not thread-safe. 00175 * Do not use WOLFSSL_FUNC_TIME in production code. 00176 */ 00177 void WOLFSSL_START(int funcNum) 00178 { 00179 double now = current_time(0) * 1000.0; 00180 #ifdef WOLFSSL_FUNC_TIME_LOG 00181 fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]); 00182 #endif 00183 wc_func_start[funcNum] = now; 00184 } 00185 00186 void WOLFSSL_END(int funcNum) 00187 { 00188 double now = current_time(0) * 1000.0; 00189 wc_func_time[funcNum] += now - wc_func_start[funcNum]; 00190 #ifdef WOLFSSL_FUNC_TIME_LOG 00191 fprintf(stderr, "%17.3f: END - %s\n", now, wc_func_name[funcNum]); 00192 #endif 00193 } 00194 00195 void WOLFSSL_TIME(int count) 00196 { 00197 int i; 00198 double avg, total = 0; 00199 00200 for (i = 0; i < WC_FUNC_COUNT; i++) { 00201 if (wc_func_time[i] > 0) { 00202 avg = wc_func_time[i] / count; 00203 fprintf(stderr, "%8.3f ms: %s\n", avg, wc_func_name[i]); 00204 total += avg; 00205 } 00206 } 00207 fprintf(stderr, "%8.3f ms\n", total); 00208 } 00209 #endif 00210 00211 #ifdef DEBUG_WOLFSSL 00212 00213 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX) 00214 /* see wc_port.h for fio.h and nio.h includes */ 00215 #elif defined(WOLFSSL_SGX) 00216 /* Declare sprintf for ocall */ 00217 int sprintf(char* buf, const char *fmt, ...); 00218 #elif defined(WOLFSSL_DEOS) 00219 #elif defined(MICRIUM) 00220 #if (BSP_SER_COMM_EN == DEF_ENABLED) 00221 #include <bsp_ser.h> 00222 #endif 00223 #elif defined(WOLFSSL_USER_LOG) 00224 /* user includes their own headers */ 00225 #elif defined(WOLFSSL_ESPIDF) 00226 #include "esp_types.h" 00227 #include "esp_log.h" 00228 #elif defined(WOLFSSL_TELIT_M2MB) 00229 #include <stdio.h> 00230 #include "m2m_log.h" 00231 #elif defined(WOLFSSL_ANDROID_DEBUG) 00232 #include <android/log.h> 00233 #else 00234 #include <stdio.h> /* for default printf stuff */ 00235 #endif 00236 00237 #if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF) 00238 int dc_log_printf(char*, ...); 00239 #endif 00240 00241 static void wolfssl_log(const int logLevel, const char *const logMessage) 00242 { 00243 if (log_function) 00244 log_function(logLevel, logMessage); 00245 else { 00246 #if defined(WOLFSSL_USER_LOG) 00247 WOLFSSL_USER_LOG(logMessage); 00248 #elif defined(WOLFSSL_LOG_PRINTF) 00249 printf("%s\n", logMessage); 00250 00251 #elif defined(THREADX) && !defined(THREADX_NO_DC_PRINTF) 00252 dc_log_printf("%s\n", logMessage); 00253 #elif defined(WOLFSSL_DEOS) 00254 printf("%s\r\n", logMessage); 00255 #elif defined(MICRIUM) 00256 BSP_Ser_Printf("%s\r\n", logMessage); 00257 #elif defined(WOLFSSL_MDK_ARM) 00258 fflush(stdout) ; 00259 printf("%s\n", logMessage); 00260 fflush(stdout) ; 00261 #elif defined(WOLFSSL_UTASKER) 00262 fnDebugMsg((char*)logMessage); 00263 fnDebugMsg("\r\n"); 00264 #elif defined(MQX_USE_IO_OLD) 00265 fprintf(_mqxio_stderr, "%s\n", logMessage); 00266 00267 #elif defined(WOLFSSL_APACHE_MYNEWT) 00268 LOG_DEBUG(&mynewt_log, LOG_MODULE_DEFAULT, "%s\n", logMessage); 00269 #elif defined(WOLFSSL_ESPIDF) 00270 ESP_LOGI("wolfssl", "%s", logMessage); 00271 #elif defined(WOLFSSL_ZEPHYR) 00272 printk("%s\n", logMessage); 00273 #elif defined(WOLFSSL_TELIT_M2MB) 00274 M2M_LOG_INFO("%s\n", logMessage); 00275 #elif defined(WOLFSSL_ANDROID_DEBUG) 00276 __android_log_print(ANDROID_LOG_VERBOSE, "[wolfSSL]", "%s", logMessage); 00277 #else 00278 fprintf(stderr, "%s\n", logMessage); 00279 #endif 00280 } 00281 } 00282 00283 #ifndef WOLFSSL_DEBUG_ERRORS_ONLY 00284 void WOLFSSL_MSG(const char* msg) 00285 { 00286 if (loggingEnabled) 00287 wolfssl_log(INFO_LOG , msg); 00288 } 00289 00290 #ifndef LINE_LEN 00291 #define LINE_LEN 16 00292 #endif 00293 void WOLFSSL_BUFFER(const byte* buffer, word32 length) 00294 { 00295 int i, buflen = (int)length, bufidx; 00296 char line[(LINE_LEN * 4) + 3]; /* \t00..0F | chars...chars\0 */ 00297 00298 if (!loggingEnabled) { 00299 return; 00300 } 00301 00302 if (!buffer) { 00303 wolfssl_log(INFO_LOG, "\tNULL"); 00304 return; 00305 } 00306 00307 while (buflen > 0) { 00308 bufidx = 0; 00309 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "\t"); 00310 bufidx++; 00311 00312 for (i = 0; i < LINE_LEN; i++) { 00313 if (i < buflen) { 00314 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "%02x ", buffer[i]); 00315 } 00316 else { 00317 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, " "); 00318 } 00319 bufidx += 3; 00320 } 00321 00322 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, "| "); 00323 bufidx++; 00324 00325 for (i = 0; i < LINE_LEN; i++) { 00326 if (i < buflen) { 00327 XSNPRINTF(&line[bufidx], sizeof(line)-bufidx, 00328 "%c", 31 < buffer[i] && buffer[i] < 127 ? buffer[i] : '.'); 00329 bufidx++; 00330 } 00331 } 00332 00333 wolfssl_log(INFO_LOG, line); 00334 buffer += LINE_LEN; 00335 buflen -= LINE_LEN; 00336 } 00337 } 00338 00339 00340 void WOLFSSL_ENTER(const char* msg) 00341 { 00342 if (loggingEnabled) { 00343 char buffer[WOLFSSL_MAX_ERROR_SZ]; 00344 XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg); 00345 wolfssl_log(ENTER_LOG , buffer); 00346 } 00347 } 00348 00349 00350 void WOLFSSL_LEAVE(const char* msg, int ret) 00351 { 00352 if (loggingEnabled) { 00353 char buffer[WOLFSSL_MAX_ERROR_SZ]; 00354 XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d", 00355 msg, ret); 00356 wolfssl_log(LEAVE_LOG , buffer); 00357 } 00358 } 00359 00360 WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void) 00361 { 00362 return loggingEnabled; 00363 } 00364 #endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */ 00365 #endif /* DEBUG_WOLFSSL */ 00366 00367 /* 00368 * When using OPENSSL_EXTRA or DEBUG_WOLFSSL_VERBOSE macro then WOLFSSL_ERROR is 00369 * mapped to new function WOLFSSL_ERROR_LINE which gets the line # and function 00370 * name where WOLFSSL_ERROR is called at. 00371 */ 00372 #if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || \ 00373 defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ 00374 defined(OPENSSL_EXTRA) 00375 00376 #if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(NO_ERROR_QUEUE)) \ 00377 || defined(DEBUG_WOLFSSL_VERBOSE) 00378 void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line, 00379 const char* file, void* usrCtx) 00380 #else 00381 void WOLFSSL_ERROR(int error) 00382 #endif 00383 { 00384 #ifdef WOLFSSL_ASYNC_CRYPT 00385 if (error != WC_PENDING_E) 00386 #endif 00387 { 00388 char buffer[WOLFSSL_MAX_ERROR_SZ]; 00389 00390 #if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && \ 00391 !defined(NO_ERROR_QUEUE)) || defined(DEBUG_WOLFSSL_VERBOSE) 00392 (void)usrCtx; /* a user ctx for future flexibility */ 00393 (void)func; 00394 00395 if (wc_LockMutex(&debug_mutex) != 0) { 00396 WOLFSSL_MSG("Lock debug mutex failed"); 00397 XSNPRINTF(buffer, sizeof(buffer), 00398 "wolfSSL error occurred, error = %d", error); 00399 } 00400 else { 00401 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) 00402 /* If running in compatibility mode do not add want read and 00403 want right to error queue */ 00404 if (error != WANT_READ && error != WANT_WRITE) { 00405 #endif 00406 if (error < 0) 00407 error = error - (2 * error); /* get absolute value */ 00408 XSNPRINTF(buffer, sizeof(buffer), 00409 "wolfSSL error occurred, error = %d line:%d file:%s", 00410 error, line, file); 00411 if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) { 00412 WOLFSSL_MSG("Error creating logging node"); 00413 /* with void function there is no return here, continue on 00414 * to unlock mutex and log what buffer was created. */ 00415 } 00416 #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) 00417 } 00418 else { 00419 XSNPRINTF(buffer, sizeof(buffer), 00420 "wolfSSL error occurred, error = %d", error); 00421 00422 } 00423 #endif 00424 00425 wc_UnLockMutex(&debug_mutex); 00426 } 00427 #else 00428 XSNPRINTF(buffer, sizeof(buffer), 00429 "wolfSSL error occurred, error = %d", error); 00430 #endif 00431 00432 #ifdef DEBUG_WOLFSSL 00433 if (loggingEnabled) 00434 wolfssl_log(ERROR_LOG , buffer); 00435 #endif 00436 } 00437 } 00438 00439 void WOLFSSL_ERROR_MSG(const char* msg) 00440 { 00441 #ifdef DEBUG_WOLFSSL 00442 if (loggingEnabled) 00443 wolfssl_log(ERROR_LOG , msg); 00444 #else 00445 (void)msg; 00446 #endif 00447 } 00448 00449 #endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ 00450 00451 #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) 00452 /* Internal function that is called by wolfCrypt_Init() */ 00453 int wc_LoggingInit(void) 00454 { 00455 if (wc_InitMutex(&debug_mutex) != 0) { 00456 WOLFSSL_MSG("Bad Init Mutex"); 00457 return BAD_MUTEX_E; 00458 } 00459 wc_errors = NULL; 00460 wc_current_node = NULL; 00461 wc_last_node = NULL; 00462 00463 return 0; 00464 } 00465 00466 00467 /* internal function that is called by wolfCrypt_Cleanup */ 00468 int wc_LoggingCleanup(void) 00469 { 00470 /* clear logging entries */ 00471 wc_ClearErrorNodes(); 00472 00473 /* free mutex */ 00474 if (wc_FreeMutex(&debug_mutex) != 0) { 00475 WOLFSSL_MSG("Bad Mutex free"); 00476 return BAD_MUTEX_E; 00477 } 00478 return 0; 00479 } 00480 00481 00482 /* peek at an error node 00483 * 00484 * idx : if -1 then the most recent node is looked at, otherwise search 00485 * through queue for node at the given index 00486 * file : pointer to internal file string 00487 * reason : pointer to internal error reason 00488 * line : line number that error happened at 00489 * 00490 * Returns a negative value in error case, on success returns the nodes error 00491 * value which is positive (absolute value) 00492 */ 00493 int wc_PeekErrorNode(int idx, const char **file, const char **reason, 00494 int *line) 00495 { 00496 struct wc_error_queue* err; 00497 00498 if (wc_LockMutex(&debug_mutex) != 0) { 00499 WOLFSSL_MSG("Lock debug mutex failed"); 00500 return BAD_MUTEX_E; 00501 } 00502 00503 if (idx < 0) { 00504 err = wc_last_node; 00505 } 00506 else { 00507 int i; 00508 00509 err = (struct wc_error_queue*)wc_errors; 00510 for (i = 0; i < idx; i++) { 00511 if (err == NULL) { 00512 WOLFSSL_MSG("Error node not found. Bad index?"); 00513 wc_UnLockMutex(&debug_mutex); 00514 return BAD_FUNC_ARG; 00515 } 00516 err = err->next; 00517 } 00518 } 00519 00520 if (err == NULL) { 00521 WOLFSSL_MSG("No Errors in queue"); 00522 wc_UnLockMutex(&debug_mutex); 00523 return BAD_STATE_E; 00524 } 00525 00526 if (file != NULL) { 00527 *file = err->file; 00528 } 00529 00530 if (reason != NULL) { 00531 *reason = err->error; 00532 } 00533 00534 if (line != NULL) { 00535 *line = err->line; 00536 } 00537 00538 wc_UnLockMutex(&debug_mutex); 00539 00540 return err->value; 00541 } 00542 00543 00544 /* Pulls the current node from error queue and increments current state. 00545 * Note: this does not delete nodes because input arguments are pointing to 00546 * node buffers. 00547 * 00548 * file pointer to file that error was in. Can be NULL to return no file. 00549 * reason error string giving reason for error. Can be NULL to return no reason. 00550 * line return line number of where error happened. 00551 * 00552 * returns the error value on success and BAD_MUTEX_E or BAD_STATE_E on failure 00553 */ 00554 int wc_PullErrorNode(const char **file, const char **reason, int *line) 00555 { 00556 struct wc_error_queue* err; 00557 int value; 00558 00559 if (wc_LockMutex(&debug_mutex) != 0) { 00560 WOLFSSL_MSG("Lock debug mutex failed"); 00561 return BAD_MUTEX_E; 00562 } 00563 00564 err = wc_current_node; 00565 if (err == NULL) { 00566 WOLFSSL_MSG("No Errors in queue"); 00567 wc_UnLockMutex(&debug_mutex); 00568 return BAD_STATE_E; 00569 } 00570 00571 if (file != NULL) { 00572 *file = err->file; 00573 } 00574 00575 if (reason != NULL) { 00576 *reason = err->error; 00577 } 00578 00579 if (line != NULL) { 00580 *line = err->line; 00581 } 00582 00583 value = err->value; 00584 wc_current_node = err->next; 00585 wc_UnLockMutex(&debug_mutex); 00586 00587 return value; 00588 } 00589 00590 00591 /* create new error node and add it to the queue 00592 * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal 00593 * function. debug_mutex should be locked before a call to this function. */ 00594 int wc_AddErrorNode(int error, int line, char* buf, char* file) 00595 { 00596 #if defined(NO_ERROR_QUEUE) 00597 (void)error; 00598 (void)line; 00599 (void)buf; 00600 (void)file; 00601 WOLFSSL_MSG("Error queue turned off, can not add nodes"); 00602 #else 00603 struct wc_error_queue* err; 00604 err = (struct wc_error_queue*)XMALLOC( 00605 sizeof(struct wc_error_queue), wc_error_heap, DYNAMIC_TYPE_LOG); 00606 if (err == NULL) { 00607 WOLFSSL_MSG("Unable to create error node for log"); 00608 return MEMORY_E; 00609 } 00610 else { 00611 int sz; 00612 00613 XMEMSET(err, 0, sizeof(struct wc_error_queue)); 00614 err->heap = wc_error_heap; 00615 sz = (int)XSTRLEN(buf); 00616 if (sz > WOLFSSL_MAX_ERROR_SZ - 1) { 00617 sz = WOLFSSL_MAX_ERROR_SZ - 1; 00618 } 00619 if (sz > 0) { 00620 XMEMCPY(err->error, buf, sz); 00621 } 00622 00623 sz = (int)XSTRLEN(file); 00624 if (sz > WOLFSSL_MAX_ERROR_SZ - 1) { 00625 sz = WOLFSSL_MAX_ERROR_SZ - 1; 00626 } 00627 if (sz > 0) { 00628 XMEMCPY(err->file, file, sz); 00629 } 00630 00631 err->value = error; 00632 err->line = line; 00633 00634 /* make sure is terminated */ 00635 err->error[WOLFSSL_MAX_ERROR_SZ - 1] = '\0'; 00636 err->file[WOLFSSL_MAX_ERROR_SZ - 1] = '\0'; 00637 00638 00639 /* since is queue place new node at last of the list */ 00640 if (wc_last_node == NULL) { 00641 /* case of first node added to queue */ 00642 if (wc_errors != NULL) { 00643 /* check for unexpected case before over writing wc_errors */ 00644 WOLFSSL_MSG("ERROR in adding new node to logging queue!!\n"); 00645 /* In the event both wc_last_node and wc_errors are NULL, err 00646 * goes unassigned to external wc_errors, wc_last_node. Free 00647 * err in this instance since wc_ClearErrorNodes will not 00648 */ 00649 XFREE(err, wc_error_heap, DYNAMIC_TYPE_LOG); 00650 } 00651 else { 00652 wc_errors = err; 00653 wc_last_node = err; 00654 wc_current_node = err; 00655 } 00656 } 00657 else { 00658 wc_last_node->next = err; 00659 err->prev = wc_last_node; 00660 wc_last_node = err; 00661 00662 /* check the case where have read to the end of the queue and the 00663 * current node to read needs updated */ 00664 if (wc_current_node == NULL) { 00665 wc_current_node = err; 00666 } 00667 } 00668 } 00669 #endif 00670 return 0; 00671 } 00672 00673 /* Removes the error node at the specified index. 00674 * idx : if -1 then the most recent node is looked at, otherwise search 00675 * through queue for node at the given index 00676 */ 00677 void wc_RemoveErrorNode(int idx) 00678 { 00679 struct wc_error_queue* current; 00680 00681 if (wc_LockMutex(&debug_mutex) != 0) { 00682 WOLFSSL_MSG("Lock debug mutex failed"); 00683 return; 00684 } 00685 00686 if (idx == -1) 00687 current = wc_last_node; 00688 else { 00689 current = (struct wc_error_queue*)wc_errors; 00690 for (; current != NULL && idx > 0; idx--) 00691 current = current->next; 00692 } 00693 if (current != NULL) { 00694 if (current->prev != NULL) 00695 current->prev->next = current->next; 00696 if (current->next != NULL) 00697 current->next->prev = current->prev; 00698 if (wc_last_node == current) 00699 wc_last_node = current->prev; 00700 if (wc_errors == current) 00701 wc_errors = current->next; 00702 if (wc_current_node == current) 00703 wc_current_node = current->next; 00704 XFREE(current, current->heap, DYNAMIC_TYPE_LOG); 00705 } 00706 00707 wc_UnLockMutex(&debug_mutex); 00708 } 00709 00710 00711 /* Clears out the list of error nodes. 00712 */ 00713 void wc_ClearErrorNodes(void) 00714 { 00715 #if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \ 00716 defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) 00717 00718 if (wc_LockMutex(&debug_mutex) != 0) { 00719 WOLFSSL_MSG("Lock debug mutex failed"); 00720 return; 00721 } 00722 00723 /* free all nodes from error queue */ 00724 { 00725 struct wc_error_queue* current; 00726 struct wc_error_queue* next; 00727 00728 current = (struct wc_error_queue*)wc_errors; 00729 while (current != NULL) { 00730 next = current->next; 00731 XFREE(current, current->heap, DYNAMIC_TYPE_LOG); 00732 current = next; 00733 } 00734 } 00735 00736 wc_errors = NULL; 00737 wc_last_node = NULL; 00738 wc_current_node = NULL; 00739 wc_UnLockMutex(&debug_mutex); 00740 #endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */ 00741 } 00742 00743 int wc_SetLoggingHeap(void* h) 00744 { 00745 if (wc_LockMutex(&debug_mutex) != 0) { 00746 WOLFSSL_MSG("Lock debug mutex failed"); 00747 return BAD_MUTEX_E; 00748 } 00749 wc_error_heap = h; 00750 wc_UnLockMutex(&debug_mutex); 00751 return 0; 00752 } 00753 00754 00755 /* frees all nodes in the queue 00756 * 00757 * id this is the thread id 00758 */ 00759 int wc_ERR_remove_state(void) 00760 { 00761 struct wc_error_queue* current; 00762 struct wc_error_queue* next; 00763 00764 if (wc_LockMutex(&debug_mutex) != 0) { 00765 WOLFSSL_MSG("Lock debug mutex failed"); 00766 return BAD_MUTEX_E; 00767 } 00768 00769 /* free all nodes from error queue */ 00770 current = (struct wc_error_queue*)wc_errors; 00771 while (current != NULL) { 00772 next = current->next; 00773 XFREE(current, current->heap, DYNAMIC_TYPE_LOG); 00774 current = next; 00775 } 00776 00777 wc_errors = NULL; 00778 wc_last_node = NULL; 00779 00780 wc_UnLockMutex(&debug_mutex); 00781 00782 return 0; 00783 } 00784 00785 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) 00786 /* empties out the error queue into the file */ 00787 static int wc_ERR_dump_to_file (const char *str, size_t len, void *u) 00788 { 00789 XFILE fp = (XFILE ) u; 00790 fprintf(fp, "%-*.*s\n", (int)len, (int)len, str); 00791 return 0; 00792 } 00793 00794 /* This callback allows the application to provide a custom error printing 00795 * function. */ 00796 void wc_ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), 00797 void *u) 00798 { 00799 WOLFSSL_ENTER("wc_ERR_print_errors_cb"); 00800 00801 if (cb == NULL) { 00802 /* Invalid param */ 00803 return; 00804 } 00805 00806 if (wc_LockMutex(&debug_mutex) != 0) 00807 { 00808 WOLFSSL_MSG("Lock debug mutex failed"); 00809 } 00810 else 00811 { 00812 /* free all nodes from error queue and print them to file */ 00813 struct wc_error_queue *current; 00814 struct wc_error_queue *next; 00815 00816 current = (struct wc_error_queue *)wc_errors; 00817 while (current != NULL) 00818 { 00819 next = current->next; 00820 cb(current->error, strlen(current->error), u); 00821 XFREE(current, current->heap, DYNAMIC_TYPE_LOG); 00822 current = next; 00823 } 00824 00825 /* set global pointers to match having been freed */ 00826 wc_errors = NULL; 00827 wc_last_node = NULL; 00828 00829 wc_UnLockMutex(&debug_mutex); 00830 } 00831 } 00832 00833 void wc_ERR_print_errors_fp(XFILE fp) 00834 { 00835 WOLFSSL_ENTER("wc_ERR_print_errors_fp"); 00836 00837 /* Send all errors to the wc_ERR_dump_to_file function */ 00838 wc_ERR_print_errors_cb(wc_ERR_dump_to_file, fp); 00839 } 00840 00841 #endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */ 00842 00843 #endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */ 00844
Generated on Tue Jul 12 2022 20:58:40 by 1.7.2