OPCFoundation / UA-.NETStandard

OPC Unified Architecture .NET Standard
Other
1.89k stars 926 forks source link

IOP: BrowseNext continuation is not always handled correctly, when multiple nodes are browsed #2566

Open mregen opened 3 months ago

mregen commented 3 months ago

Type of issue

Current Behavior

The browse continuation must take into account that a server may have only a limited number of continuations. BrowseNext must be called first before issueing the next browse, specifically if the call is batched in multiple service calls, and for the status result: BadNoContinuationPoints the browse must be repeated. The ClientSample handles the browse correctly, but e.g. NodeCache internally does not.

Expected Behavior

No response

Steps To Reproduce

Browse a server with many nested nodes that contain a lot of child nodes which cause a continuation with BrowseNext. Browse results may be incorrect if the BadNoContinuationPoints is ignored or if a new Browse is started before the continuation points are processed with BrowseNext.

Environment

- OS:
- Environment:
- Runtime:
- Nuget Version:
- Component:
- Server:
- Client:

Anything else?

No response

ThomasNehring commented 1 month ago

Hi Martin, when you are referring to "the ClientSample handles the browse correctly...", are you referring to the file ClientSamples.cs in the ConsoleReferenceClient? And do you happen to know a (publicly available) UA server with which the issue can be reproduced?

mregen commented 1 month ago

Some well known PLC support only five continuation points, if you happen to browse into some deep folders which return the continuation points, the batching browse goes on and may return more continuation points than allowed, then the BrowseNext will fail.

ThomasNehring commented 1 month ago

this can be reproduced with the NodeCache unit test from the solution, test case NodeCache_BrowseAllVariables, when the reference server MaxBrowsContinuationPoints attribute is set to 2, and the client requests a maximum of 10 values to be returned from browse service calls. Unfortunately setting these parameters this way makes some ugly changes necessary. As on example, the node cache defaults to using the value o for the maxBrowseResultsToReturn parameter of the Browse service call, which I could only override by adding a new internal property to the session.

ThomasNehring commented 1 month ago

digging a bit deeper into the code there may be another issue: if a client issues a browse request while another browse request has reserved some continuation point, the server may (according to section 7.6 of part iv: must) delete active continuation points from the other browse call to create new ones (if it is running out of resources for continuation points). The client may then receive a BadContinuationPointInvalid service result for the first browse service call. It seems that this is not explicitly checked for in our client(s), and with the task based approach which is followed it is also not possible to exclude the possibility that two browse commands are issued concurrently. With the reference server as a test server it is not possible to analyze this issue, since the reference server checks the MaxBrowseContinuationPoints threshold per service call, not per session (according to the spec, continuation points can be (should be?) maintained per session, though.