convertersystems / opc-ua-client

Visualize and control your enterprise using OPC Unified Architecture (OPC UA) and Visual Studio.
MIT License
395 stars 112 forks source link

Issue Requesting to many Items at once ("Org.BouncyCastle.Crypto.DataLengthException") #16

Closed jogibear9988 closed 7 years ago

jogibear9988 commented 7 years ago

When I use Code like this:

    var rids = tags.Select(x => new ReadValueId()
        {
            NodeId = NodeId.Parse(x.Config.Address),
            AttributeId = AttributeIds.Value
        })

            var rq = new ReadRequest()
            {
                NodesToRead = rids.ToArray()
            };

            var result = this._session.ReadAsync(rq).Result;

It crashes with "Org.BouncyCastle.Crypto.DataLengthException", AdditionalInfo: "data not block size aligned"

With 80 Tags it works, with more than 120 it crashes

awcullen commented 7 years ago

Interesting! I edited the DataLoggerConsole to make a thousand tag read from the UACPPServer. I was not able to reproduce this ex.

            // Prepare array of nodes to read.
            var nodes = new ReadValueId[1000];

            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i] = new ReadValueId { NodeId = NodeId.Parse($"ns=2;s=Demo.Massfolder_Dynamic.Variable{i.ToString("0000")}"), AttributeId = AttributeIds.Value };
            }

            var readRequest = new ReadRequest
            {
                NodesToRead = nodes
            };

Maybe you can send a stack trace? I'll start searching the BouncyCastle source, looking for this Exception.

awcullen commented 7 years ago

Next I tested reading 1000 instances of node "ns=2;s=Demo.Static.Scalar.ImagePNG". The data value holds a 4kb byte array.

            // Prepare array of nodes to read.
            var nodes = new ReadValueId[1000];

            for (int i = 0; i < nodes.Length; i++)
            {
                //nodes[i] = new ReadValueId { NodeId = NodeId.Parse($"ns=2;s=Demo.Massfolder_Dynamic.Variable{i.ToString("0000")}"), AttributeId = AttributeIds.Value };
                nodes[i] = new ReadValueId { NodeId = NodeId.Parse($"ns=2;s=Demo.Static.Scalar.ImagePNG"), AttributeId = AttributeIds.Value };
            }

            var readRequest = new ReadRequest
            {
                NodesToRead = nodes
            };

I double-checked the size of the ReadResult. It totaled 4290032 bytes!

                            // Read the nodes.
                            var readResponse = await session.ReadAsync(readRequest).ConfigureAwait(false);

                            using (var enc = new BinaryEncoder(new System.IO.MemoryStream()))
                            {
                                readResponse.Encode(enc);
                                Console.WriteLine($"Read {enc.Position} bytes");
                            }
awcullen commented 7 years ago

I'll need to know the Server and endpoint security that is being used to diagnose further. I tried Basic128Rsa15, Basic256, and Basic256Sha256 with the UACPPServer and all seems to be working.

jogibear9988 commented 7 years ago

It's a Siemens 1500 Plc. For the Security, I'll look... Stacktrace will be added!

awcullen commented 7 years ago

It looks like turning off the server's security might be a work around for this exception.

I don't have access to a S7-1500, would you mind capturing packets with Wireshark? If you haven't done this before, there's a bit of a learning curve. Download Wireshark from https://www.wireshark.org/ and install. Reboot is required. Start Wireshark and go to Edit...Preferences...Protocols... OpcUA and add the port number of the S7-1500 Opc Server. Now set three things on the opening page.

  1. Highlight network interface (WIFI in my case)
  2. In "Capture Using this Filter" type host [ip address] (192.168.1.107 is the remote opc server in my case)
  3. In "Apply a display Filter" type opcua 2017-01-12 1

Then start capturing by clicking the blue SharkFin button on the toolbar. Now run the Opc Client. You should see the packets similar to from this exception below:

2017-01-12

Cause the exception in the OPC Client. Back in Wireshark, click red Stop button. Select File...Save As.

Upload to Dropbox so I can take a look.

jogibear9988 commented 7 years ago

i've often used wireshark to analyze the s7 300 protocol ;-) will do so!

jogibear9988 commented 7 years ago

i've had no time today. will do next week

jogibear9988 commented 7 years ago

Wireshark Log when the error happens. opcuaerror.zip

I've added a Halt on All Exceptions, and this is the log, when the debugger halts

awcullen commented 7 years ago

I checked the packets and found no obvious problem. The server sets a buffer size of 8192, MaxMessageSize of 2Mb, Chunk Size: unlimited. These are okay, (I tested with UnifiedAutomation and Kepware.) The server sends 5 endpoints. A secure channel is created with the most secure endpoint: Basic256, Sign and Encrypt. Then I can't see the contents (encryption's working!) But I can see packet sizes that I can guess are the UaTcpSessionClient starting up normally. A set of PublishRequests are sent. At about 10 seconds after startup, a PublishResponse is received. At about 20 seconds after startup, when the next PublishResponse is due, it ends.

Could I ask you to try your app with no security ( then again with Sign-only). I'm going to try to find out more about this device from Siemens.

jogibear9988 commented 7 years ago

I look if encryption can be disabled. Also Siemens supports OPCUA at his PLCs since a few month only, maybe they have a bug in their opc server.

How can I change your lib to not use the most secure channel?

jogibear9988 commented 7 years ago

Without encryption it seems to work without a crash

jogibear9988 commented 7 years ago

I will look if it works with the siemens example from here: https://support.industry.siemens.com/cs/document/109737901/opc-ua-net-client-for-the-simatic-s7-1500-opc-ua-server?dti=0&lc=en-PL without a exception

coconut147 commented 7 years ago

Is it possible to share a wireshark trace without encryption?

awcullen commented 7 years ago

@jogibear9988 Would you try the highest encryption once for me? secpol

jogibear9988 commented 7 years ago

i will do both this week

awcullen commented 7 years ago

Before downloading this change you will have to find OPC UA ... Server... Security... Server Certificate and click Add New.. Why? because the higher security policy demands a certificate signed using SHA256 newcert

coconut147 commented 7 years ago

any News !?

jogibear9988 commented 7 years ago

it's still on my list! but i think it will take one werk or two

awcullen commented 7 years ago

A colleague wrote:

I have here the fastest Siemens SPS (1518-4 firmware V2.0 with OPC server onboard) and need alone for complete browsing 14 minutes. For reading 2500 DINT values over 4 seconds.

He improved the reading time to 40 ms by simply pre-registering the nodes. A sample can be found at https://github.com/convertersystems/opc-ua-samples/blob/master/DataLoggingConsole/Program.cs

He did find he had to call RegisterNodesAsync and ReadAsync in three batches. This is because the onboard server limits the max number of nodes in a single call to 1000. You can find your server's limits by reading Server.ServerCapabilities.OperationLimits.MaxNodesPerRead and MaxNodesPerRegisterNodes.

jogibear9988 commented 7 years ago

thanks! has he also found a way to speedup the browse?

coconut147 commented 7 years ago

Registering is a very good option to speedup the access. Structures and Arrays would also have a heavy impact.

I could not observe any performance issues with browsing, a 14 Minute browse sounds weird for me. Did you do any comparable measures with another client?

jogibear9988 commented 7 years ago

I'll look wich Values are in the limit tags when encryption is on, maybe it's reduced then...

awcullen commented 7 years ago

@jogibear9988 I was able to locate the original bug after all. Many apologies for blaming this on the server! Please upgrade to package 1.5.8

jogibear9988 commented 7 years ago

Sorry that I could not test in the last weeks... I promise I will test again this or next week.

Thanks for your fixing

awcullen commented 7 years ago

Looks like the fix is working. Thanks for your help @jogibear9988 .