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.
Fix misspellings found with codespell across headers, sources, examples,
tests and the documentation, including "propably" in the nodeset
compiler docs. Identifiers, companion spec names and generated code are
left untouched.
batchTimerEntry passed the search window and the batching candidate to the ZIP tree iteration through three file-static variables. The comment above them claims they are only used behind the mutex, but that mutex belongs to a single UA_Timer while the variables belong to the process, and with UA_MULTITHREADING below 100 the lock macros expand to nothing at all. Two timers driven from two threads therefore overwrite each other's state, which is exactly the arrangement the library recommends: one UA_Server and one UA_Client in the same process, each iterated from its own thread, with no instance ever shared.
The effect is silent in a release build. A cyclic callback picks up the nextTime computed for an unrelated timer and fires up to one second early or late, since the batching window is capped at UA_DATETIME_SEC. In a debug build the assertion in findTimer2Batch trips first, because the window it checks against no longer belongs to the entry being iterated.
The window and the candidate now live in a context on the stack of batchTimerEntry. The window doubles as the ZIP_ITER_KEY key, which is how cmpBatchWindow receives both bounds without static state.
No regression test: the overwrite only appears when two batchTimerEntry
calls interleave across threads, and the valgrind stage serialises them.
A threaded probe caught it 10 times out of 10 natively and 0 out of 3
under valgrind, at 240 to 400 seconds a run.
Forward read and write readiness together in the POSIX and GLib backends.
Prioritizing input can starve MQTT/TLS progress while both directions are
ready. Let the TCP callback recognize combined events as well.
Pass combined readiness and socket errors to libwebsockets in one service
call, so the library can also finish closing failed TLS connections.
Add a socket-pair regression for simultaneous readiness and allow the MQTT
test peer to queue TLS records between event-loop iterations.
Compare local and UTC representations of the same instant instead of interpreting UTC as local time through mktime. This avoids timezone-cache churn reported by TSan during concurrent logging and handles fractional offsets and date rollover.
Add coverage for positive, negative and fractional-hour timezone offsets.
Timer instances have separate mutexes, so global batching-window variables race when independent event loops add or reschedule timers concurrently.
Walk the time tree with stack-local window bounds and preserve interval matching. Cover concurrent independent timers and the batching window boundary.
gmtime and inet_ntoa return a pointer to a static buffer shared by all threads. The mbedTLS certificate creation now derives its validity dates from UA_DateTime_now/UA_DateTime_toStruct, which also keeps the expiry date in UTC (mktime interpreted the gmtime result as local time). Zephyr uses gmtime_r and lwIP ip4addr_ntoa_r.
Fixes#7997
Preserve master XML and node-management behavior, adapt regression tests to the driver and built-in NodeSet loader APIs, and extend compatibility with older Check releases.
Registers each interrupt as a GLib GSource (g_unix_signal_source_new)
attached to the owning EventLoop's GMainContext, so GLib itself handles
signal delivery instead of the POSIX InterruptManager's sigaction +
self-pipe. Documents two GLib-inherent semantics this implies: async
delivery via GLib's worker thread, and no fan-out of one signal to
multiple independent watchers of the same signum.
Claude-Session: https://claude.ai/code/session_0184Hjzh21f51SYHg2bdbhz4
Adds UA_EventLoop_new_GLib, an alternative to UA_EventLoop_new_POSIX that
attaches a GSource to a GMainContext instead of calling select()/epoll_wait()
directly. Once started, the EventLoop's sockets and timers are serviced
whenever the attached GMainContext is iterated (e.g. g_main_loop_run(),
gtk_main(), g_application_run()), so a GLib-based application can drive the
whole open62541 stack without ever calling the EventLoop's own run() method.
To share the existing TCP/UDP/Ethernet/Interrupt ConnectionManagers between
both backends without duplicating their logic, UA_EventLoopPOSIX now
dispatches FD registration through per-instance registerFD/modifyFD/
deregisterFD function pointers instead of hardcoded select/epoll functions.
The timer, delayed-callback queue, EventSource lifecycle and DateTime
handling are also factored out for reuse by the GLib backend.
Enable via the new UA_ENABLE_EVENTLOOP_GLIB CMake option (requires
glib-2.0). check_eventloop_tcp_glib.c exercises the same TCP scenarios as
check_eventloop_tcp.c against the GLib backend.
Claude-Session: https://claude.ai/code/session_01FLwAbeM7su3EabJw4q51ap