Browse Source

esp_tls: Fix issue when timeout is not explicitly given in esp_tls_cfg_t
- If internet connectivity weakened or disappeared suddenly while we were
in the TLS handshake stage, the app got stuck at that point indefinitely.
- This was because when timeout was not explicitly specified in esp_tls_cfg_t,
the default timeout was set at the wrong place. This causes the sockets to be
setup with zero timeout, hence the indefinite wait.

Laukik Hase 3 năm trước cách đây
mục cha
commit
665ad3dbdb
1 tập tin đã thay đổi với 17 bổ sung11 xóa
  1. 17 11
      components/esp-tls/esp_tls.c

+ 17 - 11
components/esp-tls/esp_tls.c

@@ -73,6 +73,8 @@ static const char *TAG = "esp-tls";
 #error "No TLS stack configured"
 #endif
 
+#define ESP_TLS_DEFAULT_CONN_TIMEOUT  (10)  /*!< Default connection timeout in seconds */
+
 static esp_err_t create_ssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls)
 {
     return _esp_create_ssl_handle(hostname, hostlen, cfg, tls);
@@ -203,18 +205,22 @@ static void ms_to_timeval(int timeout_ms, struct timeval *tv)
 static esp_err_t esp_tls_set_socket_options(int fd, const esp_tls_cfg_t *cfg)
 {
     if (cfg) {
-        if (cfg->timeout_ms >= 0) {
-            struct timeval tv;
+        struct timeval tv = {};
+        if (cfg->timeout_ms > 0) {
             ms_to_timeval(cfg->timeout_ms, &tv);
-            if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) != 0) {
-                ESP_LOGE(TAG, "Fail to setsockopt SO_RCVTIMEO");
-                return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
-            }
-            if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) != 0) {
-                ESP_LOGE(TAG, "Fail to setsockopt SO_SNDTIMEO");
-                return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
-            }
+        } else {
+            tv.tv_sec = ESP_TLS_DEFAULT_CONN_TIMEOUT;
+            tv.tv_usec = 0;
+        }
+        if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) != 0) {
+            ESP_LOGE(TAG, "Fail to setsockopt SO_RCVTIMEO");
+            return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
         }
+        if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) != 0) {
+            ESP_LOGE(TAG, "Fail to setsockopt SO_SNDTIMEO");
+            return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
+        }
+
         if (cfg->keep_alive_cfg && cfg->keep_alive_cfg->keep_alive_enable) {
             int keep_alive_enable = 1;
             int keep_alive_idle = cfg->keep_alive_cfg->keep_alive_idle;
@@ -300,7 +306,7 @@ static inline esp_err_t tcp_connect(const char *host, int hostlen, int port, con
     if (connect(fd, (struct sockaddr *)&address, sizeof(struct sockaddr)) < 0) {
         if (errno == EINPROGRESS) {
             fd_set fdset;
-            struct timeval tv = { .tv_usec = 0, .tv_sec = 10 }; // Default connection timeout is 10 s
+            struct timeval tv = { .tv_usec = 0, .tv_sec = ESP_TLS_DEFAULT_CONN_TIMEOUT }; // Default connection timeout is 10 s
 
             if (cfg && cfg->non_block) {
                 // Non-blocking mode -> just return successfully at this stage