Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndexOutOfRangeException when calling BacnetClient.ReadPropertyResponse #114

Open
joproulx opened this issue Oct 19, 2022 · 0 comments
Open

Comments

@joproulx
Copy link

joproulx commented Oct 19, 2022

Issue

When calling ReadPropertyResponse, we get an IndexOutOfRangeException with the following stack trace:

System.IndexOutOfRangeException:
   at System.IO.BACnet.Serialize.EncodeBuffer.Add (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.EncodeBuffer.Add (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.ASN1.encode_application_object_id (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.ASN1.bacapp_encode_application_data (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.Services.EncodeReadPropertyAcknowledge (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient+<>c__DisplayClass347_0.<ReadPropertyResponse>b__1 (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient.SendComplexAck (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient+<>c__DisplayClass347_0.<ReadPropertyResponse>b__0 (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient.HandleSegmentationResponse (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient.ReadPropertyResponse (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)

How to reproduce

  • ela-compil/BACnet v2.0.4
  • We use the library with the BacnetIpUdpProtocolTransport
  • When receiving a ReadPropertyRequest from a remote BACnet device, return a response bigger than 1476 bytes
  • The request must have been routed through a BACnet router

Investigation

From what we can see, because the request was coming from a BACnet router, the response need to add a bigger NPDU header and this would increase the max_offset of the buffer to a value higher than the actual size of the buffer as you can see here:

image

So when trying to add response payload (ADPU) bigger than 1476 bytes, the validation with the max_offset goes through even though the size of the buffer is not big enough and we get an IndexOutOfRangeException.

image

Potential fix

  • As a first workaround, we tried to increase the max payload in the transport (here). But this has the side effect of causing IP fragmentation because now the packets are too big.

  • We also tried another fix in BacnetClient.EncodeSegmentHeader. This seems to fix the issue from our initial tests:
    image

Couple of questions for you guys:

  • Does the fix makes sense?
  • Are there any tests we can run to validate we don't add regression to the library?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant