Closed edrose-tewke closed 5 months ago
It's probably worth following the logic in Section 4.6 of the RFC, which makes the fix quite easy:
If the Path MTU is not known for a destination, an IP MTU of 1280 bytes SHOULD be assumed; if nothing is known about the size of the headers, good upper bounds are 1152 bytes for the message size and 1024 bytes for the payload size.
So Block2
transfers should start once the payload size goes above 1024.
In addition, the default for the maxPacketSize
parameter should be reduced to 1152 since 1280 is the IP MTU and doesn't include the UDP header. If the UDP payload goes above 1280 then fragmentation at the IP layer might occur.
Thank you very much for the infos and also research. If you like we are happy about any PR or such (like your patch in the first post).
I've been working on this in my personal time outside of work, so I've switched to my personal account (same person as OP, slightly different username).
I'll probably have a PR ready by the end of the day.
Description
When node-coap is used as a server it is normally not required to explicitly set the
Block2
option when sending a response, even if the payload length is greater than themaxPacketSize
setting. This is because of a check performed at server.ts:678 which should detect that the payload requires a blockwise transfer, and then automatically apply the blockwise transfer logic to ensure that the transfer goes ahead.Unfortunately this check is performed on just the payload, without regard for the size of the header. This means that the logic does not work for payload sizes that are close to, but not over, the
maxPacketSize
parameter. Depending on the header size, this holds for packets that are roughly between 1268 - 1280 bytes long.Code to Recreate
The problem can easily be recreated by modifying
examples/blockwise.js
. If the client does not add theBlock2
header (since it does not know what size the response will be), and the server generates a payload of 1268 bytes, the server will crash with the message "Max packet size is 1280: current is 1281".If the requested payload size is increased on line 16 to a value >= 1280 then the server automatically applies blockwise transfers and no error is thrown. If it is decreased to <= 1267 then the payload doesn't need to be split and gets sent in a single response. The error only appears when (in pseudocode)
payload.length < maxPacketSize && payload.length + header.length > maxPacketSize
.Here is a patch that can be applied to the master branch to change the example if needed