aws / aws-iot-device-sdk-embedded-C

SDK for connecting to AWS IoT from a device using embedded C.
MIT License
976 stars 629 forks source link

Memory usage and mbedtls setup #81

Closed gustavomassa closed 7 years ago

gustavomassa commented 7 years ago

Hello,

I have some questions regarding the mbedtls setup and memory usage.

1 - What is the lowest value for the max_content_length that mbedtls can use (lowest value that the server is able to handle from the client and still have a stable connection). 2 - On the mqtt_sub_pub sample the value of SSL_READ_TIMEOUT is just 10ms, what is the lowest and highest value that can be handled?

I have some concerns about the SDK memory usage: 3 - I’m using an ESP8266 with freeRRTOS (40kb of heap available), when using the original paho embedded c client with a simple mbedtls ssl wrapper, the MQTT Task need a stack of size 2048. Although when using the aws embedded c sdk, for the same MQTT Task, it requires at least a stack of size 6000+. I haven’t tested the shadow connection yet.

I also have two questions regarding the configuration of the mqtt client: 4 - What is the correct value for the keepalive value? 5 - What is the relation of the keepalive with the yield? Normally on the MQTT Task I’ve been using 1 second for yield.

Thank you, Best Regards

chaurah commented 7 years ago

Hi @gustavomassa, Answering your questions below: 1) We haven't tested any SDK specific values. The default values used in MbedTLS is 16K, there should be no reason to not have a lower value. 2) Depends on your device. This is something that needs to be tested in your expected usage scenario. 3) There are significant implementation differences between the original paho SDK and the current version of our SDK. I agree that the stack size needs to be reduced. We are making some progress on the next release of the SDK that directly addresses the size issues. 4) Again depends on your use case. Its easy to set this to the maximum value, but you may want to test expected usage scenarios and fine tune this. 5) The yield function is where the Ping request/response processing happens. Its not ideal, but currently yield needs to be called at least once every keepalive interval duration. If the duration is exceeded and there's no ping response waiting already, the SDK will assume a disconnect and attempt to reconnect. If the duration is exceed and no other mqtt operation was performed (the server receives no messages), then the connection will be disconnected on the server side.

I know some of the answers basically say, "test it yourself". Unfortunately, there is no one right answer for a generic SDK in these cases. These numbers can be affected by everything from device performance to network configuration and need to be tested in the specific use case you have for the SDK. That being said, I will be happy to help you figure out any issues you see with particular values. Please let me know if you have any further questions or concerns. Thank you for using AWS IoT.

Rahul

gustavomassa commented 7 years ago

@chaurah

Thank you for the responses, I was able to make it work. But I still have some questions regarding the server-side configuration about the ssl.

Reading the mbedTLS documentation about reduce memory usage and storage footprint it says:

By default, mbed TLS uses a 16k frame buffer to hold data for incoming and outgoing frames. This is what the TLS standard requires. If you control both sides of a connection (Server and Client) you can reduce the maximum frame size to reduce the buffer's needed to store the data. The size of this frame is determined by MBEDTLS_SSL_MAX_CONTENT_LEN. You can safely reduce this to a more appropriate size (like 2k bytes) if:
   1 -  both sides support the max_fragment_length SSL extension (allowing reduction to < 1k bytes for the buffers.
   2 -  you control both sides of the connection or know the maximum size that will ever be sent in a single SSL/TLS frame.
/**
 * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
 *
 * Enable support for RFC 6066 max_fragment_length extension in SSL.
 *
 * Comment this macro to disable support for the max_fragment_length extension
 */
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH

I've enabled this option on my mbedtls library, then I reduced the max_content_len to "2048", but any value lower than "3048" will cause a MBEDTLS_ERR_SSL_INVALID_RECORD error. It seems that the server is not supporting the "max_fragment_length extension". Could you please confirm?

I have new questions about the SDK: 1 - It seems that the server does not support keepAlive interval of 1 hour, the client is losing connection on the ping message. I'm using 30 minutes and works fine. 2 - Let's say I need a real-time communication between my iot device and the aws broker, I must call Yield to receive/send all messages, If my iot device receive/send more than 1 message between Yields interval, those messages will be saved in a queue or the data will be lost?

Thank you, Best Regards

chaurah commented 7 years ago

Hi @gustavomassa, You are correct about the server not support max_fragment_length_extension at the moment. This is something we are working on adding in the future but unfortunately there's no specific timeline on when it will be released. For your SDK questions, responses below: 1) You can find details about the limits imposed by AWS IoT here. The current maximum allowed value for Keepalive is 1200 seconds. 2) Unfortunately there's no "MQTT message" queuing on the SDK side. That being said, you do not need to yield to send messages. It is a blocking SDK, and all publish requests will be immediately sent out. For receive, the SDK might not buffer any messages, but the TLS layer will. If your TLS buffer size is large enough to store all messages between yield intervals, you should be fine. I realize its not the most reliable method, but implementing queuing in the current version of the SDK was a very messy proposition. We decided that is not something that is worth releasing to customers and making things more complicated then they need to be. We are looking into adding queuing support in the next release of the SDK.

Apologies for the late response on this. Please do let me know if you have any suggestions for improvement or further questions and I will do my best to help you out. Thank you for using AWS IoT.

Rahul