Description
Answers checklist.
- I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- I have searched the issue tracker for a similar issue and not found a similar issue.
General issue report
[Disclaimer: I know little about HTTP and TLS, I may be missing something]
When testing https OTA with standard examples (simple/advanced_https_ota), I found (for multiple versions of IDF incl. 5.3.1) the following issue:
If I use $ openssl s_server -WWW
as the https server (as mentioned in the OTA examples README), then once the server sends out the entire file it sends a TLS message with the PSH flag set and an encrypted close-notify alert. My understanding of the expected behavior from the client in this case is that it should respond with close-notify and proceed to close the connection: https://datatracker.ietf.org/doc/html/rfc6101#section-5.4.1
However, what actually happens is that the client keeps sending TCP keepalives indefinitely and the OTA never completes (adding a custom header with esp_http_client_set_header(http_client, "Connection", "Close");
doesn't help). The client keeps calling esp_https_ota_perform()
with a result of ESP_ERR_HTTPS_OTA_IN_PROGRESS
, even though it's unable to read any additional data. I can tell from the byte count that the entire file has been received by that point. When mbedtls debugging is enabled one can see that the close-notify message is received and handled (see attached screenshot).
But if I use a simple python3 server (see attached) the behaviour is different: when the server has sent the entire file, instead of sending a "close-notify" alert in the TLS message it sets the FIN flag (along with PSH as before). This is handled successfully by the client, which now proceeds to send a TCP message with FIN and close the connection. The OTA successfully completes.
It appears that the esp http/s stack doesn't properly handle the first case, when a close-notify alert is sent.
Wireshark capture of successful and unsuccessful runs (one file, separate by timestamp) attached along with python https server. (client is 192.168.43.117, server is 192.168.43.203)