fix: Increase default MQTT payload size to 256 MiB#3130
Conversation
Codecov ReportAttention: Patch coverage is Additional details and impacted files📢 Thoughts on this report? Let us know! |
| mqtt_schema, | ||
| tedge_config.aws.mapper.timestamp_format, | ||
| prefix.clone(), | ||
| tedge_config.az.mapper.mqtt.max_payload_size, |
There was a problem hiding this comment.
Copy/paste typo
| tedge_config.az.mapper.mqtt.max_payload_size, | |
| tedge_config.aws.mapper.mqtt.max_payload_size, |
Robot Results
|
6b0ae87 to
59a1618
Compare
didier-wenzek
left a comment
There was a problem hiding this comment.
The issue is addressed by the proposed fix. However, this introduces a weakness, and I would consider to limit the size of the messages actually processed by thin-edge, ignoring those too large.
| max_packet_size: 1024 * 1024, | ||
| max_packet_size: MAX_PACKET_SIZE, |
There was a problem hiding this comment.
Looking closer to root cause of an infinite loop caused by a message that is too large, it appears that the issue is not rooted in the MQTT protocol per se, but is due to a bad combination of rumqttc and thin-edge.
- when a message that is too large is received, rumqttc raises a
PayloadSizeLimitExceedederror - when this error is received thin-edge do nothing beyond logging and adding some delay (which is useless)
- rumqttc also cuts the connection and then reconnects.
- the message is then resent by the broker that is still expecting an acknowledgement.
Unfortunately, the rumqttc API provides no means to skip that poison pill (the error structs does not contain the message pkid).
=> Removing the limit as done here fixes the issue. However, we can consider to add our own check with no limit on what is received from rumqttc but with a filter implemented by mqtt_channel to prune messages that are too large. Without this limit a rogue client might overwhelmed the mapper or the agent.
| mqtt: { | ||
| /// The maximum message payload size that can be mapped to the cloud | ||
| #[tedge_config(example = "8192", default(variable = "C8Y_MQTT_PAYLOAD_LIMIT"))] | ||
| max_payload_size: u32, |
There was a problem hiding this comment.
The maximum size of u32 is much bigger than 256MiB. (4294967295 > 268435455). I think we need protection for such big input from user.
| mqtt_schema, | ||
| tedge_config.aws.mapper.timestamp_format, | ||
| prefix.clone(), | ||
| tedge_config.aws.mapper.mqtt.max_payload_size, |
There was a problem hiding this comment.
Related to my comment above, for example, here we can add the size check for aws.mapper.mqtt.max_payload_size
There was a problem hiding this comment.
Implemented the validation at the tedge_config level itself, so that the user gets the feedback much earlier.
didier-wenzek
left a comment
There was a problem hiding this comment.
The code is correct. I would prefer to revert the default max size to the previous values.
| /// Maximum size for a message payload | ||
| /// | ||
| /// Default: `1024 * 1024`. | ||
| /// Default: `268435455` (256 MB). |
There was a problem hiding this comment.
I would not change the default, now that the correct protection is implemented.
| /// Default: `268435455` (256 MB). | |
| /// Default: `1024 * 1024`. |
| } | ||
| } | ||
|
|
||
| impl TryFrom<u32> for MqttPayloadLimit { |
There was a problem hiding this comment.
I wouldn't have gone so far. But since this has been done, we can keep it.
f43495e to
7dbd1aa
Compare
Proposed changes
Types of changes
Paste Link to the issue
#3124
Checklist
cargo fmtas mentioned in CODING_GUIDELINEScargo clippyas mentioned in CODING_GUIDELINESFurther comments