mirror of
https://github.com/open62541/open62541.git
synced 2026-10-18 13:42:32 +08:00
6901aedc07
Port keyless certificate validation into the GDS receiver driver instead of restoring the removed server implementation. Preserve master's timer batching, PubSub lifecycle and client HTTP configuration handling. Adapt Publish cancellation to response tokens and the HEL/fuzz harnesses to the explicit TCP driver. Keep SKS policy history and custom datatype ownership intact, including failed replacement configuration cleanup. Retain TPM error cleanup while enforcing key-handle and nonce lengths. Validation: - Full mbedTLS unit-test build with full namespace, GDS, SKS and Query. - 21 affected suites passed with ASan/UBSan, plus 9 isolated SKS ownership and lifecycle checks. - OpenSSL certificate update, GDS information model and client encryption suites passed with sanitizers. - OPN, MSG and binary-message fuzzers each completed 100 sanitizer runs. - Both TPM PubSub policy sources passed compilation checks. The full SKS client suite timed out after multicast UDP sends reported "No route to host" on this machine; its affected ownership and lifecycle cases passed separately. No live TPM hardware validation was performed.
135 lines
4.1 KiB
C
135 lines
4.1 KiB
C
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
|
|
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
|
|
*
|
|
* Copyright 2016-2018 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
|
|
* Copyright 2017 (c) Thomas Stalder, Blue Time Concept SA
|
|
*/
|
|
|
|
#include <open62541/plugin/log_stdout.h>
|
|
#include <open62541/types.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "mp_printf.h"
|
|
|
|
/* ANSI escape sequences for color output taken from here:
|
|
* https://stackoverflow.com/questions/3219393/stdlib-and-colored-output-in-c*/
|
|
|
|
#ifdef UA_ARCHITECTURE_POSIX
|
|
# define ANSI_COLOR_RED "\x1b[31m"
|
|
# define ANSI_COLOR_GREEN "\x1b[32m"
|
|
# define ANSI_COLOR_YELLOW "\x1b[33m"
|
|
/* # define ANSI_COLOR_BLUE "\x1b[34m" */
|
|
# define ANSI_COLOR_MAGENTA "\x1b[35m"
|
|
/* # define ANSI_COLOR_CYAN "\x1b[36m" */
|
|
# define ANSI_COLOR_RESET "\x1b[0m"
|
|
#else
|
|
# define ANSI_COLOR_RED ""
|
|
# define ANSI_COLOR_GREEN ""
|
|
# define ANSI_COLOR_YELLOW ""
|
|
/* # define ANSI_COLOR_BLUE "" */
|
|
# define ANSI_COLOR_MAGENTA ""
|
|
/* # define ANSI_COLOR_CYAN "" */
|
|
# define ANSI_COLOR_RESET ""
|
|
#endif
|
|
|
|
static
|
|
const char *logLevelNames[6] = {"trace", "debug",
|
|
ANSI_COLOR_GREEN "info",
|
|
ANSI_COLOR_YELLOW "warn",
|
|
ANSI_COLOR_RED "error",
|
|
ANSI_COLOR_MAGENTA "fatal"};
|
|
static const char *
|
|
logCategoryNames[UA_LOGCATEGORIES] =
|
|
{"network", "channel", "session", "server", "client",
|
|
"application", "security", "eventloop", "pubsub", "discovery"};
|
|
|
|
static const char *
|
|
logCategoryName(UA_LogCategory category) {
|
|
if((UA_UInt32)category >= UA_LOGCATEGORIES)
|
|
return "unknown";
|
|
return logCategoryNames[category];
|
|
}
|
|
|
|
/* Protect crosstalk during logging via global lock. Use a spinlock as we cannot
|
|
* statically initialize a global lock across all platforms. */
|
|
#if UA_MULTITHREADING >= 100
|
|
static UA_atomic(void *) logSpinLock = NULL;
|
|
static UA_INLINE void spinLock(void) {
|
|
void *expected;
|
|
do {
|
|
expected = NULL;
|
|
UA_atomic_cmpxchg(&logSpinLock, &expected, (void*)0x1);
|
|
} while(expected != NULL);
|
|
}
|
|
static UA_INLINE void spinUnLock(void) {
|
|
UA_atomic_store(&logSpinLock, NULL);
|
|
}
|
|
#endif
|
|
|
|
#ifdef __clang__
|
|
__attribute__((__format__(__printf__, 4 , 0)))
|
|
#endif
|
|
static void
|
|
UA_Log_Stdout_log(void *context, UA_LogLevel level, UA_LogCategory category,
|
|
const char *msg, va_list args) {
|
|
/* MinLevel encoded in the context pointer */
|
|
UA_LogLevel minLevel = (UA_LogLevel)(uintptr_t)context;
|
|
if(minLevel > level)
|
|
return;
|
|
|
|
UA_Int64 tOffset = UA_DateTime_localTimeUtcOffset();
|
|
UA_DateTimeStruct dts = UA_DateTime_toStruct(UA_DateTime_now() + tOffset);
|
|
|
|
int logLevelSlot = ((int)level / 100) - 1;
|
|
if(logLevelSlot < 0 || logLevelSlot > 5)
|
|
logLevelSlot = 5; /* Set to fatal if the level is outside the range */
|
|
|
|
/* Lock */
|
|
#if UA_MULTITHREADING >= 100
|
|
spinLock();
|
|
#endif
|
|
|
|
#define STDOUT_LOGBUFSIZE 512
|
|
char logbuf[STDOUT_LOGBUFSIZE];
|
|
|
|
/* Log */
|
|
printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u (UTC%+05d)] %s/%s" ANSI_COLOR_RESET "\t",
|
|
dts.year, dts.month, dts.day, dts.hour, dts.min, dts.sec, dts.milliSec,
|
|
(int)(tOffset / UA_DATETIME_SEC / 36), logLevelNames[logLevelSlot],
|
|
logCategoryName(category));
|
|
mp_vsnprintf(logbuf, STDOUT_LOGBUFSIZE, msg, args);
|
|
printf("%s\n", logbuf);
|
|
(void)fflush(stdout); /* Logging is best-effort and cannot report failure. */
|
|
|
|
/* Unlock */
|
|
#if UA_MULTITHREADING >= 100
|
|
spinUnLock();
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
UA_Log_Stdout_clear(UA_Logger *logger) {
|
|
UA_free(logger);
|
|
}
|
|
|
|
const UA_Logger UA_Log_Stdout_ = {UA_Log_Stdout_log, NULL, NULL};
|
|
const UA_Logger *UA_Log_Stdout = &UA_Log_Stdout_;
|
|
|
|
UA_Logger
|
|
UA_Log_Stdout_withLevel(UA_LogLevel minlevel) {
|
|
UA_Logger logger =
|
|
{UA_Log_Stdout_log, (void*)(uintptr_t)minlevel, NULL};
|
|
return logger;
|
|
}
|
|
|
|
UA_Logger *
|
|
UA_Log_Stdout_new(UA_LogLevel minlevel) {
|
|
UA_Logger *logger = (UA_Logger*)UA_malloc(sizeof(UA_Logger));
|
|
if(!logger)
|
|
return NULL;
|
|
*logger = UA_Log_Stdout_withLevel(minlevel);
|
|
logger->clear = UA_Log_Stdout_clear;
|
|
return logger;
|
|
}
|