80 Commits
Author SHA1 Message Date
Niels Beier 7bae399502 fix(server): use the session state, add the Session purge, adapt tests to the new behavior 2026-10-17 14:12:21 +02:00
Julius Pfrommer 3d390d26b1 Merge remote-tracking branch 'origin/1.5' into merge_15_master
# Conflicts:
#	CHANGES.md
#	src/server/ua_services_attribute.c
#	src/server/ua_transport_tcp.c
#	tests/server/check_accesscontrol.c
2026-10-08 14:33:33 +02:00
StalderT ed5d86df4d fix(server): drop links to deleted MonitoredItems in SetTriggering
Links to a deleted MonitoredItem were only removed when the triggering item reported. If it never reports (Disabled mode, or a value that does not change), they stay forever, and since MonitoredItem ids are never reused a client can grow the link array of one item without bound by creating, linking and deleting items in a loop. Every addLink scans that array, so SetTriggering gets slower with each round.

Part 4, 5.13.1.6 says that the link goes away with the triggered item. SetTriggering now prunes the links of the triggering item to MonitoredItems that no longer exist before applying the request, which keeps the array bounded by the items of the Subscription.
2026-10-06 12:47:29 +02:00
Niels Beier bc51e62537 test(server): check the end of the first publishing cycle 2026-10-06 09:18:05 +02:00
Niels Beier edc16fb6f2 test(server): cover transfer of detached Subscriptions 2026-10-06 07:37:13 +02:00
StalderT b2eae285f9 fix(server): limit the number of links in SetTriggering
CreateMonitoredItems, ModifyMonitoredItems, SetMonitoringMode and DeleteMonitoredItems all check maxMonitoredItemsPerCall, but SetTriggering accepted any number of links. Apply the same limit there, counting the links to add and the links to remove together, and return Bad_TooManyOperations above it (Part 4, 5.13.5).

Also free removeResults with its own size in the out-of-memory path, it was using linksToAddSize.
2026-10-05 23:35:14 +02:00
Niels Beier 32c514b4c7 test(server): check the StatusChange after a transfer without Publish 2026-10-05 23:30:06 +02:00
Julius Pfrommer 9a43b33a4b Merge remote-tracking branch 'origin/1.5' into merge_15_master
# Conflicts:
#	plugins/crypto/mbedtls/create_certificate.c
#	plugins/crypto/mbedtls/securitypolicy_aes256sha256rsapss.c
#	plugins/crypto/mbedtls/securitypolicy_common.c
#	src/client/ua_client.c
#	src/pubsub/ua_pubsub_config.c
#	src/pubsub/ua_pubsub_keystorage.c
#	src/pubsub/ua_pubsub_keystorage.h
#	src/pubsub/ua_pubsub_ns0.c
#	src/pubsub/ua_pubsub_ns0_sks.c
#	src/pubsub/ua_pubsub_securitygroup.c
#	src/pubsub/ua_pubsub_writer.c
#	src/pubsub/ua_pubsub_writergroup.c
#	src/server/ua_server_ns0.c
#	src/server/ua_server_ns0_gds.c
#	src/server/ua_server_utils.c
#	src/server/ua_services_session.c
#	src/server/ua_subscription_alarms_conditions.c
#	src/ua_types_encoding_xml.c
#	tests/check_types_builtin_xml.c
#	tests/encryption/check_cert_generation.c
#	tests/pubsub/check_pubsub_configuration.c
#	tests/pubsub/check_pubsub_informationmodel_methods.c
#	tests/pubsub/check_pubsub_publish.c
#	tests/pubsub/check_pubsub_sks_client.c
#	tests/pubsub/check_pubsub_sks_keystorage.c
#	tests/pubsub/check_pubsub_sks_push.c
#	tests/pubsub/check_pubsub_sks_securitygroups.c
#	tests/server/check_server_alarmsconditions.c
2026-09-20 10:02:09 +02:00
Julius Pfrommer c15f297b8d Merge remote-tracking branch 'origin/1.4' into merge_14_15
# Conflicts:
#	CHANGELOG
#	CMakeLists.txt
#	plugins/crypto/openssl/securitypolicy_openssl_common.c
#	plugins/crypto/pkcs11/securitypolicy_pubsub_aes128ctr_tpm.c
#	plugins/crypto/pkcs11/securitypolicy_pubsub_aes256ctr_tpm.c
#	src/pubsub/ua_pubsub_networkmessage.c
#	src/pubsub/ua_pubsub_ns0.c
#	src/pubsub/ua_pubsub_writer.c
#	src/pubsub/ua_pubsub_writergroup.c
#	src/server/ua_services_monitoreditem.c
#	src/server/ua_services_session.c
#	src/server/ua_session.h
#	tests/CMakeLists.txt
#	tests/check_securechannel.c
#	tests/pubsub/check_pubsub_encryption.c
#	tests/pubsub/check_pubsub_publish.c
#	tests/server/check_server_alarmsconditions.c
2026-09-17 21:58:21 +02:00
Julius Pfrommer da61fd82a9 test(server): support the Check version on Ubuntu 20.04 2026-09-15 20:11:28 +02:00
Julius Pfrommer 30701e5cff fix(server): bound diagnostics member names
Session and subscription diagnostics callbacks copied a node BrowseName into a fixed 128-byte stack buffer without checking its length. A modified diagnostics model could therefore overflow the stack when the node was read.

Reject names that cannot fit, including the terminator, and cover both callbacks with a regression test.
2026-09-15 20:11:28 +02:00
Julius Pfrommer 432353d3dc fix(server): sanitize modified sampling intervals 2026-09-13 22:16:32 +02:00
Julius Pfrommer a476806541 Merge remote-tracking branch 'origin/1.5' into merge_15_master
# Conflicts:
#	.github/workflows/build_linux.yml
#	CHANGES.md
#	arch/common/eventloop_mqtt.c
#	examples/encryption/server_encryption_filestore.c
#	plugins/crypto/ua_certificategroup_filestore.c
#	src/pubsub/ua_pubsub_networkmessage_json.c
#	src/server/ua_discovery.h
#	src/server/ua_discovery_mdns.c
#	src/server/ua_discovery_mdns_avahi.c
#	src/server/ua_services_attribute.c
#	src/server/ua_services_discovery.c
#	src/server/ua_services_monitoreditem.c
#	src/server/ua_services_nodemanagement.c
#	src/server/ua_subscription.c
#	src/server/ua_subscription.h
#	src/server/ua_subscription_alarms_conditions.c
#	src/server/ua_subscription_event.c
#	src/ua_types_encoding_json_105.c
#	tests/client/check_activateSessionAsync.c
#	tests/server/check_local_monitored_item.c
#	tests/server/check_services_subscriptions.c
2026-09-03 14:33:21 +02:00
StalderT f388a96ada perf(server): O(1) MonitoredItem removal via the intrusive LIST macros
The per-node MonitoredItem back-pointer list (UA_NodeHead.monitoredItems)
was a hand-rolled singly-linked list. Removing an item scanned the list to
find its predecessor, so tearing down all MonitoredItems attached to one
node was O(n^2).

Switch the list to the intrusive BSD-style LIST_* macros from
deps/open62541_queue.h, already used for the subscription sampling list.
Removal follows the le_prev back-pointer and is O(1); no search is needed.

The list head stays the bare UA_MonitoredItem* in the public UA_NodeHead
(plugin/nodestore.h): it is layout-compatible with a LIST_HEAD, so the
server casts the address of that field to UA_MonitoredItemList* to run the
LIST_* macros over it. The public header and the generated amalgamation
therefore stay independent of open62541_queue.h. The cast is type-punning
that relies on this layout compatibility, and the build already sets
-fno-strict-aliasing.

The intrusive list adds an invariant the previous one did not have: the
le_prev of the first element points into the node that holds the list
head. Nothing has to be re-anchored on a node copy, because the server
only edits nodes in place -- UA_Server_editNode goes through getEditNode,
which the ziptree nodestore implements in-situ -- so a live node never
moves. A nodestore that instead relocates a node (getNodeCopy followed by
replaceNode, which no caller in the server uses today) has to re-anchor
le_prev onto the replacement after a successful replace: carrying the head
pointer over on its own is not sufficient. Re-anchoring at copy time would
be wrong, since the copy still shares the list with the source and the
replace may still fail.

Add a regression test on the per-node list (samplingInterval == 0, "on
write" sampling) covering head, interior and tail removal as well as the
on-write iterator, asserting the *le_prev == element invariant on every
element throughout.

Tearing down N MonitoredItems attached to a single node was O(n^2).
Deleting them now scales linearly:

    N         delete before    delete after
    20000       669 ms           29 ms   (x23)
    50000      6477 ms           71 ms   (x92)
    80000     25756 ms          120 ms  (x215)
   100000     66072 ms          169 ms  (x391)

(amalgamation of each revision built identically with -O2 -DNDEBUG.)
2026-09-03 07:54:40 +02:00
Julius Pfrommer 36f44a977c test(server): cover session closure during monitored item creation
Closing the owning session from MONITOREDITEM_CREATED queues MonitoredItem, Subscription and Session cleanup in one reentrant call stack. Verify that current 1.5 lifecycle handling removes all three objects and that the later Subscription and Session cleanup callbacks are each reached exactly once.
2026-08-31 07:29:36 +02:00
StalderT 7d8f7d84f8 fix(server): Lookup tree for MonitoredItems to prevent accidentally quadratic runtime (#7884) 2026-08-30 21:05:40 +02:00
Julius Pfrommer f499999fe5 fix(server): harden subscription lifecycle reentrancy
Make MonitoredItem and Subscription removal terminal and idempotent while their allocations remain delayed-valid. Prevent sampling, data-change processing, and event-filter completion from enqueueing work after reentrant deletion.

Cover deletion from an application-backed data-source read and Session closure from a MonitoredItem deletion callback during Subscription teardown.
2026-08-30 16:20:31 +02:00
Julius Pfrommer 2e58975548 fix(server): treat zero session and channel limits as unlimited
Honor the established zero-as-unlimited convention when creating Sessions and SecureChannels.

Document the sentinel behavior and add regression coverage for both paths.
2026-08-28 19:09:35 +02:00
Julius Pfrommer f9965e0d0a test(server): cover resource-limit defaults and rejection logs
Verify the bounded default configuration and both MonitoredItem limit paths.

Check that resource rejections use warning-level Session logging.
2026-08-28 19:09:35 +02:00
Andreas Ebner d2c5d0aff0 Merge remote-tracking branch 'origin/1.5' into merge_15_master_5
# Conflicts:
#	CMakeLists.txt
#	src/server/ua_session.c
#	src/ua_types_encoding_json.c
#	src/ua_types_encoding_json_105.c
#	tests/CMakeLists.txt
#	tests/pubsub/check_pubsub_publish.c
#	tests/server/check_services_subscriptions.c
#	tests/valgrind_check_error.py
#	tools/ci/linux/ci.sh
2026-07-17 09:19:33 +02:00
Andreas Ebner e92e2ea71e test: extend coverage across core, server, client, security and subscription
Add unit tests for previously-uncovered branches and fix registration issues found in PR #8088 review.
2026-07-15 14:15:49 +02:00
Julius Pfrommer 60ce89f362 fix(server): Notify a Subscription deletion also during server shutdown 2026-07-03 07:18:14 +02:00
Julius Pfrommer df52807cfa breaking(server): Remove/replace monitoredItemRegisterCallback in server config
The functionality is now provided by the unified notification mechanism instead of a dedicated callback signature.
2026-07-03 07:18:14 +02:00
Julius Pfrommer 4b317d1bc6 Merge remote-tracking branch 'origin/1.4' into merge_14_15_2 2026-06-27 20:02:25 +02:00
Niels Beier bbe99cf606 test(server): update subscription-survives-timeout test for detached-transfer policy 2026-06-25 14:16:17 +02:00
Julius Pfrommer 450bdaf19b Merge remote-tracking branch 'origin/1.4' into merge_14_15_7 2026-05-12 11:19:46 +02:00
Andreas Ebner 944aca6fde fix(server): Variables with DataSource and SamplingInterval=0 receive DataChangeNotifications
When a MonitoredItem with SamplingInterval=0 targets a DataSource node,
the server was unconditionally installing an EVENT (backpointer) sampler.
Backpointer sampling only fires when the node is written via the OPC UA
Write service. DataSource nodes (e.g. Server/ServerStatus/CurrentTime)
compute their value on-the-fly in a read callback; they are never written
via Write, so no DataChangeNotification was ever enqueued.

A regression test is added to check_services_subscriptions.c that monitors
Server/ServerStatus/CurrentTime (i=2258) -- always available, no compile
flags required. The test verifies:
 - samplingType == UA_MONITOREDITEMSAMPLINGTYPE_PUBLISH (structural fix)
 - queue grows after each publish cycle (functional fix)
 - second notification has a strictly later DateTime value
2026-05-12 00:42:27 +02:00
StalderT 442e6d58ba fix(server): avoid dangling pointer warning in notifySubscription
Fix a build failure with recent GCC versions when compiling with
`-Werror`.

The function `notifySubscription()` stores the address of a stack
variable (`enabled`) in a `UA_Variant` via `UA_Variant_setScalar()`.
Newer GCC versions detect this as a potential dangling pointer
(`-Wdangling-pointer`).

To avoid storing a pointer to a stack variable, the value is now taken
directly from the subscription object instead of using a temporary local
variable.

    error: storing the address of local variable 'enabled' in
    'createSubData[7].value.data' [-Werror=dangling-pointer]

-   Remove the temporary stack variable `enabled`
-   Use the subscription state directly when populating the `UA_Variant`

``` c
UA_Boolean enabled = (sub->state = UA_SUBSCRIPTIONSTATE_ENABLED);

UA_Variant_setScalar(&createSubData[7].value, &enabled,
                     &UA_TYPES[UA_TYPES_BOOLEAN]);
```

``` c
sub->enabled = (sub->state == UA_SUBSCRIPTIONSTATE_ENABLED);

UA_Variant_setScalar(&createSubData[7].value, &sub->enabled,
                     &UA_TYPES[UA_TYPES_BOOLEAN]);
```

-   OS: Linux
-   Compiler: GCC 13 / GCC 14
-   Build flags: `-Wall -Wextra -Werror`

fix(server): avoid dangling pointer warning in notifySubscription

Fix a build failure with recent GCC versions when compiling with
`-Werror`.

The function `notifySubscription()` stores the address of a stack
variable (`enabled`) in a `UA_Variant` via `UA_Variant_setScalar()`.
Newer GCC versions detect this as a potential dangling pointer
(`-Wdangling-pointer`).

To avoid storing a pointer to a stack variable, the value is now taken
directly from the subscription object instead of using a temporary local
variable.

    error: storing the address of local variable 'enabled' in
    'createSubData[7].value.data' [-Werror=dangling-pointer]

-   Remove the temporary stack variable `enabled`
-   Use the subscription state directly when populating the `UA_Variant`

``` c
UA_Boolean enabled = (sub->state = UA_SUBSCRIPTIONSTATE_ENABLED);

UA_Variant_setScalar(&createSubData[7].value, &enabled,
                     &UA_TYPES[UA_TYPES_BOOLEAN]);
```

``` c
sub->enabled = (sub->state == UA_SUBSCRIPTIONSTATE_ENABLED);

UA_Variant_setScalar(&createSubData[7].value, &sub->enabled,
                     &UA_TYPES[UA_TYPES_BOOLEAN]);
```

-   OS: Linux
-   Compiler: GCC 13 / GCC 14
-   Build flags: `-Wall -Wextra -Werror`

server: fix potential dangling pointer in subscription notification data and add test
2026-03-31 14:13:37 +02:00
Andreas Ebner 7bc0c36af9 tests(server): add coverage tests for src/server/ 2026-03-06 09:17:03 +01:00
Andreas Ebner c625d1dade fix(server): detach subscriptions on session timeout instead of deleting
When a session timed out, the server unconditionally deleted all
subscriptions owned by that session. Per OPC UA Part 4, §5.13.7,
the subscription lifetime is independent of the session lifetime.
Subscriptions whose lifetime has not expired must survive the session
timeout so clients can recover them via TransferSubscriptions.

Detach subscriptions (instead of deleting them) when the shutdown
reason is UA_SHUTDOWNREASON_TIMEOUT. Detached subscriptions remain
in the server-wide list with session==NULL and self-destruct when
their own lifetime expires.
2026-02-27 23:52:24 +01:00
Julius Pfrommer de4709cb0f Merge remote-tracking branch 'origin/1.4' into merge_14_15_5 2026-02-17 13:56:24 +01:00
Andreas Ebner b53cebc4dc fix(server): block transfer subscription for anonymous users including unit tests
- Modified allowTransferSubscription_default() to use UA_String_equal()
  for direct string comparison instead of UA_order()
- Added explicit check: userId->length == 0 means anonymous user
- Anonymous users are rejected from transferring subscriptions
- Added Server_transferSubscription_anonymous unit test
- Added createAuthenticatedSession() helper for authenticated tests
- Updated Server_transferSubscriptionDiagnostics to use authenticated sessions
- All 17 unit tests pass

This fix addresses the OPC UA CTT compliance requirement that
anonymous users should not be allowed to transfer subscriptions.
2026-02-16 22:08:56 +01:00
Julius Pfrommer e15dd97712 Merge remote-tracking branch 'origin/1.4' into merge_14_15_4 2026-02-12 16:13:16 +01:00
Andreas Ebner 05b8129793 fix(server): track transferred subscriptions for correct diagnostics counter update
Add wasTransferred flag to UA_Subscription to prevent incorrect
currentSubscriptionCount decrements when a subscription is transferred
to another session and the old subscription object is deleted.

When a subscription is transferred, the old subscription object is
deleted but the subscription continues to exist under a new object.
The diagnostics counter should only be decremented when a subscription
is truly deleted, not when it's being replaced during a transfer.

Includes test case to verify the fix.

add author information
2026-02-12 13:09:49 +01:00
Julius Pfrommer 7db36eaedd refactor(tests): Remove the dependency of the server tests on realSleep 2025-11-05 09:03:43 +01:00
Julius Pfrommer 51df8ebf3e refactor(server): Remove UA_Server_ prefix from internal methods 2025-10-14 15:48:16 +02:00
Julius Pfrommer 99d4d46804 Merge remote-tracking branch 'origin/1.4' into merge_14_master_25 2025-01-28 06:55:14 +01:00
Julius Pfrommer 1321281968 refactor(tests): Lock the EventLoop before client/server in the tests 2025-01-26 23:29:22 +01:00
Julius Pfrommer 4d3aedd74b refactor(server): Unify duplicate UA_MonitoredItem_sample definitions 2024-05-28 22:52:07 +02:00
Julius Pfrommer dd300f3eff refactor(tests): Set a custom "fake" clock in the EventLoop for unit tests 2023-10-04 10:56:26 +02:00
Julius Pfrommer 390c092c05 refactor(tests): Include stdlib.h where open62541 no longer does it 2023-07-28 21:42:56 +02:00
Julius Pfrommer 1630f9dc0c fix(server): Return publishing interval if sampling interval == -1.0 2023-04-28 01:03:42 +02:00
Julius Pfrommer b33540652d Merge branch 'negative_sampling_interval' 2023-02-01 11:26:19 +01:00
Julius Pfrommer c351fe96c8 fix(server): Sample MonitoredItems with interval <0 together with the subscription publish callback 2023-01-31 23:22:02 +01:00
StalderT 05951d5973 fix(server): Allow negative sampling interval
According to https://reference.opcfoundation.org/Core/Part4/v104/docs/5.12.1.2, a negative Sampling interval number indicates that the default sampling interval defined by the publishing interval of the Subscription is requested.
2023-01-31 22:16:50 +01:00
Andreas Eckerstorfer 022ad60723 fix (tests): Check server instance in UNIT tests
Failed UNIT tests caused an exception in the server loop, if the
server instance could not be created.
2023-01-31 00:07:18 +01:00
Andreas Eckerstorfer 13af9b8688 refactor(core): Remove trailing spaces in code (#5221) 2022-06-24 11:03:25 +02:00
Julius Pfrommer 46a12f16a6 feat(server): Enable DataChange MonitoredItems with zero sampling interval 2021-09-23 20:07:12 +02:00
Julius Pfrommer 4843f912b0 refactor(server): Simplify datachange monitoreditem sampling 2021-09-23 17:49:21 +02:00
Julius Pfrommer 27d78c346c refactor(server): Use UA_order to test for data changes in MonitoredItems 2021-09-23 17:49:21 +02:00